pax_global_header 0000666 0000000 0000000 00000000064 14126326331 0014513 g ustar 00root root 0000000 0000000 52 comment=13efebef12254fd39110b6f9dd80a7b5b0a579c2
mescc-tools-Release_1.3/ 0000775 0000000 0000000 00000000000 14126326331 0015246 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/.gitignore 0000664 0000000 0000000 00000002212 14126326331 0017233 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
# Ignore build directory
bin/
# Ignore Temp directory
temp/
# Ignore test result directory
test/results/
# Ignore temp and special files
*.tst
*.qst
# Ignore bootstrap build files
M1-macro-footer.M1
M1-macro.M1
M1-macro.hex2
blood-elf-footer.M1
blood-elf.M1
blood-elf.hex2
hex2_linker-footer.M1
hex2_linker.M1
hex2_linker.hex2
get_machine-footer.M1
get_machine.M1
get_machine.hex2
exec_enable-footer.M1
exec_enable.M1
exec_enable.hex2
mescc-tools-Release_1.3/.gitmodules 0000664 0000000 0000000 00000000121 14126326331 0017415 0 ustar 00root root 0000000 0000000 [submodule "M2libc"]
path = M2libc
url = https://github.com/oriansj/M2libc.git
mescc-tools-Release_1.3/CHANGELOG.org 0000664 0000000 0000000 00000033421 14126326331 0017251 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
* Current
** Added
Hex2 support for RISC-V
M1 support for RISC-V
Blood-elf support for RISC-V
** Changed
clean up $@ behavior for kaem
*MAJOR BREAKING CHANGE* make Blood-elf require --little-endian or --big-endian flag to be used (commit db4a332418e7fe5033b2836c9f355f076df325df)
** Fixed
Make changing PATH within a kaem script actually change the PATH
Multiple typos in hex2 and M1
Correct e_entry behavior for elf example headers
Make kaem behave correctly when given a NULL envp
Make kaem behave correctly when given an empty envp
** Removed
Removed High level prototypes for hex1, hex2 and M0
* 1.2 - 2021-06-09
** Added
netBSD support for tests
FreeBSD support for test
FreeBSD support for generated binaries
Implemented Hash table to speed up M1
Add aligned addressing for AArch64
Produce meaningful warning message when users are not generating ROM images
Produce warning for potentially wrong endianess
Use hash table for hex2 jump table
Add proper escaping support to kaem
Adding baseline support for ppc64le in hex2
Add ppc64le support to M1
Add minimal PPC64LE test for M1+hex2
Add RISC-V support to hex2_linker
Add RISC-V support to M1
Add --blood flag to get_machine to simplify the process of getting blood-elf flags during bootstrap
Added variable expansion collapse support
** Changed
Inherrit CFLAGS in kaem makefile
Changed M1 to leverage O(1) macro application
Pulled all variable initialization outside of loops to fix M2-Planet compatibility
Broke kaem tests into individual commands
Close files that were fopen'ed
Harmonize get_machine flags to support --os and depreciate --OS
Replace file_print with more C standard compliant fputs
Harmonized on ELF header numbers for architecture numbering
** Fixed
Fixed makefiles so guix is able to build
Fixed kaem 32bit regression.
Spelling mistakes
GCC 10 Compatibility issue
Behavior of kaem --strict in regards to blank lines
Missing makefile dependencies on get_machine
catm stopped reading past the end of argv
Added missing test and made add_envar update
Fix kaem overwriting environment variables
Make kaem test14 not locale specific
Fixed build failure caused by export LANGUAGE=nl_BE:nl
Disable attempting to run Linux binaries on non-Linux hosts
Make overly long atoms have a useful error message
** Removed
Remove kaem.run in Kaem/
Finish eliminating all functions outside of M2libc
* 1.0 - 2020-05-01
** Added
Added builtin cd into kaem
Added builtin set into kaem
Added builtin pwd into kaem
Added working variable substitution into kaem
Added kaem subtests
Seperate kaem makefile
Added fuzzing argument to kaem to prevent damage during fuzzing
** Changed
Prevent buffer overflows in kaem
Made hex2 argument names more standard
Made M1 argument names more standard
Moved kaem and its tests into a seperate directory
** Fixed
kaem behavior in regards to failing execve
kaem segfaults from messy inputs caught
Multiple segfaults found from fuzzing
Fixed kaem truncation bug
Got kaem to run properly on armv7l
** Removed
* 0.7 - 2020-01-30
** Added
Added support for AMD64 dwarf footers in blood-elf via --64
Added hex0 for i386 in NASM, M1 and hex0
Added hex1 for i386 in NASM, M1, hex1 and hex0
Added first generation AARCH64 elf header
Added hex2 for i386 in NASM, M1, hex2 and hex1
Added M0 for i386 in NASM, M1 and hex2
Added catm for i386 in NASM, M1 and hex0
Added support for EOF in line comments in hex2 and M1; thanks to markjenkins
Added prototype M1 Manpage
Added prototype hex2 Manpage
Added prototype blood-elf Manpage
Added prototype kaem Manpage
Added prototype get_machine Manpage
Added cc_x86 for AMD64 in NASM and M1
Added cc_x86 for x86 in NASM and M1
Added cc_amd64 for AMD64 in NASM and M1
Added cc_amd64 for x86 in NASM and M1
** Changed
** Fixed
Removed duplicate in kaem's help
Fixed regression in M1 in regards to knight null padding
Removed a series of segfaults
** Removed
* 0.6 - 2019-04-14
** Added
Added template ELF headers for ARM
Added initial support for ARM
Added official hex0 seed for AMD64
Added official hex1 seed for AMD64
Added support for
Added catm NASM prototype to simplify build
Added catm M1 prototype to reduce bootstrap dependency
Added catm hex0 prototype to eliminate bootstrap dependencies down to hex0
Added M0 NASM prototype to simplify build
Added M0 M1 prototype to reduce bootstrap dependency
Added M0 hex2 prototype to eliminate bootstrap dependencies down to hex2
Verified ARM port to support M2-Planet
** Changed
Updated build.sh and kaem.run to the current mescc-tools syntax
Reduced get_machine's build dependencies
Cleaned up x86 elf headers
Removed kaem's dependence on getopt
Replaced --Architecture with --architecture
changed get_machine's default output to filter machine names into known families
Reduced M1 null padding of strings to a single null for all architectures except Knight
Updated AMD64 bootstrap kaem.run to include steps from hex0 to M0
** Fixed
Fixed broken test9 thanks to janneke
Fixed wrong displacement calculations for ARM immediates
Fixed typo in license header
Fixed kaem.run to actually function and produce identical results
Fixed regression caused by linux 4.17
Removed false newline added in numerate_number for zero case
Fixed broken bootstrap script
** Removed
Removed final dependency on getopt
Removed need to know architecture numbers as that was a bad idea
* 0.5 - 2018-06-15
** Added
Added INSTALL notes
Added HACKING notes
Added examples of minimal Hex1, Hex2 and M1-macro programs that may need to be
written to bootstrap a particular architecture.
Added useful functions to reduce bootstrap dependencies
Added support for binary output in M1-macro
** Changed
Changed Knight architecture offset calculation to match new standard
Updated test3 lisp.s to include more functionality
Updated test3 definitions file to reflect changes in Knight instruction encoding
enhanced README to be more useful
Pulled numerate_string functionality out of hex2 and M1 into a shared library
Eliminated getopt from M1-Macro, hex2-linker and blood-elf; use --Architecture 1 instead of --Architecture=1
** Fixed
Corrected M1-macro incorrectly expressing negative numbers
Updated test3 checksum to reflect new version of lisp.s
fixed check.sh to actually perform all checks.
Fixed build.sh to function in a self-hosting fashion
** Removed
Removed blood-elf's dependency on getopt
Removed C preprocessor macro from blood-elf needed for mescc support
Removed hex2's dependency on getopt
Removed C preprocessor macro from hex2 needed for mescc support
Removed need for octal support in the building of hex2
Removed M1's dependency on getopt
Removed C preprocessor macro from M1 needed for mescc support
Removed need for sprintf from M1
* 0.4 - 2018-02-24
** Added
Added file checks to reduce the number of error messageless faults
Added a current generation M1.M1 file as a test for mescc-tools
Added prototype kaem build script
M1-macro now catches undefined macros to allow easier troubleshooting
Added kaem build tool
Added ability to track build progress in kaem
Added support for line escapes in kaem
Added support for --strict in kaem to halt in the event of errors
Added selectable script file support in kaem
Added support for PATH search to kaem with fallbacks in the event of NULL environments
** Changed
flipped blood-elf from ignoring :: to :_
converted test8 into a full test
Added bash style line comments to kaem
Added support for raw strings to kaem
Stopped showing comment lines in kaem --verbose
Removed dependence on getenv to have more control over environmental lookup
** Fixed
Fixed stack overflow bug caused by too deeply nested recursion by transforming into iteration
Fixed default repo to point to current repo
Added missing license header to kaem.c
Fixed infinite looping in kaem scripts that hit an error that resets the file descriptor
** Removed
Removed need for strtol
Removed need for a global variable in M1-Macro
Removed legacy functions from kaem
* 0.3 - 2017-12-01
** Added
Incorporated a hex0 test which implements hex1 functionality
Added --output and --exec_enable options to hex2
Added --output option to M1
Wrote Hex1 in Hex0 for AMD64/ELF
Added the ability to specify an output file
Added exec_enable to allow the arbitrary setting of executable bits
Added get_machine to enable better scripting
Incorporated janneke's build scripts
Added a test to test for unusual nybble and byte order/formatting issues
Added blood-elf to generate elf footer capable of being used by objdump
** Changed
Renamed MESCC_Tools to mescc-tools to harmonize with guix package name
Now all tests will be architecture specific
Modified sprintf to behave correctly for negative numbers
Converted blood-elf to read M1-macro input and output M1-macro output
replaced uint with unsigned to better match the standard
Harmonized MAXSTRING to 4096bytess
** Fixed
Incorporated janneke's patchs to fix mescc compatibility
Fixed test on ARM platforms
Fixed range check to behave correctly with unsigned ints
** Removed
Removed the need to redirect hex2 output into a file
Removed the need for chmod u+x in development paths
Removed the need to redirect M1 output into a file
Removed the need for chmod entirely from bootstrap path
Removed dependency on shell supporting redirects
Removed need for stdint and stdbool
Removed need for enum support
Removed need for strtol in M1-macro
* 0.2 - 2017-07-25
** Added
created test2 (a 32bit x86 hex assembler) with its associated build and test changes
Fixed proof answers for test1 and test2
Added support to M0 for multiple architectures
Added range checking into M0 to make sure immediates will fit into specified space
Added a basic tutorial for generating new M0 definitions
Created a M1 compatible version of test0
Added an amd64 program for enabling execute bits (might need to later alter the 0777)
Added an i386 program for enabling execute bits (might need to later alter the 0777)
Added rain1's improvements to gcc flags
Added rain1's stack reduction recommendations
Incorporated an AMD64/elf hex1 example program as a test
Incorporated Test7 into make test and make clean flows
** Changed
Adjusted tags to reflect current CHANGELOG
Make test now depends upon test2 completing
Changed how M0 processes input to reduce stack usage and improve performance
Renamed M0 to M1 to reflect the additional functionality it provides
Applied Janneke's patch for accepting hex numerics in M1
Refactored x86/amd64 elf headers to a standard to avoid duplication
Standardized C flags for compiling M1 and Hex2
Made eval_immediates iterative instead of recursive
Made identify_macros iterative instead of recursive
Made process_string iterative instead of recursive
Made preserve_other iterative instead of recursive
Made print_hex iterative instead of recursive
Incremented version numbers for hex2 and M1
Updated guix.scm to match the new version and finish the release
Converted guix.scm definition for mescc_tools to use uri method instead of git
** Fixed
Removed unrequired temp file in test1
Clarified meaning of Label>base displacement conditional
Corrected error in test0 elf32
Test1 and Test2 to reflect the fact that /bin/bash doesn't exist in guix
Fixed M0 regression to continue to support original test code
Corrected makefile and build scripts to reflect rename
Modified test make scripts to reflect new standard elf headers
Fixed base address needed by test5 and its associated checksum
Harmonized flags for displaying version with standard
** Removed
Removed bashisms from Test1 and Test2 to allow proper behavior on debian based systems
Removed alerting on missing files in cleanup target
Removed massive M0 Definition lists as they don't serve a useful purpose
* 0.1 - 2017-06-25
** Added
Incorporated support for little Endian output format in hex2
Incorporated support for multiple input files in hex2
Added range checking for Hex2
Added support for 1 and 4 byte relative displacements
Added Hex2 Test
Added the ability to specify a new base address
Added example M0 x86 opcode definitions
Incorporated support for multiple input files in M0
Added support for little Endian immediate output in M0
Added Hex assembler example test
Added support for Label>base in Hex2
Added Version info
Added install target
Added inital guix package definition
** Changed
Displacement calculations are now based on architecture specific rules
M0 Immediates now need prefixes to specify the storage space to use for the immediate
** Fixed
Behavior regarding !label displacements
** Removed
* 0.0 - 2017-05-10
Initial release of MESCC Tools from stage0 High Level prototypes
mescc-tools-Release_1.3/COPYING 0000664 0000000 0000000 00000104513 14126326331 0016305 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
mescc-tools-Release_1.3/Generating_M0_Definitions.org 0000664 0000000 0000000 00000025526 14126326331 0022743 0 ustar 00root root 0000000 0000000 * License
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
* How to use software to generated opcode information
Lets start with a simple program you wish to convert to M1, so to start we are going to write a hex disassembler that uses a lookup table
** simple assembly example
.text # section declaration
output: .byte 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x0A
# we must export the entry point to the ELF linker or loader.
# They convientionally recognize _start as their entry point.
# Use ld -e main to override the default if you wish
.global _start
print_byte:
# Write what ever is in eax
mov $1, %edx # set the size of chars we want
mov %eax, %ecx # What we are writing
mov $1, %ebx # Stdout File Descriptor
mov $4, %eax # the syscall number for write
int $0x80 # call the Kernel
ret
read_byte:
# Attempt to read a single byte from STDIN
mov $1, %edx # set the size of chars we want
mov $input, %ecx # Where to put it
mov $0, %ebx # Where are we reading from
mov $3, %eax # the syscall number for read
int $0x80 # call the Kernel
# If we didn't read any bytes jump to Done
test %eax, %eax # check what we got
jz Done # Got EOF call it done
# Move our byte into registers for processing
movb input, %al # load char
movzx %al, %eax # move char into eax
ret
_start:
loop:
call read_byte
mov %eax, %esi # We have to zero extend it to use it
mov %eax, %ebp # We have to zero extend it to use it
# Break out the nibbles
shr $4, %esi # Purge the bottom 4 bits
and $0xF, %ebp # Chop off all but the bottom 4 bits
# add our base pointer
add $output, %esi # Use that as our index into our array
add $output, %ebp # Use that as our index into our array
# Print our first Hex
mov %esi, %eax # What we are writing
call print_byte
# Print our second Hex
mov %ebp, %eax # What we are writing
call print_byte
jmp loop
Done:
# program completed Successfully
mov $0, %ebx # All is well
mov $1, %eax # put the exit syscall number in eax
int $0x80 # Call it a good day
.data
write_size = 2
input:
.byte write_size
** Build it
To build the above program (assuming you put it in a file named foo.S and wish to produce a program called foo):
as -o foo.o foo.S
ld -o foo foo.S
** objdump its secrets
If one were to run:
objdump -d foo > opcodes.note
*** Which would contain
Disassembly of section .text:
08048074 :
8048074: 30 31 xor %dh,(%ecx)
8048076: 32 33 xor (%ebx),%dh
8048078: 34 35 xor $0x35,%al
804807a: 36 37 ss aaa
804807c: 38 39 cmp %bh,(%ecx)
804807e: 41 inc %ecx
804807f: 42 inc %edx
8048080: 43 inc %ebx
8048081: 44 inc %esp
8048082: 45 inc %ebp
8048083: 46 inc %esi
8048084: 0a .byte 0xa
08048085 :
8048085: ba 01 00 00 00 mov $0x1,%edx
804808a: 89 c1 mov %eax,%ecx
804808c: bb 01 00 00 00 mov $0x1,%ebx
8048091: b8 04 00 00 00 mov $0x4,%eax
8048096: cd 80 int $0x80
8048098: c3 ret
08048099 :
8048099: ba 01 00 00 00 mov $0x1,%edx
804809e: b9 f3 90 04 08 mov $0x80490f3,%ecx
80480a3: bb 00 00 00 00 mov $0x0,%ebx
80480a8: b8 03 00 00 00 mov $0x3,%eax
80480ad: cd 80 int $0x80
80480af: 85 c0 test %eax,%eax
80480b1: 74 34 je 80480e7
80480b3: a0 f3 90 04 08 mov 0x80490f3,%al
80480b8: 0f b6 c0 movzbl %al,%eax
80480bb: c3 ret
080480bc <_start>:
80480bc: e8 d8 ff ff ff call 8048099
80480c1: 89 c6 mov %eax,%esi
80480c3: 89 c5 mov %eax,%ebp
80480c5: c1 ee 04 shr $0x4,%esi
80480c8: 83 e5 0f and $0xf,%ebp
80480cb: 81 c6 74 80 04 08 add $0x8048074,%esi
80480d1: 81 c5 74 80 04 08 add $0x8048074,%ebp
80480d7: 89 f0 mov %esi,%eax
80480d9: e8 a7 ff ff ff call 8048085
80480de: 89 e8 mov %ebp,%eax
80480e0: e8 a0 ff ff ff call 8048085
80480e5: eb d5 jmp 80480bc <_start>
080480e7 :
80480e7: bb 00 00 00 00 mov $0x0,%ebx
80480ec: b8 01 00 00 00 mov $0x1,%eax
80480f1: cd 80 int $0x80
** making sense of the objdump information
*** Labels
When you see 08048074 :
It indicates that at address 0x08048074 the definition of the function output resides.
*** 1OP Instructions
When you see 8048098: c3 ret
It indicates that at address 0x8048098 there is a Return instruction which as the Hex opcode encoding of C3 and could be implemented in M1 as:
DEFINE RETURN C3
Or any other mnemonic term that is more optimal for the problem at hand.
*** 2OP Instructions
When you see 80480c1: 89 c6 mov %eax,%esi
It indicate that at address 0x80480C1 there is a Move instruction that copies the value of register eax to register esi and has the Hex opcode encoding of 89C6 and therefor can be defined in M1 as:
DEFINE COPY_EAX_To_ESI 89C6
or
If we assume (eax=>R0, ebx=>R1, ecx=>R2, edx=>R3, esi=>R4, edi=>R5, ebp=>R6, and esp=>R7)
DEFINE COPY_R0_To_R4 89C6
*** Instructions with Immediates or displacements
Immediates occur in variable sizes but an immediate can not exist without an instruction
**** Trivial example
Most immediates are common values such as 1 (01) or -1 (FF..FF) that are immediately obvious:
80480a8: b8 03 00 00 00 mov $0x3,%eax
8048091: b8 04 00 00 00 mov $0x4,%eax
80480ec: b8 01 00 00 00 mov $0x1,%eax
Espcially when there is a very familiar pattern and leading (or in x86's case trailing zeros)
It should be immediately obvious that B8 is the opcode for loading a 32bit immediate value into eax, which can be written in M1 as:
DEFINE MOV_Immediate32_EAX B8
or
DEFINE LOADI32_R0 B8
You only need to remember to follow that mnemonic with a 32bit immediate (%4 works)
**** Easy example
For some immediate instructions the size and placement of the immediate is obvious (or perhaps obvious once you realize the Endianness of the instruction set you are working with)
For example:
80480b3: a0 f3 90 04 08 mov 0x80490f3,%al
Knowing that x86 is little endian, the 08 should pop out at you.
f3 90 04 08 is the little endian encoding of the number 0x080490F3
and thus we know that the opcode is A0 and it requires a 32bit value (An absolute address) and that it writes that result to al (which is the bottom 8bits of the eax register)
Thus we can express this opcode as:
DEFINE MOV_Absolute32_al A0
or
LOAD8_R0_Absolute32 A0
Which then always has to be followed by a 32bit absolute address ($foo works)
**** Annoying example
For some instructions, you may have to lookup the opcode to determine its length and thus the length of its immediate such as:
80480b1: 74 34 je 80480e7
Which when confronted with such a case, simply lookup the 74 in http://ref.x86asm.net/coder32.html
thus resolving to it is both jz and je and it takes a 8bit relative address (the 34).
Thus we can define our newly determined opcode in M1 as:
DEFINE JE8 74
DEFINE JZ8 74
or
DEFINE Jump_if_Zero8 74
but we need to make sure that whenever we use our mnemonic we follow it with a 8bit relative value (!label works well)
*** Things objdump gets wrong
The thing all disassemblers tend to get wrong and dependes entirely on heuristics is the identification of strings and byte constants.
In our case, it has identified our table as a set of instructions (also correctly determined their representation)
08048074 :
8048074: 30 31 xor %dh,(%ecx)
8048076: 32 33 xor (%ebx),%dh
8048078: 34 35 xor $0x35,%al
804807a: 36 37 ss aaa
804807c: 38 39 cmp %bh,(%ecx)
804807e: 41 inc %ecx
804807f: 42 inc %edx
8048080: 43 inc %ebx
8048081: 44 inc %esp
8048082: 45 inc %ebp
8048083: 46 inc %esi
8048084: 0a .byte 0xa
In M1 we have the ability to do things like strings to store such a table.
Which would probably be the following:
:output
"0123456789ABCDEF"
Which certainly alot easier to read and understand than
output: .byte 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x0A
* Using that opcode information to write a M1 program
Thus we would come to a defintion list that looks something like this:
DEFINE MOVZBL_al_To_eax 0FB6C0
DEFINE JE8 74
DEFINE ADD_Immediate32_To_ebp 81C5
DEFINE ADD_Immediate32_To_esi 81C6
DEFINE ANDI8_ebp 83E5
DEFINE TEST_eax_eax 85C0
DEFINE MOV_eax_To_ecx 89C1
DEFINE MOV_eax_To_ebp 89C5
DEFINE MOV_eax_To_esi 89C6
DEFINE MOV_ebp_To_eax 89E8
DEFINE MOV_esi_To_eax 89F0
DEFINE LOAD8_al A0
DEFINE LOADI32_eax B8
DEFINE LOADI32_ecx B9
DEFINE LOADI32_edx BA
DEFINE LOADI32_ebx BB
DEFINE SHIFT_RIGHT_Immediate8_esi C1EE
DEFINE RETURN C3
DEFINE INT_80 CD80
DEFINE CALLI32 E8
DEFINE JUMP8 EB
** emacs tips
Using the objdump output, first clear the labels and not instruction data.
Then leverage C-x ( and C-x ) to define a keyboard macro that deletes the address from the start of the line. C-x e followed by e repeatedly to clear all of the lines.
M-x sort-lines, will sort all selected lines (very useful as now all instructions with the same opcode are next to each other for easy pruning)
M-x delete-duplicate-lines will purge all exact duplicates (very handy for compiler output)
Then all that remains is determining the immediates and figuring out what line actually does. This is left as an exercise for the reader.
mescc-tools-Release_1.3/HACKING 0000664 0000000 0000000 00000005310 14126326331 0016234 0 ustar 00root root 0000000 0000000 -*-mode:org-*-
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
mescc-tools being based on the goal of absolute minimal platform bootstrap.
If your hardware doesn't have some crazy engineering decisions, mescc-tools can
and likely will be trivially ported to it.
* SETUP
The most obvious way to setup for mescc-tools development is to install any C
compiler and make clone of your choice.
* BUILD
The standard C based approach to building mescc-tools is simply running:
make
Should you wish to verify that mescc-tools was built correctly run:
make test
* ADDING an ARCHITECTURE
The process is simple:
1) add an architecture flag for your architecture to hex2_linker.c
2) Then make sure byte and then bit order are correct
3) Tweak to make sure immediate prefixes are the correct size for your architecture
4) Then make sure relative displacements are calculated correctly
5) Then make sure absolute displacements are calculated correctly
6) add an architecture flag for your architecture to M1-Macro.c
7) Then make sure byte and then bit order are correct
8) Tweak to make sure immediate prefixes are the correct size for your architecture
9) If you require unusual string padding, please add that now
10) Write your architecture.def or architecture.M1 file to include instruction
and register encodings that map to the required encoding.
* ROADMAP
The current outstanding work for mescc-tools is several architecture specific
bootstrap ports, that unfortunately share C level code but require significant
manual labor to implement.
* DEBUG
The default build process will generate debuggable binaries.
as blood-elf will generate the segments and text section required for proper debugging
* Bugs
mescc-tools is the most unforgiving assembly development environment possible.
Things such as manual padding requirements, arbitrary instruction encoding and
other features of these tools, make for rapid bootstrapping but horrific
development environments.
Please only use these tools to bootstrap your system from zero; otherwise cross-
compile with gcc and save yourself the pain.
mescc-tools-Release_1.3/INSTALL 0000664 0000000 0000000 00000002214 14126326331 0016276 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
Building and Installing mescc-tools
* Get it
git clone https://github.com/oriansj/mescc-tools.git
* Prerequisites
** Bootstrapping
mescc-tools can be bootstrapped from a simple hex assembler.
mescc-tools-seed contains the steps for several architectures on posix systems
to do so.
** Development
The tools required for easier development include binutils, gcc and make
* Build it
make
* Check it
make test
* Install it
make install
mescc-tools-Release_1.3/Kaem/ 0000775 0000000 0000000 00000000000 14126326331 0016123 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/.gitignore 0000664 0000000 0000000 00000000230 14126326331 0020106 0 ustar 00root root 0000000 0000000 # Ignore build directory
bin/
# Ignore Temp directory
temp/
# Ignore test result directory
test/results/
# Ignore temp and special files
*.tst
*.qst
mescc-tools-Release_1.3/Kaem/README 0000664 0000000 0000000 00000000313 14126326331 0017000 0 ustar 00root root 0000000 0000000 kaem is the world's worst build tool.
You really really should use make instead.
This tool exists only as the bare bottom floor scriptable build tool for bootstrapping.
Avoid as there be dragons here.
mescc-tools-Release_1.3/Kaem/kaem.c 0000664 0000000 0000000 00000055330 14126326331 0017212 0 ustar 00root root 0000000 0000000 /* Copyright (C) 2016-2020 Jeremiah Orians
* Copyright (C) 2020 fosslinux
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include
#include
#include "kaem.h"
/* Prototypes from other files */
void handle_variables(char** argv, struct Token* n);
/*
* UTILITY FUNCTIONS
*/
/* Function to find a character in a string */
char* find_char(char* string, char a)
{
if(0 == string[0]) return NULL;
while(a != string[0])
{
string = string + 1;
if(0 == string[0]) return string;
}
return string;
}
/* Function to find the length of a char**; an array of strings */
int array_length(char** array)
{
int length = 0;
while(array[length] != NULL)
{
length = length + 1;
}
return length;
}
/* Search for a variable in the env linked-list */
char* env_lookup(char* variable)
{
/* Start at the head */
struct Token* n = env;
/* Loop over the linked-list */
while(n != NULL)
{
if(match(variable, n->var))
{ /* We have found the correct node */
return n->value; /* Done */
}
/* Nope, try the next */
n = n->next;
}
/* We didn't find anything! */
return NULL;
}
/* Find the full path to an executable */
char* find_executable(char* name)
{
if(match("", name)) return NULL;
if(('.' == name[0]) || ('/' == name[0]))
{ /* assume names that start with . or / are relative or absolute */
return name;
}
char* trial = calloc(MAX_STRING, sizeof(char));
char* MPATH = calloc(MAX_STRING, sizeof(char)); /* Modified PATH */
require(MPATH != NULL, "Memory initialization of MPATH in find_executable failed\n");
strcpy(MPATH, PATH);
FILE* t;
char* next = find_char(MPATH, ':');
int index;
int offset;
int mpath_length;
int name_length;
int trial_length;
while(NULL != next)
{
/* Reset trial */
trial_length = strlen(trial);
for(index = 0; index < trial_length; index = index + 1)
{
trial[index] = 0;
}
next[0] = 0;
/* prepend_string(MPATH, prepend_string("/", name)) */
mpath_length = strlen(MPATH);
for(index = 0; index < mpath_length; index = index + 1)
{
require(MAX_STRING > index, "Element of PATH is too long\n");
trial[index] = MPATH[index];
}
trial[index] = '/';
offset = strlen(trial);
name_length = strlen(name);
for(index = 0; index < name_length; index = index + 1)
{
require(MAX_STRING > index, "Element of PATH is too long\n");
trial[index + offset] = name[index];
}
/* Try the trial */
require(strlen(trial) < MAX_STRING, "COMMAND TOO LONG!\nABORTING HARD\n");
t = fopen(trial, "r");
if(NULL != t)
{
fclose(t);
return trial;
}
MPATH = next + 1;
next = find_char(MPATH, ':');
}
return NULL;
}
/* Function to convert a Token linked-list into an array of strings */
char** list_to_array(struct Token* s)
{
char* hold;
struct Token* n;
n = s;
char** array = calloc(MAX_ARRAY, sizeof(char*));
require(array != NULL, "Memory initialization of array in conversion of list to array failed\n");
char* element = calloc(MAX_STRING, sizeof(char));
require(element != NULL, "Memory initialization of element in conversion of list to array failed\n");
int index = 0;
int i;
int value_length;
int var_length;
int offset;
while(n != NULL)
{ /* Loop through each node and assign it to an array index */
array[index] = calloc(MAX_STRING, sizeof(char));
require(array[index] != NULL, "Memory initialization of array[index] in conversion of list to array failed\n");
/* Bounds checking */
/* No easy way to tell which it is, output generic message */
require(index < MAX_ARRAY, "SCRIPT TOO LONG or TOO MANY ENVARS\nABORTING HARD\n");
if(n->var == NULL)
{ /* It is a line */
array[index] = n->value;
}
else
{ /* It is a var */
/* prepend_string(n->var, prepend_string("=", n->value)) */
var_length = strlen(n->var);
for(i = 0; i < var_length; i = i + 1)
{
element[i] = n->var[i];
}
element[i] = '=';
i = i + 1;
offset = i;
value_length = strlen(n->value);
for(i = 0; i < value_length; i = i + 1)
{
element[i + offset] = n->value[i];
}
}
/* Insert elements if not empty */
if(!match("", element)) strcpy(array[index], element);
n = n->next;
index = index + 1;
/* Reset element */
for(i = 0; i < MAX_STRING; i = i + 1) element[i] = 0;
}
return array;
}
/* Function to handle the correct options for escapes */
int handle_escape(int c)
{
if(c == '\n')
{ /* Do nothing - eat up the newline */
return -1;
}
else if('n' == c)
{ /* Add a newline to the token */
return '\n';
}
else if('r' == c)
{ /* Add a return to the token */
return '\r';
}
else if('\\' == c)
{ /* Add a real backslash to the token */
return '\\';
}
else
{ /* Just add it to the token (eg, quotes) */
return c;
}
}
/*
* TOKEN COLLECTION FUNCTIONS
*/
/* Function for skipping over line comments */
void collect_comment(FILE* input)
{
int c;
/* Eat up the comment, one character at a time */
/*
* Sanity check that the comment ends with \n.
* Remove the comment from the FILE*
*/
do
{
c = fgetc(input);
/* We reached an EOF!! */
require(EOF != c, "IMPROPERLY TERMINATED LINE COMMENT!\nABORTING HARD\n");
} while('\n' != c); /* We can now be sure it ended with \n -- and have purged the comment */
}
/* Function for collecting strings and removing the "" pair that goes with them */
int collect_string(FILE* input, char* n, int index)
{
int string_done = FALSE;
int c;
int cc;
do
{
/* Bounds check */
require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");
c = fgetc(input);
require(EOF != c, "IMPROPERLY TERMINATED STRING!\nABORTING HARD\n");
if('\\' == c)
{ /* We are escaping the next character */
/* This correctly handles escaped quotes as it just returns the quote */
c = fgetc(input);
cc = handle_escape(c);
n[index] = c;
index = index + 1;
}
else if('"' == c)
{ /* End of string */
string_done = TRUE;
}
else
{
n[index] = c;
index = index + 1;
}
} while(string_done == FALSE);
return index;
}
/* Function to parse and assign token->value */
int collect_token(FILE* input, char* n, int last_index)
{
int c;
int cc;
int token_done = FALSE;
char* token = calloc(MAX_STRING, sizeof(char));
require(token != NULL, "Memory initialization of token in collect_token failed\n");
int index = 0;
do
{ /* Loop over each character in the token */
c = fgetc(input);
/* Bounds checking */
require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");
if(EOF == c)
{ /* End of file -- this means script complete */
/* We don't actually exit here. This logically makes more sense;
* let the code follow its natural path of execution and exit
* sucessfuly at the end of main().
*/
token_done = TRUE;
command_done = TRUE;
return -1;
}
else if((' ' == c) || ('\t' == c))
{ /* Space and tab are token seperators */
token_done = TRUE;
}
else if('\n' == c)
{ /* Command terminates at end of a line */
command_done = TRUE;
token_done = TRUE;
if(0 == index) index = last_index;
}
else if('"' == c)
{ /* Handle strings -- everything between a pair of "" */
index = collect_string(input, n, index);
token_done = TRUE;
}
else if('#' == c)
{ /* Handle line comments */
collect_comment(input);
command_done = TRUE;
token_done = TRUE;
if(0 == index) index = last_index;
}
else if('\\' == c)
{ /* Support for escapes */
c = fgetc(input); /* Skips over \, gets the next char */
cc = handle_escape(c);
if(-1 != cc)
{ /* We need to put it into the token */
n[index] = cc;
}
index = index + 1;
}
else if(0 == c)
{ /* We have come to the end of the token */
token_done = TRUE;
}
else
{ /* It's a character to assign */
n[index] = c;
index = index + 1;
}
} while (token_done == FALSE);
return index;
}
/*
* EXECUTION FUNCTIONS
* Note: All of the builtins return FALSE (0) when they exit successfully
* and TRUE (1) when they fail.
*/
/* Function to check if the token is an envar */
int is_envar(char* token)
{
int i = 0;
int token_length = strlen(token);
while(i < token_length)
{
if(token[i] == '=')
{
return TRUE;
}
i = i + 1;
}
return FALSE;
}
/* Add an envar */
void add_envar()
{
/* Pointers to strings we want */
char* name = calloc(strlen(token->value) + 4, sizeof(char));
char* value = token->value;
char* newvalue;
int i = 0;
/* Isolate the name */
while('=' != value[i])
{
name[i] = value[i];
i = i + 1;
}
/* Isolate the value */
newvalue = name + i + 2;
value = value + i + 1;
i = 0;
require(0 != value[i], "add_envar recieved improper variable\n");
while(0 != value[i])
{
newvalue[i] = value[i];
i = i + 1;
}
/* If we are in init-mode and this is the first var env == NULL, rectify */
if(env == NULL)
{
env = calloc(1, sizeof(struct Token));
require(env != NULL, "Memory initialization of env failed\n");
env->var = name; /* Add our first variable */
}
/*
* If the name of the envar is PATH, then we need to set our (internal)
* global PATH value.
*/
if(match(name, "PATH"))
{
strcpy(PATH, newvalue);
}
struct Token* n = env;
/* Find match if possible */
while(!match(name, n->var))
{
if(NULL == n->next)
{
n->next = calloc(1, sizeof(struct Token));
require(n->next != NULL, "Memory initialization of next env node in add_envar failed\n");
n->next->var = name;
} /* Loop will match and exit */
n = n->next;
}
/* Since we found the variable we need only to set it to its new value */
n->value = newvalue;
}
/* cd builtin */
int cd()
{
if(NULL == token->next) return TRUE;
token = token->next;
if(NULL == token->value) return TRUE;
int ret = chdir(token->value);
if(0 > ret) return TRUE;
return FALSE;
}
/* pwd builtin */
int pwd()
{
char* path = calloc(MAX_STRING, sizeof(char));
require(path != NULL, "Memory initialization of path in pwd failed\n");
getcwd(path, MAX_STRING);
require(!match("", path), "getcwd() failed\n");
fputs(path, stdout);
fputs("\n", stdout);
return FALSE;
}
/* set builtin */
int set()
{
/* Get the options */
int i;
if(NULL == token->next) goto cleanup_set;
token = token->next;
if(NULL == token->value) goto cleanup_set;
char* options = calloc(MAX_STRING, sizeof(char));
require(options != NULL, "Memory initialization of options in set failed\n");
int last_position = strlen(token->value) - 1;
for(i = 0; i < last_position; i = i + 1)
{
options[i] = token->value[i + 1];
}
/* Parse the options */
int options_length = strlen(options);
for(i = 0; i < options_length; i = i + 1)
{
if(options[i] == 'a')
{ /* set -a is on by default and cannot be disabled at this time */
if(WARNINGS)
{
fputs("set -a is on by default and cannot be disabled\n", stdout);
}
continue;
}
else if(options[i] == 'e')
{ /* Fail on failure */
STRICT = TRUE;
}
else if(options[i] == 'x')
{ /* Show commands as executed */
/* TODO: this currently behaves like -v. Make it do what it should */
VERBOSE = TRUE;
/*
* Output the set -x because VERBOSE didn't catch it before.
* We don't do just -x because we support multiple options in one command,
* eg set -ex.
*/
fputs(" +> set -", stdout);
fputs(options, stdout);
fputs("\n", stdout);
fflush(stdout);
}
else
{ /* Invalid */
fputc(options[i], stderr);
fputs(" is an invalid set option!\n", stderr);
exit(EXIT_FAILURE);
}
}
return FALSE;
cleanup_set:
return TRUE;
}
/* echo builtin */
void echo()
{
if(token->next == NULL)
{ /* No arguments */
fputs("\n", stdout);
return;
}
if(token->next->value == NULL)
{ /* No arguments */
fputs("\n", stdout);
return;
}
token = token->next; /* Skip the actual echo */
while(token != NULL)
{ /* Output each argument to echo to stdout */
/* M2-Planet doesn't let us do this in the while */
if(token->value == NULL) break;
fputs(token->value, stdout);
token = token->next;
}
fputs("\n", stdout);
}
/* unset builtin */
void unset()
{
struct Token* e;
/* We support multiple variables on the same line */
struct Token* t;
t = token->next;
while(t != NULL)
{
e = env;
/* Look for the variable; we operate on ->next because we need to remove ->next */
while(e->next != NULL)
{
if(NULL == t->value) break;
if(match(e->next->var, t->value)) break;
e = e->next;
}
t = t->next;
/* If it's NULL nothing was found */
if(e->next == NULL) continue;
/* Otherwise there is something to unset */
e->next = e->next->next;
}
}
/* Execute program */
int execute()
{ /* Run the command */
/* rc = return code */
int rc;
/* Actually do the execution */
if(is_envar(token->value) == TRUE)
{
add_envar();
return 0;
}
else if(match(token->value, "cd"))
{
rc = cd();
if(STRICT) require(rc == FALSE, "cd failed!\n");
return 0;
}
else if(match(token->value, "set"))
{
rc = set();
if(STRICT) require(rc == FALSE, "set failed!\n");
return 0;
}
else if(match(token->value, "pwd"))
{
rc = pwd();
if(STRICT) require(rc == FALSE, "pwd failed!\n");
return 0;
}
else if(match(token->value, "echo"))
{
echo();
return 0;
}
else if(match(token->value, "unset"))
{
unset();
return 0;
}
/* If it is not a builtin, run it as an executable */
int status; /* i.e. return code */
char** array;
char** envp;
/* Get the full path to the executable */
char* program = find_executable(token->value);
/* Check we can find the executable */
if(NULL == program)
{
if(STRICT == TRUE)
{
fputs("WHILE EXECUTING ", stderr);
fputs(token->value, stderr);
fputs(" NOT FOUND!\nABORTING HARD\n", stderr);
exit(EXIT_FAILURE);
}
/* If we are not strict simply return */
return 0;
}
int f = fork();
/* Ensure fork succeeded */
if (f == -1)
{
fputs("WHILE EXECUTING ", stderr);
fputs(token->value, stderr);
fputs("fork() FAILED\nABORTING HARD\n", stderr);
exit(EXIT_FAILURE);
}
else if (f == 0)
{ /* Child */
/**************************************************************
* Fuzzing produces random stuff; we don't want it running *
* dangerous commands. So we just don't execve. *
* But, we still do the list_to_array calls to check for *
* segfaults. *
**************************************************************/
array = list_to_array(token);
envp = list_to_array(env);
if(FALSE == FUZZING)
{ /* We are not fuzzing */
/* execve() returns only on error */
execve(program, array, envp);
}
/* Prevent infinite loops */
_exit(EXIT_SUCCESS);
}
/* Otherwise we are the parent */
/* And we should wait for it to complete */
waitpid(f, &status, 0);
return status;
}
int collect_command(FILE* script, char** argv)
{
command_done = FALSE;
/* Initialize token */
struct Token* n;
n = calloc(1, sizeof(struct Token));
require(n != NULL, "Memory initialization of token in collect_command failed\n");
char* s = calloc(MAX_STRING, sizeof(char));
require(s != NULL, "Memory initialization of token in collect_command failed\n");
token = n;
int index = 0;
/* Get the tokens */
while(command_done == FALSE)
{
index = collect_token(script, s, index);
/* Don't allocate another node if the current one yielded nothing, OR
* if we are done.
*/
if(match(s, "")) continue;
/* add to token */
n->value = s;
s = calloc(MAX_STRING, sizeof(char));
require(s != NULL, "Memory initialization of next token node in collect_command failed\n");
/* Deal with variables */
handle_variables(argv, n);
/* If the variable expands into nothing*/
if(match(n->value, " "))
{
n->value = NULL;
continue;
}
/* Prepare for next loop */
n->next = calloc(1, sizeof(struct Token));
require(n->next != NULL, "Memory initialization of next token node in collect_command failed\n");
n = n->next;
}
/* -1 means the script is done */
if(EOF == index) return index;
/* Output the command if verbose is set */
/* Also if there is nothing in the command skip over */
if(VERBOSE && !match(token->value, "") && !match(token->value, NULL))
{
n = token;
fputs(" +>", stdout);
while(n != NULL)
{ /* Print out each token token */
fputs(" ", stdout);
/* M2-Planet doesn't let us do this in the while */
if(n->value != NULL)
{
if(!match(n->value, "")) fputs(n->value, stdout);
}
n = n->next;
}
fputc('\n', stdout);
fflush(stdout);
}
return index;
}
/* Function for executing our programs with desired arguments */
void run_script(FILE* script, char** argv)
{
int index;
int status;
while(TRUE)
{
/*
* Tokens has to be reset each time, as we need a new linked-list for
* each line.
* See, the program flows like this as a high level overview:
* Get line -> Sanitize line and perform variable replacement etc ->
* Execute line -> Next.
* We don't need the previous lines once they are done with, so tokens
* are hence for each line.
*/
index = collect_command(script, argv);
/* -1 means the script is done */
if(EOF == index) break;
if(0 == index) continue;
/* Stuff to exec */
status = execute();
if(STRICT == TRUE && (0 != status))
{ /* Clearly the script hit an issue that should never have happened */
fputs("Subprocess error ", stderr);
fputs(int2str(status, 10, TRUE), stderr);
fputs("\nABORTING HARD\n", stderr);
exit(EXIT_FAILURE);
}
}
}
/* Function to populate env */
void populate_env(char** envp)
{
/* You can't populate a NULL environment */
if(NULL == envp) return;
/* avoid empty arrays */
int max = array_length(envp);
if(0 == max) return;
/* Initialize env and n */
env = calloc(1, sizeof(struct Token));
require(env != NULL, "Memory initialization of env failed\n");
struct Token* n;
n = env;
int i;
int j;
int k;
char* envp_line;
for(i = 0; i < max; i = i + 1)
{
n->var = calloc(MAX_STRING, sizeof(char));
require(n->var != NULL, "Memory initialization of n->var in population of env failed\n");
n->value = calloc(MAX_STRING, sizeof(char));
require(n->value != NULL, "Memory initialization of n->var in population of env failed\n");
j = 0;
/*
* envp is weird.
* When referencing envp[i]'s characters directly, they were all jumbled.
* So just copy envp[i] to envp_line, and work with that - that seems
* to fix it.
*/
envp_line = calloc(MAX_STRING, sizeof(char));
require(envp_line != NULL, "Memory initialization of envp_line in population of env failed\n");
strcpy(envp_line, envp[i]);
while(envp_line[j] != '=')
{ /* Copy over everything up to = to var */
n->var[j] = envp_line[j];
j = j + 1;
}
/* If we get strange input, we need to ignore it */
if(n->var == NULL) continue;
j = j + 1; /* Skip over = */
k = 0; /* As envp[i] will continue as j but n->value begins at 0 */
while(envp_line[j] != 0)
{ /* Copy everything else to value */
n->value[k] = envp_line[j];
j = j + 1;
k = k + 1;
}
/* Sometimes, we get lines like VAR=, indicating nothing is in the variable */
if(n->value == NULL) n->value = "";
/* Advance to next part of linked list */
n->next = calloc(1, sizeof(struct Token));
require(n->next != NULL, "Memory initialization of n->next in population of env failed\n");
n = n->next;
}
/* Get rid of node on the end */
n = NULL;
/* Also destroy the n->next reference */
n = env;
while(n->next->var != NULL) n = n->next;
n->next = NULL;
}
int main(int argc, char** argv, char** envp)
{
VERBOSE = FALSE;
STRICT = FALSE;
FUZZING = FALSE;
WARNINGS = FALSE;
char* filename = "kaem.run";
FILE* script = NULL;
/* Initalize structs */
token = calloc(1, sizeof(struct Token));
require(token != NULL, "Memory initialization of token failed\n");
int i = 1;
/* Loop over arguments */
while(i <= argc)
{
if(NULL == argv[i])
{ /* Ignore the argument */
i = i + 1;
}
else if(match(argv[i], "-h") || match(argv[i], "--help"))
{ /* Help information */
fputs("Usage: ", stdout);
fputs(argv[0], stdout);
fputs(" [-h | --help] [-V | --version] [--file filename | -f filename] [-i | --init-mode] [-v | --verbose] [--strict] [--warn] [--fuzz]\n", stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[i], "-f") || match(argv[i], "--file"))
{ /* Set the filename */
if(argv[i + 1] != NULL)
{
filename = argv[i + 1];
}
i = i + 2;
}
else if(match(argv[i], "-i") || match(argv[i], "--init-mode"))
{ /* init mode does not populate env */
INIT_MODE = TRUE;
i = i + 1;
}
else if(match(argv[i], "-V") || match(argv[i], "--version"))
{ /* Output version */
fputs("kaem version 1.1.0\n", stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[i], "-v") || match(argv[i], "--verbose"))
{ /* Set verbose */
VERBOSE = TRUE;
i = i + 1;
}
else if(match(argv[i], "--strict"))
{ /* Set strict */
STRICT = TRUE;
i = i + 1;
}
else if(match(argv[i], "--warn"))
{ /* Set warnings */
WARNINGS = TRUE;
i = i + 1;
}
else if(match(argv[i], "--fuzz"))
{ /* Set fuzzing */
FUZZING = TRUE;
i = i + 1;
}
else if(match(argv[i], "--"))
{ /* Nothing more after this */
break;
}
else
{ /* We don't know this argument */
fputs("UNKNOWN ARGUMENT\n", stdout);
exit(EXIT_FAILURE);
}
}
/* Populate env */
if(INIT_MODE == FALSE)
{
populate_env(envp);
}
/* Populate PATH variable
* We don't need to calloc() because env_lookup() does this for us.
*/
PATH = env_lookup("PATH");
/* Populate USERNAME variable */
char* USERNAME = env_lookup("LOGNAME");
/* Handle edge cases */
if((NULL == PATH) && (NULL == USERNAME))
{ /* We didn't find either of PATH or USERNAME -- use a generic PATH */
PATH = calloc(MAX_STRING, sizeof(char));
require(PATH != NULL, "Memory initialization of PATH failed\n");
strcpy(PATH, "/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin");
}
else if(NULL == PATH)
{ /* We did find a username but not a PATH -- use a generic PATH but with /home/USERNAME */
PATH = calloc(MAX_STRING, sizeof(char));
PATH = strcat(PATH, "/home/");
PATH = strcat(PATH, USERNAME);
PATH = strcat(PATH, "/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games");
}
/* Open the script */
script = fopen(filename, "r");
if(NULL == script)
{
fputs("The file: ", stderr);
fputs(filename, stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
/* Run the commands */
run_script(script, argv);
/* Cleanup */
fclose(script);
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/Kaem/kaem.h 0000664 0000000 0000000 00000002651 14126326331 0017215 0 ustar 00root root 0000000 0000000 /* Copyright (C) 2016-2020 Jeremiah Orians
* Copyright (C) 2020 fosslinux
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include "../M2libc/bootstrappable.h"
/*
* DEFINES
*/
#define FALSE 0
#define TRUE 1
#define MAX_STRING 4096
#define MAX_ARRAY 256
/*
* Here is the token struct. It is used for both the token linked-list and
* env linked-list.
*/
struct Token
{
/*
* For the token linked-list, this stores the token; for the env linked-list
* this stores the value of the variable.
*/
char* value;
/*
* Used only for the env linked-list. It holds a string containing the
* name of the var.
*/
char* var;
/*
* This struct stores a node of a singly linked list, store the pointer to
* the next node.
*/
struct Token* next;
};
#include "kaem_globals.h"
mescc-tools-Release_1.3/Kaem/kaem_globals.c 0000664 0000000 0000000 00000002010 14126326331 0020700 0 ustar 00root root 0000000 0000000 /* Copyright (C) 2016-2020 Jeremiah Orians
* Copyright (C) 2020 fosslinux
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include "kaem.h"
int command_done;
int VERBOSE;
int STRICT;
int INIT_MODE;
int FUZZING;
int WARNINGS;
char* PATH;
/* Token linked-list; stores the tokens of each line */
struct Token* token;
/* Env linked-list; stores the environment variables */
struct Token* env;
mescc-tools-Release_1.3/Kaem/kaem_globals.h 0000664 0000000 0000000 00000002064 14126326331 0020716 0 ustar 00root root 0000000 0000000 /* Copyright (C) 2016-2020 Jeremiah Orians
* Copyright (C) 2020 fosslinux
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
extern int command_done;
extern int VERBOSE;
extern int STRICT;
extern int INIT_MODE;
extern int FUZZING;
extern int WARNINGS;
extern char* PATH;
/* Token linked-list; stores the tokens of each line */
extern struct Token* token;
/* Env linked-list; stores the environment variables */
extern struct Token* env;
mescc-tools-Release_1.3/Kaem/makefile 0000664 0000000 0000000 00000002714 14126326331 0017627 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2016 Jeremiah Orians
## Copyright (C) 2020 fosslinux
## This file is part of mescc-tools.
##
## mescc-tools is free software: you an redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
# Prevent rebuilding
VPATH = ../bin:test/results
all: kaem
CC=gcc
CFLAGS:=$(CFLAGS) -D_GNU_SOURCE -std=c99 -ggdb
kaem: kaem.c kaem_globals.c variable.c | bin
$(CC) $(CFLAGS) kaem.c \
kaem_globals.c \
variable.c \
../M2libc/bootstrappable.c \
-o ../bin/kaem
# Always run the tests
.PHONY: test
test: kaem | results
./test.sh
# Generate test answers
.PHONY: Generate-test-answers
Generate-test-answers:
sha256sum test/results/* >| test/test.answers
# Clean up after ourselves
.PHONY: clean
clean:
rm -rf ../bin/
rm -rf test/results/
results:
mkdir -p test/results
bin:
mkdir -p ../bin
DESTDIR:=
PREFIX:=/usr/local
bindir:=$(DESTDIR)$(PREFIX)/bin
.PHONY: install
install: kaem
mkdir -p $(bindir)
cp $^ $(bindir)
mescc-tools-Release_1.3/Kaem/test.sh 0000775 0000000 0000000 00000004152 14126326331 0017443 0 ustar 00root root 0000000 0000000 #!/bin/bash
# Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
echo "Starting kaem tests"
LANG=C ../bin/kaem -f "test/test00/kaem.test" >| "test/results/test00-output"
LANG=C ../bin/kaem -f "test/test01/kaem.test" >| "test/results/test01-output"
LANG=C ../bin/kaem -f "test/test02/kaem.test" >| "test/results/test02-output"
LANG=C ../bin/kaem -f "test/test03/kaem.test" >| "test/results/test03-output"
LANG=C ../bin/kaem -f "test/test04/kaem.test" >| "test/results/test04-output" 2>&1
LANG=C ../bin/kaem -f "test/test05/kaem.test" >| "test/results/test05-output"
LANG=C ../bin/kaem -f "test/test06/kaem.test" >| "test/results/test06-output" 2>&1
LANG=C ../bin/kaem -f "test/test07/kaem.test" >| "test/results/test07-output"
LANG=C ../bin/kaem -f "test/test08/kaem.test" >| "test/results/test08-output"
LANG=C ../bin/kaem -f "test/test09/kaem.test" >| "test/results/test09-output"
LANG=C ../bin/kaem -f "test/test10/kaem.test" >| "test/results/test10-output"
LANG=C ../bin/kaem -f "test/test11/kaem.test" >| "test/results/test11-output"
LANG=C ../bin/kaem -f "test/test12/kaem.test" >| "test/results/test12-output"
LANG=C ../bin/kaem -f "test/test13/kaem.test" >| "test/results/test13-output"
LANG=C ../bin/kaem -f "test/test14/kaem.test" >| "test/results/test14-output" 2>&1
LANG=C ../bin/kaem -f "test/test15/kaem.test" >| "test/results/test15-output"
LANG=C ../bin/kaem -f "test/test16/kaem.test" >| "test/results/test16-output"
. ../sha256.sh
sha256_check test/test.answers
echo "kaem tests complete"
mescc-tools-Release_1.3/Kaem/test/ 0000775 0000000 0000000 00000000000 14126326331 0017102 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/.gitignore 0000664 0000000 0000000 00000000011 14126326331 0021062 0 ustar 00root root 0000000 0000000 results/
mescc-tools-Release_1.3/Kaem/test/test.answers 0000664 0000000 0000000 00000003055 14126326331 0021470 0 ustar 00root root 0000000 0000000 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test/results/test00-output
27e6f695d734689575e2a063b77668a1fab9c7a83071134630f6a02ebf697592 test/results/test01-output
98ea6e4f216f2fb4b69fff9b3a44842c38686ca685f3f55dc48c5d3fb1107be4 test/results/test02-output
5881f8af754d89e4b6f0cc5e65a0654444a83140946a83f7d5941e6236f180d2 test/results/test03-output
8753402793cfecacc5b90b6c7c0f8b351c9be60fd7d07fe18cf4a189bfff16f3 test/results/test04-output
8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4 test/results/test05-output
11b03bec7e7e57151b67cf4d3b38cc5cc9a0469549e104f58b9bf9de82f90c22 test/results/test06-output
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test/results/test07-output
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 test/results/test08-output
714ef04291d344f7719c207060944b017d4b565ef565b04fbef5ec4c3e8cacb8 test/results/test09-output
d857aa87f123be8ca15bab264d2fbc143fe6ca9fa82ebfcc92a3096627c2bfbd test/results/test10-output
95b4340f5a016b59be85be8351cb267642fea01129c8ae40049061301c1b0a95 test/results/test11-output
dfb2a6b3ee002a7a82419230acf97563ffe8b84e72f0de074e48453b092da4ad test/results/test12-output
8148f4b7ea4ab56d699162b872c2f622693a9a5621cdf78ad16cad3d47571ffb test/results/test13-output
8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4 test/results/test14-output
3b22d4ec57697b461347a0c8d195c854172ae4b8c92b86497f2bbd8add4c4229 test/results/test15-output
472ed61017e76d36a6340ad495bd9e7be5f721d8df65fd4c2caa75e88a412601 test/results/test16-output
mescc-tools-Release_1.3/Kaem/test/test00/ 0000775 0000000 0000000 00000000000 14126326331 0020221 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test00/kaem.test 0000664 0000000 0000000 00000001374 14126326331 0022044 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# This test tests line comments!
# There should be no output.
mescc-tools-Release_1.3/Kaem/test/test01/ 0000775 0000000 0000000 00000000000 14126326331 0020222 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test01/kaem.test 0000664 0000000 0000000 00000001367 14126326331 0022047 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test execution of simple commands.
printf hi
printf hi
mescc-tools-Release_1.3/Kaem/test/test02/ 0000775 0000000 0000000 00000000000 14126326331 0020223 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test02/kaem.test 0000664 0000000 0000000 00000001322 14126326331 0022037 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test echo
echo hi
mescc-tools-Release_1.3/Kaem/test/test03/ 0000775 0000000 0000000 00000000000 14126326331 0020224 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test03/kaem.test 0000664 0000000 0000000 00000001344 14126326331 0022044 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test use of set -x
set -x
printf hi
mescc-tools-Release_1.3/Kaem/test/test04/ 0000775 0000000 0000000 00000000000 14126326331 0020225 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test04/kaem.test 0000664 0000000 0000000 00000001374 14126326331 0022050 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test use of set -e
set -e
thiscommanddoesnotexist
printf hi
mescc-tools-Release_1.3/Kaem/test/test05/ 0000775 0000000 0000000 00000000000 14126326331 0020226 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test05/kaem.test 0000664 0000000 0000000 00000001414 14126326331 0022044 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test non existent commands without set -e
thiscommanddoesnotexist
printf hi
mescc-tools-Release_1.3/Kaem/test/test06/ 0000775 0000000 0000000 00000000000 14126326331 0020227 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test06/kaem.test 0000664 0000000 0000000 00000001422 14126326331 0022044 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test use of multiple arguments with set
set -ex
thiscommanddoesnotexist
printf hi
mescc-tools-Release_1.3/Kaem/test/test07/ 0000775 0000000 0000000 00000000000 14126326331 0020230 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test07/kaem.test 0000664 0000000 0000000 00000001420 14126326331 0022043 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# This is meant to test pwd.
# But I don't have a very good way to test it yet...
mescc-tools-Release_1.3/Kaem/test/test08/ 0000775 0000000 0000000 00000000000 14126326331 0020231 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test08/kaem.test 0000664 0000000 0000000 00000001341 14126326331 0022046 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test adding of an envar
VAR=text
mescc-tools-Release_1.3/Kaem/test/test09/ 0000775 0000000 0000000 00000000000 14126326331 0020232 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test09/kaem.test 0000664 0000000 0000000 00000001343 14126326331 0022051 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test RAW strings
echo "raw string"
mescc-tools-Release_1.3/Kaem/test/test10/ 0000775 0000000 0000000 00000000000 14126326331 0020222 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test10/kaem.test 0000664 0000000 0000000 00000001501 14126326331 0022035 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test simple variable substitution
VAR=text
ANOTHER=more
echo text-${VAR}-${ANOTHER}-text
../bin/kaem -f test/test10/subkaem.test
mescc-tools-Release_1.3/Kaem/test/test10/subkaem.test 0000664 0000000 0000000 00000001433 14126326331 0022553 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test simple variable substitution, passed to another kaem
echo text-${VAR}-${ANOTHER}-text
mescc-tools-Release_1.3/Kaem/test/test11/ 0000775 0000000 0000000 00000000000 14126326331 0020223 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test11/kaem.test 0000664 0000000 0000000 00000001423 14126326331 0022041 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test variable subsitution with :- where the var exists
VAR=exists
echo ${VAR:-not}
mescc-tools-Release_1.3/Kaem/test/test12/ 0000775 0000000 0000000 00000000000 14126326331 0020224 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test12/kaem.test 0000664 0000000 0000000 00000001425 14126326331 0022044 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test variable subsitution with :- where the variable does not exist
echo ${VAR:-not}
mescc-tools-Release_1.3/Kaem/test/test13/ 0000775 0000000 0000000 00000000000 14126326331 0020225 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test13/kaem.test 0000664 0000000 0000000 00000001347 14126326331 0022050 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test substitution of $@
echo $@ -- foo
mescc-tools-Release_1.3/Kaem/test/test14/ 0000775 0000000 0000000 00000000000 14126326331 0020226 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test14/kaem.test 0000664 0000000 0000000 00000001353 14126326331 0022046 0 ustar 00root root 0000000 0000000 # Copyright (C) 2020 fosslinux
# This file is part of mescc-tools.
#
# mescc-tools is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
#
# Test end-of-line escapes
printf \
"hi"
mescc-tools-Release_1.3/Kaem/test/test15/ 0000775 0000000 0000000 00000000000 14126326331 0020227 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test15/kaem.test 0000664 0000000 0000000 00000000121 14126326331 0022037 0 ustar 00root root 0000000 0000000 VAR=test
ANOTHER=test2
echo ${VAR}
unset VAR ANOTHER
echo ${VAR}
echo ${ANOTHER}
mescc-tools-Release_1.3/Kaem/test/test16/ 0000775 0000000 0000000 00000000000 14126326331 0020230 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/Kaem/test/test16/kaem.test 0000664 0000000 0000000 00000000035 14126326331 0022044 0 ustar 00root root 0000000 0000000 echo \"test\"
echo "\"test2"
mescc-tools-Release_1.3/Kaem/variable.c 0000664 0000000 0000000 00000017655 14126326331 0020072 0 ustar 00root root 0000000 0000000 /*
* Copyright (C) 2020 fosslinux
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include
#include "kaem.h"
/* Prototypes from other files */
int array_length(char** array);
char* env_lookup(char* variable);
/*
* VARIABLE HANDLING FUNCTIONS
*/
/* Substitute a variable into n->value */
int run_substitution(char* var_name, struct Token* n)
{
char* value = env_lookup(var_name);
/* If there is nothing to substitute, don't substitute anything! */
if(value != NULL)
{
char* s = calloc(MAX_STRING, sizeof(char));
s = strcat(s, n->value);
s = strcat(s, value);
n->value = s;
return TRUE;
}
return FALSE;
}
/* Handle ${var:-text} format of variables - i.e. ifset format */
int variable_substitute_ifset(char* input, struct Token* n, int index)
{
/*
* In ${var:-text} format, we evaluate like follows.
* If var is set as an envar, then we substitute the contents of that
* envar. If it is not set, we substitute alternative text.
*
* In this function, we assume that input is the raw token,
* n->value is everything already done in variable_substitute,
* index is where we are up to in input. offset is for n->value.
*/
/*
* Check if we should even be performing this function.
* We perform this function when we come across ${var:-text} syntax.
*/
int index_old = index;
int perform = FALSE;
int input_length = strlen(input);
while(index < input_length)
{ /* Loop over each character */
if(input[index] == ':' && input[index + 1] == '-')
{ /* Yes, this is (most likely) ${var:-text} format. */
perform = TRUE;
break;
}
index = index + 1;
}
/* Don't perform it if we shouldn't */
if(perform == FALSE) return index_old;
index = index_old;
/*
* Get offset.
* offset is the difference between the index of the variable we write to
* in the following blocks and input.
* This stays relatively constant.
*/
int offset = index;
/* Get the variable name */
char* var_name = calloc(MAX_STRING, sizeof(char));
require(var_name != NULL, "Memory initialization of var_name in variable_substitute_ifset failed\n");
while(input[index] != ':')
{ /* Copy into var_name until :- */
var_name[index - offset] = input[index];
index = index + 1;
}
/* Skip over :- */
index = index + 2;
offset = index;
/* Get the alternative text */
char* text = calloc(MAX_STRING, sizeof(char));
require(text != NULL, "Memory initialization of text in variable_substitute_ifset failed\n");
while(input[index] != '}')
{ /* Copy into text until } */
require(input_length > index, "IMPROPERLY TERMINATED VARIABLE\nABORTING HARD\n");
text[index - offset] = input[index];
index = index + 1;
}
/* Do the substitution */
if(run_substitution(var_name, n) == FALSE)
{ /* The variable was not found. Substitute the alternative text. */
char* s = calloc(MAX_STRING, sizeof(char));
s = strcat(s, n->value);
s = strcat(s, text);
n->value = s;
}
return index;
}
/* Controls substitution for ${variable} and derivatives */
int variable_substitute(char* input, struct Token* n, int index)
{
/* NOTE: index is the pos of input */
index = index + 1; /* We don't want the { */
/*
* Check for "special" types
* If we do find a special type we delegate the substitution to it
* and return here; as we are done... there's nothing more do do in
* that case.
*/
int index_old = index;
index = variable_substitute_ifset(input, n, index);
if(index != index_old) return index;
/* Reset index */
index = index_old;
/*
* If we reach here it is a normal substitution
* Let's do it!
*/
/* Initialize var_name and offset */
char* var_name = calloc(MAX_STRING, sizeof(char));
require(var_name != NULL, "Memory initialization of var_name in variable_substitute failed\n");
int offset = index;
/* Get the variable name */
int substitute_done = FALSE;
char c;
while(substitute_done == FALSE)
{
c = input[index];
require(MAX_STRING > index, "LINE IS TOO LONG\nABORTING HARD\n");
if(EOF == c || '\n' == c || index > strlen(input))
{ /* We never should hit EOF, EOL or run past the end of the line
while collecting a variable */
fputs("IMPROPERLY TERMINATED VARIABLE!\nABORTING HARD\n", stderr);
exit(EXIT_FAILURE);
}
else if('\\' == c)
{ /* Drop the \ - poor mans escaping. */
index = index + 1;
}
else if('}' == c)
{ /* End of variable name */
substitute_done = TRUE;
}
else
{
var_name[index - offset] = c;
index = index + 1;
}
}
/* Substitute the variable */
run_substitution(var_name, n);
return index;
}
/* Function to concatenate all command line arguments */
void variable_all(char** argv, struct Token* n)
{
fflush(stdout);
/* index refernences the index of n->value, unlike other functions */
int index = 0;
int argv_length = array_length(argv);
int i = 0;
char* argv_element = calloc(MAX_STRING, sizeof(char));
char* hold = argv[i];
n->value = argv_element;
/* Assuming the form kaem -f script or kaem -f script -- 123 we want matching results to bash, so skip the kaem, -f and script */
while(!match("--", hold))
{
i = i + 1;
hold = argv[i];
if(argv_length == i) break;
}
/* put i = i + 1 in the for initialization to skip past the -- */
for(; i < argv_length; i = i + 1)
{
/* Ends up with (n->value) (argv[i]) */
/* If we don't do this we get jumbled results in M2-Planet */
hold = argv[i];
strcpy(argv_element + index, hold);
index = index + strlen(hold);
/* Add space on the end */
n->value[index] = ' ';
index = index + 1;
}
/* Remove trailing space */
index = index - 1;
n->value[index] = 0;
}
/* Function controlling substitution of variables */
void handle_variables(char** argv, struct Token* n)
{
/* NOTE: index is the position of input */
int index = 0;
/* Create input */
char* input = calloc(MAX_STRING, sizeof(char));
require(input != NULL, "Memory initialization of input in collect_variable failed\n");
strcpy(input, n->value);
/* Reset n->value */
n->value = calloc(MAX_STRING, sizeof(char));
require(n->value != NULL, "Memory initialization of n->value in collect_variable failed\n");
/* Copy everything up to the $ */
/*
* TODO: Not need allocation of input before this check if there is no
* variable in it.
*/
while(input[index] != '$')
{
if(input[index] == 0)
{ /* No variable in it */
n->value = input;
return; /* We don't need to do anything more */
}
n->value[index] = input[index];
index = index + 1;
}
/* Must be outside the loop */
int offset;
substitute:
index = index + 1; /* We are uninterested in the $ */
/* Run the substitution */
if(input[index] == '{')
{ /* Handle everything ${ related */
index = variable_substitute(input, n, index);
index = index + 1; /* We don't want the closing } */
}
else if(input[index] == '@')
{ /* Handles $@ */
index = index + 1; /* We don't want the @ */
variable_all(argv, n);
}
else
{ /* We don't know that */
fputs("IMPROPERLY USED VARIABLE!\nOnly ${foo} and $@ format are accepted at this time.\nABORTING HARD\n", stderr);
exit(EXIT_FAILURE);
}
offset = strlen(n->value) - index;
/* Copy everything from the end of the variable to the end of the token */
while(input[index] != 0)
{
if(input[index] == '$')
{ /* We have found another variable */
fflush(stdout);
goto substitute;
}
n->value[index + offset] = input[index];
index = index + 1;
}
}
mescc-tools-Release_1.3/M1-macro.c 0000664 0000000 0000000 00000046013 14126326331 0016772 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include "M2libc/bootstrappable.h"
/* Internal processing Constants */
// CONSTANT max_string 4096
#define max_string 4096
// CONSTANT PROCESSED 1
#define PROCESSED 1
// CONSTANT STR 2
#define STR 2
// CONSTANT NEWLINE 3
#define NEWLINE 3
/* Unique code for each architecture */
// CONSTANT KNIGHT 0
#define KNIGHT 0
// CONSTANT X86 3
#define X86 0x03
// CONSTANT AMD64 62
#define AMD64 0x3E
// CONSTANT ARMV7L 40
#define ARMV7L 0x28
// CONSTANT AARM64 183
#define AARM64 0xB7
// CONSTANT PPC64LE 21
#define PPC64LE 0x15
// CONSTANT RISCV32 243
#define RISCV32 0xF3
// CONSTANT RISCV64 65779
#define RISCV64 0x100F3 /* Because RISC-V unlike all other architectures does get a seperate e_machine when changing from 32 to 64bit */
/* How do you want that output? */
// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2
/* Imported from stringify.c */
int stringify(char* s, int digits, int divisor, int value, int shift);
void LittleEndian(char* start, int ByteMode);
struct blob
{
struct blob* next;
int type;
char* Text;
char* Expression;
struct blob* hash_next;
};
struct Token
{
struct Token* next;
struct blob* contents;
char* filename;
int linenumber;
};
/* Globals */
FILE* source_file;
FILE* destination_file;
int BigEndian;
int ByteMode;
int Architecture;
int linenumber;
struct Token* token_list;
struct blob* blob_list;
struct blob* define_blob;
struct blob* newline_blob;
int blob_count;
char* SCRATCH;
struct blob** hash_table;
void line_error(char* filename, int linenumber)
{
fputs(filename, stderr);
fputs(":", stderr);
fputs(int2str(linenumber,10, FALSE), stderr);
fputs(" :", stderr);
}
void ClearScratch()
{
int i = 0;
int c = SCRATCH[i];
while(0 != c)
{
SCRATCH[i] = 0;
i = i + 1;
c = SCRATCH[i];
}
}
int GetHash(char* s)
{
int i = 5381;
while(0 != s[0])
{
i = (i << 5) + i + s[0];
s = s + 1;
}
return i & 0xFFFF;
}
struct blob* FindBlob()
{
int hash = GetHash(SCRATCH);
struct blob* i = hash_table[hash];
while(NULL != i)
{
if(match(SCRATCH, i->Text)) return i;
i = i->hash_next;
}
return NULL;
}
void AddHash(struct blob* a, char* s)
{
int i = GetHash(s);
a->hash_next = hash_table[i];
hash_table[i] = a;
}
void NewBlob(int size)
{
blob_count = blob_count + 1;
struct blob* a = calloc(1, sizeof(struct blob));
require(NULL != a, "Exhausted available memory\n");
a->Text = calloc(size + 1, sizeof(char));
require(NULL != a->Text, "Exhausted available memory\n");
int i = 0;
while(i <= size)
{
a->Text[i] = SCRATCH[i];
i = i + 1;
}
a->next = blob_list;
blob_list = a;
AddHash(a, SCRATCH);
}
struct Token* newToken(char* filename, int linenumber)
{
struct Token* p;
p = calloc (1, sizeof (struct Token));
require(NULL != p, "Exhausted available memory\n");
p->filename = filename;
p->linenumber = linenumber;
return p;
}
struct Token* reverse_list(struct Token* head)
{
struct Token* root = NULL;
struct Token* next;
while(NULL != head)
{
next = head->next;
head->next = root;
root = head;
head = next;
}
return root;
}
void purge_lineComment()
{
int c = fgetc(source_file);
while(!in_set(c, "\n\r"))
{
if(EOF == c) break;
c = fgetc(source_file);
}
}
struct Token* append_newline(struct Token* head, char* filename)
{
linenumber = linenumber + 1;
if(NULL == head) return NULL;
if(NEWLINE == head->contents->type)
{/* Don't waste whitespace*/
return head;
}
struct Token* lf = newToken(filename, linenumber);
lf->contents = newline_blob;
lf->next = head;
return lf;
}
struct Token* store_atom(struct Token* head, char c, char* filename)
{
ClearScratch();
int ch = c;
int i = 0;
do
{
SCRATCH[i] = ch;
ch = fgetc(source_file);
i = i + 1;
if(i >= max_string)
{
fputs("storing atom of size larger than max_string\n", stderr);
line_error(filename, linenumber);
fputc('\n', stderr);
exit(EXIT_FAILURE);
}
if(EOF == ch) break;
} while (!in_set(ch, "\t\n "));
head->contents = FindBlob();
if(NULL == head->contents)
{
NewBlob(i);
head->contents = blob_list;
}
if('\n' == ch)
{
return append_newline(head, filename);
}
return head;
}
struct blob* store_string(char c, char* filename)
{
ClearScratch();
int ch = c;
int i = 0;
do
{
SCRATCH[i] = ch;
i = i + 1;
if('\n' == ch) linenumber = linenumber + 1;
ch = fgetc(source_file);
require(EOF != ch, "Unmatched \"!\n");
if(max_string == i)
{
line_error(filename, linenumber);
fputs("String: ", stderr);
fputs(SCRATCH, stderr);
fputs(" exceeds max string size\n", stderr);
exit(EXIT_FAILURE);
}
} while(ch != c);
struct blob* a = FindBlob();
if(NULL == a)
{
NewBlob(i);
a = blob_list;
a->type = STR;
}
return a;
}
struct Token* Tokenize_Line(struct Token* head, char* filename)
{
int c;
struct Token* p;
linenumber = 1;
do
{
restart:
c = fgetc(source_file);
if(in_set(c, ";#"))
{
purge_lineComment();
head = append_newline(head, filename);
goto restart;
}
if(in_set(c, "\t "))
{
goto restart;
}
if('\n' == c)
{
head = append_newline(head, filename);
goto restart;
}
if(EOF == c)
{
head = append_newline(head, filename);
goto done;
}
p = newToken(filename, linenumber);
p->next = head;
if(in_set(c, "'\""))
{
p->contents = store_string(c, filename);
}
else
{
p = store_atom(p, c, filename);
}
head = p;
} while(TRUE);
done:
return head;
}
void line_macro(struct Token* p)
{
struct Token* i;
for(i = p; NULL != i; i = i->next)
{
if(define_blob == i->contents)
{
require(NULL != i->next, "Macro name must exist\n");
require(NULL != i->next->next, "Macro value must exist\n");
if(PROCESSED == i->next->contents->type)
{
line_error(i->filename, i->linenumber);
fputs("Multiple definitions for macro ", stderr);
fputs(i->next->contents->Text, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
i->contents = newline_blob;
if (STR == i->next->next->contents->type)
{
i->contents->Expression = i->next->next->contents->Text + 1;
}
else
{
i->next->contents->Expression = i->next->next->contents->Text;
}
i->next = i->next->next->next;
}
}
}
void hexify_string(struct blob* p)
{
char* table = "0123456789ABCDEF";
int i = strlen(p->Text);
int size;
if(HEX == ByteMode) size = (((i << 1) + i) + 12);
else if(OCTAL == ByteMode) size = (i << 2) + 1;
else if(BINARY == ByteMode) size = (i << 3) + i + 1;
else size = 1;
require(1 != size, "hexify_string lacked a valid bytemode\n");
char* d = calloc(size, sizeof(char));
require(NULL != d, "Exhausted available memory\n");
p->Expression = d;
char* S = p->Text;
if((KNIGHT == Architecture) && (HEX == ByteMode))
{
i = (((((i - 1) >> 2) + 1) << 3) + i);
while( 0 < i)
{
i = i - 1;
d[i] = '0';
}
}
if(HEX == ByteMode)
{
while(0 != S[0])
{
S = S + 1;
d[0] = table[S[0] >> 4];
d[1] = table[S[0] & 0xF];
d[2] = ' ';
d = d + 3;
}
}
else if(OCTAL == ByteMode)
{
while(0 != S[0])
{
S = S + 1;
d[0] = table[S[0] >> 6];
d[1] = table[(S[0] >> 3) & 0x7];
d[2] = table[S[0] & 0x7];
d[3] = ' ';
d = d + 4;
}
}
else if(BINARY == ByteMode)
{
while(0 != S[0])
{
S = S + 1;
d[0] = table[S[0] >> 7];
d[1] = table[(S[0] >> 6) & 0x1];
d[2] = table[(S[0] >> 5) & 0x1];
d[3] = table[(S[0] >> 4) & 0x1];
d[4] = table[(S[0] >> 3) & 0x1];
d[5] = table[(S[0] >> 2) & 0x1];
d[6] = table[(S[0] >> 1) & 0x1];
d[7] = table[S[0] & 0x1];
d[8] = ' ';
d = d + 9;
}
}
}
void process_string(struct blob* p)
{
struct blob* i;
for(i = p; NULL != i; i = i->next)
{
if(STR == i->type)
{
if('\'' == i->Text[0])
{
i->Expression = i->Text + 1;
}
else if('"' == i->Text[0])
{
hexify_string(i);
}
}
}
}
char* pad_nulls(int size, char* nil)
{
if(0 == size) return nil;
require(size > 0, "negative null padding not possible\n");
if(HEX == ByteMode) size = size * 2;
else if (OCTAL == ByteMode) size = size * 3;
else if (BINARY == ByteMode) size = size * 8;
char* s = calloc(size + 1, sizeof(char));
require(NULL != s, "Exhausted available memory\n");
int i = 0;
while(i < size)
{
s[i] = '0';
i = i + 1;
}
return s;
}
void preserve_other(struct blob* p)
{
struct blob* i;
char c;
for(i = p; NULL != i; i = i->next)
{
if((NULL == i->Expression) && !(i->type & PROCESSED))
{
c = i->Text[0];
if(in_set(c, "!@$~%&:^"))
{
i->Expression = i->Text;
}
else if('<' == c)
{
i->Expression = pad_nulls(strtoint(i->Text + 1), i->Text);
}
}
}
}
void bound_values(int displacement, int number_of_bytes, int low, int high)
{
if((high < displacement) || (displacement < low))
{
fputs("A displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in ", stderr);
fputs(int2str(number_of_bytes, 10, TRUE), stderr);
fputs(" bytes\n", stderr);
exit(EXIT_FAILURE);
}
}
void range_check(int displacement, int number_of_bytes)
{
if(4 == number_of_bytes) return;
else if(3 == number_of_bytes)
{
bound_values(displacement, number_of_bytes, -8388608, 16777216);
return;
}
else if(2 == number_of_bytes)
{
bound_values(displacement, number_of_bytes, -32768, 65535);
return;
}
else if(1 == number_of_bytes)
{
bound_values(displacement, number_of_bytes, -128, 255);
return;
}
fputs("Received an invalid number of bytes in range_check\n", stderr);
exit(EXIT_FAILURE);
}
char* express_number(int value, char c)
{
char* ch = calloc(42, sizeof(char));
require(NULL != ch, "Exhausted available memory\n");
int size;
int number_of_bytes;
int shift;
if('!' == c)
{
number_of_bytes = 1;
value = value & 0xFF;
}
else if('@' == c)
{
number_of_bytes = 2;
value = value & 0xFFFF;
}
else if('~' == c)
{
number_of_bytes = 3;
value = value & 0xFFFFFF;
}
else if('%' == c)
{
number_of_bytes = 4;
value = value & 0xFFFFFFFF;
}
else
{
fputs("Given symbol ", stderr);
fputc(c, stderr);
fputs(" to express immediate value ", stderr);
fputs(int2str(value, 10, TRUE), stderr);
fputc('\n', stderr);
exit(EXIT_FAILURE);
}
range_check(value, number_of_bytes);
if(HEX == ByteMode)
{
size = number_of_bytes * 2;
shift = 4;
}
else if(OCTAL == ByteMode)
{
size = number_of_bytes * 3;
shift = 3;
}
else if(BINARY == ByteMode)
{
size = number_of_bytes * 8;
shift = 1;
}
else
{
fputs("Got invalid ByteMode in express_number\n", stderr);
exit(EXIT_FAILURE);
}
stringify(ch, size, ByteMode, value, shift);
if(!BigEndian) LittleEndian(ch, ByteMode);
return ch;
}
char* express_word(int value, char c)
{
char* s = calloc(43, sizeof(char));
s[0] = '.';
char* ch = s + 1;
require(NULL != ch, "Exhausted available memory\n");
int size;
int shift;
int immediate;
if('!' == c)
{
/* Corresponds to RISC-V I format */
immediate = (value & 0xFFF) << 20;
}
else if('@' == c)
{
/* Corresponds to RISC-V S format */
immediate = ((value & 0x1F) << 7) | ((value & 0xFE0) << (31 - 11));
}
else if('~' == c)
{
/* Corresponds with RISC-V U format */
if ((value & 0xFFF) < 0x800)
{
immediate = value & 0xFFFFF000;
}
else
{
immediate = (value & 0xFFFFF000) + 0x1000;
}
}
else if('%' == c)
{
/* provides an option for 32bit immediate constants */
immediate = value & 0xFFFFFFFF;
/* Drop the leading . */
ch = s;
}
else
{
fputs("Given symbol ", stderr);
fputc(c, stderr);
fputs(" to express immediate value ", stderr);
fputs(int2str(value, 10, TRUE), stderr);
fputc('\n', stderr);
exit(EXIT_FAILURE);
}
if(HEX == ByteMode)
{
size = 4 * 2;
shift = 4;
}
else if(OCTAL == ByteMode)
{
size = 4 * 3;
shift = 3;
}
else if(BINARY == ByteMode)
{
size = 4 * 8;
shift = 1;
}
else
{
fputs("Got invalid ByteMode in express_number\n", stderr);
exit(EXIT_FAILURE);
}
stringify(ch, size, ByteMode, immediate, shift);
if(!BigEndian) LittleEndian(ch, ByteMode);
return s;
}
void eval_immediates(struct blob* p)
{
struct blob* i;
int value;
for(i = p; NULL != i; i = i->next)
{
if(PROCESSED == i->type) continue;
else if(NEWLINE == i->type) continue;
else if('<' == i->Text[0]) continue;
else if(NULL == i->Expression)
{
if((X86 == Architecture) || (AMD64 == Architecture) || (ARMV7L == Architecture) || (AARM64 == Architecture) || (PPC64LE == Architecture))
{
if(in_set(i->Text[0], "%~@!"))
{
value = strtoint(i->Text + 1);
if(('0' == i->Text[1]) || (0 != value))
{
i->Expression = express_number(value, i->Text[0]);
}
}
}
else if((RISCV32 == Architecture) || (RISCV64 == Architecture))
{
if(in_set(i->Text[0], "%~@!"))
{
value = strtoint(i->Text + 1);
if(('0' == i->Text[1]) || (0 != value))
{
i->Expression = express_word(value, i->Text[0]);
}
}
}
else if(KNIGHT == Architecture)
{
value = strtoint(i->Text);
if(('0' == i->Text[0]) || (0 != value))
{
i->Expression = express_number(value, '@');
}
}
else
{
fputs("Unknown architecture received in eval_immediates\n", stderr);
exit(EXIT_FAILURE);
}
}
}
}
void print_hex(struct Token* p)
{
struct Token* i;
for(i = p; NULL != i; i = i->next)
{
if(NEWLINE == i->contents->type)
{
if(NULL == i->next) fputc('\n', destination_file);
else if(NEWLINE != i->next->contents->type) fputc('\n', destination_file);
}
else if(NULL != i->contents->Expression)
{
fputs(i->contents->Expression, destination_file);
if(NEWLINE != i->next->contents->type) fputc(' ', destination_file);
}
else
{
line_error(i->filename, i->linenumber);
fputs("Received invalid other; ", stderr);
fputs(i->contents->Text, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
}
/* Standard C main program */
int main(int argc, char **argv)
{
BigEndian = TRUE;
Architecture = KNIGHT;
destination_file = stdout;
ByteMode = HEX;
char* filename;
char* arch;
blob_count = 2;
hash_table = calloc(65537, sizeof(struct blob*));
/* Create newline blob */
newline_blob = calloc(1, sizeof(struct blob));
newline_blob->Text = "\n";
newline_blob->Expression = "\n";
newline_blob->type = NEWLINE;
AddHash(newline_blob, "\n");
/* Start the blob list with DEFINE and newline */
blob_list = calloc(1, sizeof(struct blob));
blob_list->Text = "DEFINE";
define_blob = blob_list;
blob_list->next = newline_blob;
AddHash(define_blob, "DEFINE");
/* Initialize scratch */
SCRATCH = calloc(max_string + 1, sizeof(char));
int option_index = 1;
while(option_index <= argc)
{
if(NULL == argv[option_index])
{
option_index = option_index + 1;
}
else if(match(argv[option_index], "--BigEndian"))
{
fputs("--BigEndian is now depreciated and replaced by --big-endian\nAnd will stop working in a future release\n", stderr);
BigEndian = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--big-endian"))
{
BigEndian = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--LittleEndian"))
{
fputs("--LittleEndian is now depreciated and replaced by --little-endian\nAnd will stop working in a future release\n", stderr);
BigEndian = FALSE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--little-endian"))
{
BigEndian = FALSE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-A") || match(argv[option_index], "--architecture"))
{
arch = argv[option_index + 1];
if(match("knight-native", arch) || match("knight-posix", arch)) Architecture = KNIGHT;
else if(match("x86", arch)) Architecture = X86;
else if(match("amd64", arch)) Architecture = AMD64;
else if(match("armv7l", arch)) Architecture = ARMV7L;
else if(match("aarch64", arch)) Architecture = AARM64;
else if(match("ppc64le", arch)) Architecture = PPC64LE;
else if(match("riscv32", arch)) Architecture = RISCV32;
else if(match("riscv64", arch)) Architecture = RISCV64;
else
{
fputs("Unknown architecture: ", stderr);
fputs(arch, stderr);
fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, aarch64, ppc64le, riscv32 and riscv64", stderr);
exit(EXIT_FAILURE);
}
option_index = option_index + 2;
}
else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
{
ByteMode = BINARY;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
{
fputs("Usage: ", stderr);
fputs(argv[0], stderr);
fputs(" --file FILENAME1 {-f FILENAME2} (--big-endian|--little-endian) ", stderr);
fputs("[--architecture name]\nArchitectures: knight-native, knight-posix, x86, amd64, armv7, riscv32 and riscv64\n", stderr);
fputs("To leverage octal or binary output: --octal, --binary\n", stderr);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
{
filename = argv[option_index + 1];
source_file = fopen(filename, "r");
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(argv[option_index + 1], stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
token_list = Tokenize_Line(token_list, filename);
fclose(source_file);
option_index = option_index + 2;
}
else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
{
destination_file = fopen(argv[option_index + 1], "w");
if(NULL == destination_file)
{
fputs("The file: ", stderr);
fputs(argv[option_index + 1], stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
option_index = option_index + 2;
}
else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
{
ByteMode = OCTAL;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
{
fputs("M1 1.1.0\n", stdout);
exit(EXIT_SUCCESS);
}
else
{
fputs("Unknown option\n", stderr);
exit(EXIT_FAILURE);
}
}
if(NULL == token_list)
{
fputs("Either no input files were given or they were empty\n", stderr);
exit(EXIT_FAILURE);
}
token_list = reverse_list(token_list);
line_macro(token_list);
process_string(blob_list);
eval_immediates(blob_list);
preserve_other(blob_list);
print_hex(token_list);
fclose(destination_file);
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/M2libc/ 0000775 0000000 0000000 00000000000 14126326331 0016356 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/README.md 0000664 0000000 0000000 00000003630 14126326331 0016527 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
The master repository for this work is located at:
https://savannah.nongnu.org/projects/mescc-tools
# If you wish to contribute:
pull requests can be made at https://github.com/oriansj/mescc-tools
and https://gitlab.com/janneke/mescc-tools
or patches/diffs can be sent via email to Jeremiah (at) pdp10 [dot] guru
or join us on libera.chat's #bootstrappable
These are a collection of tools written for use in bootstrapping
# blood-elf
A tool for generating ELF debug tables in M1-macro format from M1-macro assembly files
# exec_enable
A tool for marking files as executable, for systems that don't have chmod
# get_machine
A tool for identifying what hardware architecture you are running on
# kaem
A minimal shell script build tool that can be used for running shell scripts on
systems that lack any shells.
# hex2_linker
The trivially bootstrappable linker that is designed to be introspectable by
humans and should you so desire assemble hex programs that you write.
# M1-macro
The universal Macro assembler that can target any reasonable hardware architecture.
With these tools on your system, you can always bootstrap real programs; even in
the most catastrophic of situations, provided you keep your cool.
mescc-tools-Release_1.3/blood-elf.c 0000664 0000000 0000000 00000033266 14126326331 0017267 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include "M2libc/bootstrappable.h"
// CONSTANT max_string 4096
#define max_string 4096
int BITSIZE;
int BigEndian;
// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2
/* Strings needed for constants */
char* zero_8;
char* zero_16;
char* zero_32;
char* one_16;
char* one_32;
char* two_8;
char* two_32;
char* three_32;
char* six_32;
char* sixteen_32;
char* twentyfour_32;
/* Imported from stringify.c */
int stringify(char* s, int digits, int divisor, int value, int shift);
void LittleEndian(char* start, int ByteMode);
struct entry
{
struct entry* next;
char* name;
};
FILE* output;
struct entry* jump_table;
int count;
char* entry;
void consume_token(FILE* source_file, char* s)
{
int i = 0;
int c = fgetc(source_file);
require(EOF != c, "Can not have an EOF token\n");
do
{
s[i] = c;
i = i + 1;
require(max_string > i, "Token exceeds token length restriction\n");
c = fgetc(source_file);
if(EOF == c) break;
} while(!in_set(c, " \t\n>"));
}
void storeLabel(FILE* source_file)
{
struct entry* entry = calloc(1, sizeof(struct entry));
/* Prepend to list */
entry->next = jump_table;
jump_table = entry;
/* Store string */
entry->name = calloc((max_string + 1), sizeof(char));
consume_token(source_file, entry->name);
count = count + 1;
}
void line_Comment(FILE* source_file)
{
int c = fgetc(source_file);
while(!in_set(c, "\n\r"))
{
if(EOF == c) break;
c = fgetc(source_file);
}
}
void purge_string(FILE* source_file)
{
int c = fgetc(source_file);
while((EOF != c) && ('"' != c))
{
c = fgetc(source_file);
}
}
void first_pass(struct entry* input)
{
if(NULL == input) return;
first_pass(input->next);
FILE* source_file = fopen(input->name, "r");
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(input->name, stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
int c;
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
{
/* Check for and deal with label */
if(58 == c)
{
storeLabel(source_file);
}
/* Check for and deal with line comments */
else if (c == '#' || c == ';')
{
line_Comment(source_file);
}
else if ('"' == c)
{
purge_string(source_file);
}
}
fclose(source_file);
}
void output_string_table(struct entry* node)
{
fputs("\n# Generated string table\n:ELF_str\n", output);
fputs(zero_8, output);
fputs("\t# NULL string\n", output);
struct entry* i;
for(i = node; NULL != i; i = i->next)
{
fputs(":ELF_str_", output);
fputs(i->name, output);
fputs("\t\"", output);
fputs(i->name, output);
fputs("\"\n", output);
}
fputs("# END Generated string table\n\n", output);
}
void output_symbol_table(struct entry* node)
{
fputs("\n# Generated symbol table\n:ELF_sym\n# Required NULL symbol entry\n", output);
if(64 == BITSIZE)
{
fputs(zero_32, output);
fputs("\t# st_name\n", output);
fputs(zero_8, output);
fputs("\t# st_info\n", output);
fputs(zero_8, output);
fputs("\t# st_other\n", output);
fputs(one_16, output);
fputs("\t# st_shndx\n", output);
fputs(zero_32, output);
fputc(' ', output);
fputs(zero_32, output);
fputs("\t# st_value\n", output);
fputs(zero_32, output);
fputc(' ', output);
fputs(zero_32, output);
fputs("\t# st_size\n\n", output);
}
else
{
fputs(zero_32, output);
fputs("\t# st_name\n", output);
fputs(zero_32, output);
fputs("\t# st_value\n", output);
fputs(zero_32, output);
fputs("\t# st_size\n", output);
fputs(zero_8, output);
fputs("\t# st_info\n", output);
fputs(zero_8, output);
fputs("\t# st_other\n", output);
fputs(one_16, output);
fputs("\t# st_shndx\n\n", output);
}
struct entry* i;
for(i = node; NULL != i; i = i->next)
{
fputs("%ELF_str_", output);
fputs(i->name, output);
fputs(">ELF_str\t# st_name\n", output);
if(64 == BITSIZE)
{
fputs(two_8, output);
fputs("\t# st_info (FUNC)\n", output);
if(('_' == i->name[0]) && !match(entry, i->name))
{
fputs(two_8, output);
fputs("\t# st_other (hidden)\n", output);
}
else
{
fputs(zero_8, output);
fputs("\t# st_other (other)\n", output);
}
fputs(one_16, output);
fputs("\t# st_shndx\n", output);
fputs("&", output);
fputs(i->name, output);
fputc(' ', output);
fputs(zero_32, output);
fputs("\t# st_value\n", output);
fputs(zero_32, output);
fputc(' ', output);
fputs(zero_32, output);
fputs("\t# st_size (unknown size)\n\n", output);
}
else
{
fputs("&", output);
fputs(i->name, output);
fputs("\t#st_value\n", output);
fputs(zero_32, output);
fputs("\t# st_size (unknown size)\n", output);
fputs(two_8, output);
fputs("\t# st_info (FUNC)\n", output);
if(('_' == i->name[0]) && !match(entry, i->name))
{
fputs(two_8, output);
fputs("\t# st_other (hidden)\n", output);
}
else
{
fputs(zero_8, output);
fputs("\t# st_other (default)\n", output);
}
fputs(one_16, output);
fputs("\t# st_shndx\n\n", output);
}
}
fputs("# END Generated symbol table\n", output);
}
struct entry* reverse_list(struct entry* head)
{
struct entry* root = NULL;
struct entry* next;
while(NULL != head)
{
next = head->next;
head->next = root;
root = head;
head = next;
}
return root;
}
void write_int(char* field, char* label)
{
fputs(field, output);
fputs("\t#", output);
fputs(label, output);
fputc('\n', output);
}
void write_register(char* field, char* label)
{
/* $field section in the section headers are different size for 32 and 64bits */
/* The below is broken for BigEndian */
fputs(field, output);
if(64 == BITSIZE)
{
fputc(' ', output);
fputs(zero_32, output);
}
fputs("\t#", output);
fputs(label, output);
fputc('\n', output);
}
void write_section(char* label, char* name, char* type, char* flags, char* address, char* offset, char* size, char* link, char* info, char* entry)
{
/* Write label */
fputc('\n', output);
fputs(label, output);
fputc('\n', output);
write_int(name, "sh_name");
write_int(type, "sh_type");
write_register(flags, "sh_flags");
write_register(address, "sh_addr");
write_register(offset, "sh_offset");
write_register(size, "sh_size");
write_int(link, "sh_link");
/* Deal with the ugly case of stubs */
fputs(info, output);
fputs("\t#sh_info\n", output);
/* Alignment section in the section headers are different size for 32 and 64bits */
/* The below is broken for BigEndian */
if(64 == BITSIZE)
{
fputs(one_32, output);
fputc(' ', output);
fputs(zero_32, output);
fputs("\t#sh_addralign\n", output);
}
else
{
fputs(one_32, output);
fputs("\t#sh_addralign\n", output);
}
write_register(entry, "sh_entsize");
}
char* get_string(int value, int size, int ByteMode, int shift)
{
char* ch = calloc(42, sizeof(char));
require(NULL != ch, "Exhausted available memory\n");
ch[0] = '\'';
stringify(ch+1, size, ByteMode, value, shift);
if(!BigEndian) LittleEndian(ch+1, ByteMode);
int i = 0;
while(0 != ch[i])
{
i = i + 1;
}
ch[i] = '\'';
return ch;
}
char* setup_string(int value, int number_of_bytes, int ByteMode)
{
int shift;
int size;
if(HEX == ByteMode)
{
size = 2;
shift = 4;
}
else if(OCTAL == ByteMode)
{
size = 3;
shift = 3;
}
else if(BINARY == ByteMode)
{
size = 8;
shift = 1;
}
else
{
fputs("reached impossible mode\n", stderr);
exit(EXIT_FAILURE);
}
return get_string(value, number_of_bytes *size, ByteMode, shift);
}
void setup_strings(int ByteMode)
{
zero_8 = setup_string(0, 1, ByteMode);
zero_16 = setup_string(0, 2, ByteMode);
zero_32 = setup_string(0, 4, ByteMode);
one_16 = setup_string(1, 2, ByteMode);
one_32 = setup_string(1, 4, ByteMode);
two_8 = setup_string(2, 1, ByteMode);
two_32 = setup_string(2, 4, ByteMode);
three_32 = setup_string(3, 4, ByteMode);
six_32 = setup_string(6, 4, ByteMode);
sixteen_32 = setup_string(16, 4, ByteMode);
twentyfour_32 = setup_string(24, 4, ByteMode);
}
/* Standard C main program */
int main(int argc, char **argv)
{
jump_table = NULL;
struct entry* input = NULL;
output = stdout;
char* output_file = "";
entry = "";
BITSIZE = 32;
count = 1;
BigEndian = TRUE;
int ByteMode = HEX;
int set = FALSE;
struct entry* temp;
struct entry* head;
int option_index = 1;
while(option_index <= argc)
{
if(NULL == argv[option_index])
{
option_index = option_index + 1;
}
else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
{
fputs("Usage: ", stderr);
fputs(argv[0], stderr);
fputs(" --file FILENAME1 {--file FILENAME2} --output FILENAME\n", stderr);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "--64"))
{
BITSIZE = 64;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
{
temp = calloc(1, sizeof(struct entry));
temp->name = argv[option_index + 1];
temp->next = input;
input = temp;
option_index = option_index + 2;
}
else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
{
output_file = argv[option_index + 1];
output = fopen(output_file, "w");
if(NULL == output)
{
fputs("The file: ", stderr);
fputs(input->name, stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
option_index = option_index + 2;
}
else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
{
ByteMode = BINARY;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
{
ByteMode = OCTAL;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-X") || match(argv[option_index], "--hex"))
{
ByteMode = HEX;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--big-endian"))
{
BigEndian = TRUE;
set = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--little-endian"))
{
BigEndian = FALSE;
set = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
{
fputs("blood-elf 2.0.0\n(Basically Launches Odd Object Dump ExecutabLe Files\n", stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "--entry"))
{
head = calloc(1, sizeof(struct entry));
/* Include _start or any other entry from your .hex2 */
head->next = jump_table;
jump_table = head;
jump_table->name = argv[option_index + 1];
/* However only the last one will be exempt from the _name hidden rule */
entry = argv[option_index + 1];
option_index = option_index + 2;
count = count + 1;
}
else
{
fputs("Unknown option\n", stderr);
exit(EXIT_FAILURE);
}
}
/* Make sure we have a program tape to run */
if (NULL == input)
{
return EXIT_FAILURE;
}
/* Force setting of endianness */
if(!set)
{
fputs("either --little-endian or --big-endian MUST be set\n", stderr);
return EXIT_FAILURE;
}
/* Setup the ugly formating because RISC-V sucks */
setup_strings(ByteMode);
/* Get all of the labels */
first_pass(input);
/* Reverse their order */
jump_table = reverse_list(jump_table);
/* Create sections */
/* Create string names for sections */
fputs("# Generated sections\n:ELF_shstr\n", output);
fputs(zero_8, output);
fputs("\t# NULL\n", output);
fputs(":ELF_shstr__text\n\".text\"\n", output);
fputs(":ELF_shstr__shstr\n\".shstrtab\"\n", output);
fputs(":ELF_shstr__sym\n\".symtab\"\n", output);
fputs(":ELF_shstr__str\n\".strtab\"\n", output);
/* Create NULL section header as is required by the Spec. So dumb and waste of bytes*/
write_section(":ELF_section_headers", zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32, zero_32);
write_section(":ELF_section_header_text", "%ELF_shstr__text>ELF_shstr", one_32, six_32, "&ELF_text", "%ELF_text>ELF_base", "%ELF_data>ELF_text", zero_32, zero_32, zero_32);
write_section(":ELF_section_header_shstr", "%ELF_shstr__shstr>ELF_shstr", three_32, zero_32, "&ELF_shstr", "%ELF_shstr>ELF_base", "%ELF_section_headers>ELF_shstr", zero_32, zero_32, zero_32);
write_section(":ELF_section_header_str", "%ELF_shstr__str>ELF_shstr", three_32, zero_32, "&ELF_str", "%ELF_str>ELF_base", "%ELF_sym>ELF_str", zero_32, zero_32, zero_32);
if(64 == BITSIZE) write_section(":ELF_section_header_sym", "%ELF_shstr__sym>ELF_shstr", two_32, zero_32, "&ELF_sym", "%ELF_sym>ELF_base", "%ELF_end>ELF_sym", three_32, setup_string(count, 4, ByteMode), twentyfour_32);
else write_section(":ELF_section_header_sym", "%ELF_shstr__sym>ELF_shstr", two_32, zero_32, "&ELF_sym", "%ELF_sym>ELF_base", "%ELF_end>ELF_sym", three_32, setup_string(count, 4, ByteMode), sixteen_32);
/* Create dwarf stubs needed for objdump -d to get function names */
output_string_table(jump_table);
output_symbol_table(jump_table);
fputs("\n:ELF_end\n", output);
/* Close output file */
fclose(output);
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/catm.c 0000664 0000000 0000000 00000003211 14126326331 0016333 0 ustar 00root root 0000000 0000000 /* Copyright (C) 2019 Jeremiah Orians
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include
// CONSTANT BUFFER_SIZE 4096
#define BUFFER_SIZE 4096
int main(int argc, char** argv)
{
if(2 > argc)
{
fputs("catm requires 2 or more arguments\n", stderr);
exit(EXIT_FAILURE);
}
int output = open(argv[1], 577 , 384);
if(-1 == output)
{
fputs("The file: ", stderr);
fputs(argv[1], stderr);
fputs(" is not a valid output file name\n", stderr);
exit(EXIT_FAILURE);
}
int i;
int bytes;
char* buffer = calloc(BUFFER_SIZE + 1, sizeof(char));
int input;
for(i = 2; i < argc ; i = i + 1)
{
input = open(argv[i], 0, 0);
if(-1 == input)
{
fputs("The file: ", stderr);
fputs(argv[i], stderr);
fputs(" is not a valid input file name\n", stderr);
exit(EXIT_FAILURE);
}
keep:
bytes = read(input, buffer, BUFFER_SIZE);
write(output, buffer, bytes);
if(BUFFER_SIZE == bytes) goto keep;
}
free(buffer);
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/check.sh 0000775 0000000 0000000 00000002551 14126326331 0016665 0 ustar 00root root 0000000 0000000 #! /usr/bin/env bash
# Copyright © 2017 Jan Nieuwenhuizen
# Copyright © 2017 Jeremiah Orians
# Copyright (C) 2019 ng0
#
# This file is part of mescc-tools
#
# mescc-tools is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
set -eux
[ -e bin ] || mkdir -p bin
[ -f bin/M1 ] || exit 1
[ -f bin/hex2 ] || exit 2
[ -f bin/blood-elf ] || exit 3
#[ -f bin/kaem ] || exit 4
[ -f bin/get_machine ] || exit 5
[ -f bin/exec_enable ] || exit 6
[ -e test/results ] || mkdir -p test/results
./test/test0/hello.sh
./test/test1/hello.sh
./test/test2/hello.sh
./test/test3/hello.sh
./test/test4/hello.sh
./test/test5/hello.sh
./test/test6/hello.sh
./test/test7/hello.sh
./test/test8/hello.sh
./test/test9/hello.sh
./test/test10/hello.sh
./test/test11/hello.sh
. sha256.sh
sha256_check test/test.answers
mescc-tools-Release_1.3/docs/ 0000775 0000000 0000000 00000000000 14126326331 0016176 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/docs/M1.1 0000664 0000000 0000000 00000004211 14126326331 0016533 0 ustar 00root root 0000000 0000000 .\"Made with Love
.TH M1 1 "JULY 2019" Linux "User Manuals"
.SH NAME
M1 \- The universal Macro assembler
.SH SYNOPSIS
.na
M1 --architecture ARCHITECTURE --file FILE [--output FILE --octal --binary --big-endian --little-endian]
.SH DESCRIPTION
M1 is the most minimal cross-platform macro assembler possible
.br
Leveraging a few grammar details to provide the user with a
rich vocabulary of ways of expressing their desired output
and input; thus eliminating surprise from the generation
process.
.br
At it's core is DEFINE MACRO EXPANDED
.br
Where one can define an assembly instruction like:
DEFINE INT_80 CD80
and know that everywhere INT_80 is placed in the input
file there will be the hex encoding of that instruction
in the output file or if no output file is specified the
output will be send to standard out.
.br
The supported ARCHITECTURES are as follows: knight-native,
knight-posix, x86, amd64, armv7l and aarch64.
If you fail to specify an architecture, the default of knight-native
will be used.
.br
M1 also supports the generation of 8, 16 and 32bit integers
provided they are encoded as !NUM, @NUM or %NUM respectively.
eg !-1, @42 and %8675309
You however can not mix integers with definitions as macros
are always applied first and will not be evaluated further.
Should you wish to specify the bit and byte encoding of the
integers to match your target --big-endian and --little-endian
Should you wish for the output to be something other than hex
format, you can specify the exact output you desire with:
--octal or --binary
.SH EXAMPLES
Typically, M1 will be called in scripts used in bootstrapping
.br
# M1 -f x86.defs -f libc-core.M1 -f cc.M1 -f cc-footer.M1 --little-endian --architecture x86 -o cc.hex2
.br
.SH COMPATIBILITY
M1 is compatible with all Turing complete machines;
even the ones that try to be Turing complete -1
.SH AUTHORS
Jeremiah Orians
.br
Jan (janneke) Nieuwenhuizen
.SH COPYRIGHT
Copyright 2016-2019 Jeremiah Orians
.br
Copyright 2017 Jan Nieuwenhuizen
.br
License GPLv3+.
.SH "SEE ALSO"
hex2(1), blood-elf(1), kaem(1), syscalls(2)
mescc-tools-Release_1.3/docs/blood-elf.1 0000664 0000000 0000000 00000002546 14126326331 0020132 0 ustar 00root root 0000000 0000000 .\"Made with Love
.TH blood-elf 1 "JULY 2019" Linux "User Manuals"
.SH NAME
blood-elf - Get mescc with dwarfs
.SH SYNOPSIS
.na
blood-elf --file FILE [--output FILE --64]
.SH DESCRIPTION
blood-elf exists to generate ELF debug tables in M1-macro
format from M1-macro assembly files.
.br
At its core is read until you find :LABEL and then add it
to the list of things to output. It will ignore labels that
have '_' prefixing their name. eg :_foo will not get an entry.
If no output is specified, the result will be sent to Standard
Out.
.br
Fortunately the only architecture difference that you need
to concern yourself with is if your binary is going to be
64bits or 32bits (which is the default) and to pass the flag:
--64 should you need that alternate format
.SH EXAMPLES
Typically, blood-elf will be called in scripts used in bootstrapping
.br
# blood-elf -f cc.M1 -o cc-footer.M1
.br
# blood-elf --file cc.M1 --64 --output cc-footer.M1
.br
.SH COMPATIBILITY
blood-elf is compatible with all Turing complete machines;
even the ones that try to be Turing complete -1.
.SH AUTHORS
Jeremiah Orians
.br
Jan (janneke) Nieuwenhuizen
.SH COPYRIGHT
Copyright 2016-2019 Jeremiah Orians
.br
Copyright 2017 Jan Nieuwenhuizen
.br
License GPLv3+.
.SH "SEE ALSO"
M1(1), hex2(1), kaem(1), syscalls(2)
mescc-tools-Release_1.3/docs/get_machine.1 0000664 0000000 0000000 00000003371 14126326331 0020527 0 ustar 00root root 0000000 0000000 .\"Made with Love
.TH get_machine 1 "JULY 2019" Linux "User Manuals"
.SH NAME
get_machine - identify running hardware architecture
.SH SYNOPSIS
.na
get_machine [ --exact --override OVERRIDE --os ]
.SH DESCRIPTION
get_machine exists to make simple shell scripts that need
to know that hardware architecture it is assuming or what
host operating system is being used.
.br
At its core is figure out the general hardware architecture
and return it as quickly as possible. Although it is sometimes
useful to return something different; which is why --override
exists and thus what ever is supplied by with it is returned.
Scripts that wish to expose that can leverage the environment
variable GET_MACHINE_FLAGS to allow efficient overriding in
their scripts. Or if they wish to only override what Operating
system is running the environment variable GET_MACHINE_OS_FLAGS
should be used.
.br
If one wishes for something more exact than x86 or amd64, the
option --exact will return more specific values like i686-pae.
.br
Should one desire to know the host operating system: --os
.br
A word of warning; --override always will take top precedence
and can return anything you desire.
.SH EXAMPLES
Typically, get_machine will be in scripts used in bootstrapping
.br
# get_machine
.br
# get_machine --override "I am the very model of a modern major general"
.br
# get_machine ${GET_MACHINE_FLAGS}
.br
# get_machine ${GET_MACHINE_OS_FLAGS} --os
.br
.SH COMPATIBILITY
get_machine is compatible with all Turing complete machines;
even the ones that try to be Turing complete -1
.SH AUTHORS
Jeremiah Orians
.SH COPYRIGHT
Copyright 2016-2021 Jeremiah Orians
.br
License GPLv3+.
.SH "SEE ALSO"
M1(1), hex2(1), blood-elf(1), kaem(1), syscalls(2)
mescc-tools-Release_1.3/docs/hex2.1 0000664 0000000 0000000 00000004730 14126326331 0017132 0 ustar 00root root 0000000 0000000 .\"Made with Love
.TH hex2 1 "JULY 2019" Linux "User Manuals"
.SH NAME
hex2 - The trivially bootstrappable linker that is designed to be introspectable by humans
.SH SYNOPSIS
.na
hex2 --architecture ARCHITECTURE --base-address ADDRESS --file FILE [--output FILE [--non-executable]]
.SH DESCRIPTION
hex2 is designed to allow humans to write elf and other binary
files by hand in a format that allows comments and ease of understanding.
.br
At its core is read 2 hex characters add them together
and output a single byte. You can override this and use
binary or octal input if you so desire, using the --octal
or --binary option.
.br
If no output file is specified the output will be send to standard out.
By default the file will be executable unless the option:
--non-executable is also passed.
.br
The supported ARCHITECTURES are as follows: knight-native,
knight-posix, x86, amd64, armv7l and aarch64.
If you fail to specify an architecture, the default of knight-native
will be used.
.br
The base address for which the binary is to be loaded into memory
and thus the relative and absolute pointers should be based,
is passed via --base-address if it is not provided the default
value of ZERO will be assumed.
.br
hex2 also support labels in the :LABEL format and relative
and absolute pointers to those labels in 8, 16, 24 or 32bit sizes.
!LABEL, @LABEL, ~LABEL and %LABEL for 8, 16, 24 and 32bit relative addresses
respectively and $LABEL and &LABEL for 16 and 32bit absolute
addresses respectively.
Should you wish to specify the bit and byte encoding of the
addresses to match your target --big-endian and --little-endian
On architectures that require word alignment the < and ^
characters have a special meaning; particulary pad to word
and use word base address calculation rather than standard
byte based address calculation; generally seen in the form:
^~LABEL EB for calls in ARM
.SH EXAMPLES
Typically, hex2 will be called in scripts used in bootstrapping
.br
# hex2 -f ELF-armv7l.hex2 -f cc.hex2 --little-endian --architecture armv7l --base-address 0x10000 -o cc
.br
.SH COMPATIBILITY
hex2 is compatible with all Turing complete machines;
even the ones that try to be Turing complete -1
.SH AUTHORS
Jeremiah Orians
.br
Jan (janneke) Nieuwenhuizen
.SH COPYRIGHT
Copyright 2016-2019 Jeremiah Orians
.br
Copyright 2017 Jan Nieuwenhuizen
.br
License GPLv3+.
.SH "SEE ALSO"
M1(1), blood-elf(1), kaem(1), syscalls(2)
mescc-tools-Release_1.3/docs/kaem.1 0000664 0000000 0000000 00000003201 14126326331 0017171 0 ustar 00root root 0000000 0000000 .\"Made with Love
.TH kaem 1 "JULY 2019" Linux "User Manuals"
.SH NAME
kaem - Like running with scissors but shell scripts without a shell
.SH SYNOPSIS
.na
kaem [--file FILE --strict --verbose --nightmare-mode]
.SH DESCRIPTION
kaem exists to be the most minimal shell needed in the bootstrap
processes; that has the ability to function as an init
thus allowing the bootstrap to occur with only itself and a
hex0 assembler as the only binaries running on the system.
.br
At its core is read a line (except when the line is terminated
with a '\\', when it is read the next line too) and then collect
the arguments into an array, lookup the program in the path
provided by the name or if not found in the ENVIRONMENT and
then execute the program with the specified options.
.br
If no filename is passed, it then attempts to execute a file
called kaem.run; which is the standard name for kaem scripts.
If you wish for kaem to stop when one of the lines throws or
returns an error code, simply add --strict. If you wish to
see what is being executed, simply add --verbose. If you
hate dealing with an environment and want to eliminate it
entirely --nightmare-mode.
.SH EXAMPLES
Typically, kaem will be in running scripts used in bootstrapping
.br
# kaem --verbose --strict
.br
# kaem -f bootstrap.sh --nightmare-mode
.br
.SH COMPATIBILITY
kaem is compatible with all Turing complete machines;
even the ones that try to be Turing complete -1
.SH AUTHORS
Jeremiah Orians
.SH COPYRIGHT
Copyright 2016-2019 Jeremiah Orians
.br
License GPLv3+.
.SH "SEE ALSO"
M1(1), hex2(1), blood-elf(1), get_machine(1), syscalls(2)
mescc-tools-Release_1.3/elf_headers/ 0000775 0000000 0000000 00000000000 14126326331 0017507 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/elf_headers/elf32-ARM-debug.hex2 0000664 0000000 0000000 00000005713 14126326331 0022721 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### elf32.hex2: 32 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
01 # e_ident[EI_CLASS] Indicating 32 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
28 00 # e_machine Indicating 32bit ARM
01 00 00 00 # e_version Indicating original elf
&_start # e_entry Address of the entry point
%ELF_program_headers>ELF_base # e_phoff Address of program header table
%ELF_section_headers>ELF_base # e_shoff Address of section header table
00 02 00 05 # e_flags
34 00 # e_ehsize Indicating our 52 Byte header
20 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
28 00 # e_shentsize size of a section header table
05 00 # e_shnum number of entries in section table
02 00 # e_shstrndx index of the section names
# @40
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
00 00 00 00 # ph_offset
&ELF_base # ph_vaddr
&ELF_base # ph_physaddr
%ELF_end>ELF_base # ph_filesz
%ELF_end>ELF_base # ph_memsz
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 01 00 # alignment
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf32-ARM.hex2 0000664 0000000 0000000 00000005726 14126326331 0021641 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### elf32.hex2: 32 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
01 # e_ident[EI_CLASS] Indicating 32 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
28 00 # e_machine Indicating 32bit ARM
01 00 00 00 # e_version Indicating original elf
&_start # e_entry Address of the entry point
%ELF_program_headers>ELF_base # e_phoff Address of program header table
00 00 00 00 # e_shoff Address of section header table
00 02 00 05 # e_flags
34 00 # e_ehsize Indicating our 52 Byte header
20 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
00 00 # e_shentsize size of a section header table
00 00 # e_shnum number of entries in section table
00 00 # e_shstrndx index of the section names
## Program Header
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
00 00 00 00 # ph_offset
&ELF_base # ph_vaddr
&ELF_base # ph_physaddr
%ELF_end>ELF_base # ph_filesz
%ELF_end>ELF_base # ph_memsz
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 01 00 # alignment
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf32-debug.hex2 0000664 0000000 0000000 00000005677 14126326331 0022315 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### stage0's hex2 format for x86
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### local_ function-local
### string_ string #
### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
:ELF_base
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
01 # e_ident[EI_CLASS] Indicating 32 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
03 00 # e_machine Indicating AMD64
01 00 00 00 # e_version Indicating original elf
&_start # e_entry Address of the entry point
%ELF_program_headers>ELF_base # e_phoff Address of program header table
%ELF_section_headers>ELF_base # e_shoff Address of section header table
00 00 00 00 # e_flags
34 00 # e_ehsize Indicating our 52 Byte header
20 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
28 00 # e_shentsize size of a section header table
05 00 # e_shnum number of entries in section table
02 00 # e_shstrndx index of the section names
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
00 00 00 00 # ph_offset
&ELF_base # ph_vaddr
&ELF_base # ph_physaddr
%ELF_end>ELF_base # ph_filesz
%ELF_end>ELF_base # ph_memsz
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00 # ph_align
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf32.hex2 0000664 0000000 0000000 00000005717 14126326331 0021224 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### elf32.hex2: 32 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
01 # e_ident[EI_CLASS] Indicating 32 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
03 00 # e_machine Indicating x86
01 00 00 00 # e_version Indicating original elf
&_start # e_entry Address of the entry point
%ELF_program_headers>ELF_base # e_phoff Address of program header table
00 00 00 00 # e_shoff Address of section header table
00 00 00 00 # e_flags
34 00 # e_ehsize Indicating our 52 Byte header
20 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
00 00 # e_shentsize size of a section header table
00 00 # e_shnum number of entries in section table
00 00 # e_shstrndx index of the section names
## Program Header
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
00 00 00 00 # ph_offset
&ELF_base # ph_vaddr
&ELF_base # ph_physaddr
%ELF_end>ELF_base # ph_filesz
%ELF_end>ELF_base # ph_memsz
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00 # ph_align
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf64-ARM.hex2 0000664 0000000 0000000 00000006316 14126326331 0021642 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### elf64.hex2: 64 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
01111111 01000101 01001100 01000110 ## e_ident[EI_MAG0-3] ELF's magic number
00000010 ## e_ident[EI_CLASS] Indicating 64 bit
00000001 ## e_ident[EI_DATA] Indicating little endianness
00000001 ## e_ident[EI_VERSION] Indicating original elf
00000011 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00000000 ## e_ident[EI_ABIVERSION] See above
00000000 00000000 00000000 00000000 00000000 00000000 00000000 ## e_ident[EI_PAD]
00000010 00000000 ## e_type Indicating Executable
10110111 00000000 ## e_machine Indicating AARCH64
00000001 00000000 00000000 00000000 ## e_version Indicating original elf
&_start 00000000 00000000 00000000 00000000 ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
%ELF_program_headers>ELF_base 00000000 00000000 00000000 00000000 ## e_phoff Address of program header table
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ## e_shoff Address of section header table
00000000 00000000 00000000 00000000 ## e_flags
01000000 00000000 ## e_ehsize Indicating our 64 Byte header
00111000 00000000 ## e_phentsize size of a program header table
00000001 00000000 ## e_phnum number of entries in program table
00000000 00000000 ## e_shentsize size of a section header table
00000000 00000000 ## e_shnum number of entries in section table
00000000 00000000 ## e_shstrndx index of the section names
## Program Header
:ELF_program_headers
00000001 00000000 00000000 00000000 ## ph_type
00000111 00000000 00000000 00000000 ## ph_lags: PF-X|PF-W|PF-R = 7
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ## p_offset
&ELF_base 00000000 00000000 00000000 00000000 ## p_vaddr
&ELF_base 00000000 00000000 00000000 00000000 ## p_physaddr
%ELF_end>ELF_base 00000000 00000000 00000000 00000000 ## p_filesz
%ELF_end>ELF_base 00000000 00000000 00000000 00000000 ## p_memsz
00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 ## Required alignment
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf64-PPC64LE-debug.hex2 0000664 0000000 0000000 00000005217 14126326331 0023323 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### elf64.hex2: 64 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number
02 ## e_ident[EI_CLASS] Indicating 64 bit
01 ## e_ident[EI_DATA] Indicating little endianness
01 ## e_ident[EI_VERSION] Indicating original elf
03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 ## e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
15 00 ## e_machine Indicating PowerPC (64)
01 00 00 00 ## e_version Indicating original elf
&__e_entry 00 00 00 00 ## e_entry PowerPC64le does the wrong thing and loads the actual e_entry value from this Address
%ELF_program_headers>ELF_base 00 00 00 00 ## e_phoff Address of program header table
%ELF_section_headers>ELF_base 00 00 00 00 ## e_shoff Address of section header table
00 00 00 00 ## e_flags
40 00 ## e_ehsize Indicating our 64 Byte header
38 00 ## e_phentsize size of a program header table
01 00 ## e_phnum number of entries in program table
40 00 ## e_shentsize size of a section header table
05 00 ## e_shnum number of entries in section table
02 00 ## e_shstrndx index of the section names
## Program Header
:ELF_program_headers
01 00 00 00 ## p_type
05 00 00 00 ## ph_flags: PF-X|PF-R = 5
00 00 00 00 00 00 00 00 ## p_offset
&ELF_base 00 00 00 00 ## p_vaddr
&ELF_base 00 00 00 00 ## p_physaddr
%ELF_end>ELF_base 00 00 00 00 ## p_filesz
%ELF_end>ELF_base 00 00 00 00 ## p_memsz
00 10 00 00 00 00 00 00 ## Required alignment
# to deal with PowerPC64le not complying with the ELF spec
:__e_entry
&_start 00 00 00 00
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf64-PPC64LE.hex2 0000664 0000000 0000000 00000005175 14126326331 0022242 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### elf64.hex2: 64 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number
02 ## e_ident[EI_CLASS] Indicating 64 bit
01 ## e_ident[EI_DATA] Indicating little endianness
01 ## e_ident[EI_VERSION] Indicating original elf
03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 ## e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
15 00 ## e_machine Indicating PowerPC (64)
01 00 00 00 ## e_version Indicating original elf
&__e_entry 00 00 00 00 ## e_entry PowerPC64le does the wrong thing and loads the actual e_entry value from this Address
%ELF_program_headers>ELF_base 00 00 00 00 ## e_phoff Address of program header table
00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
00 00 00 00 ## e_flags
40 00 ## e_ehsize Indicating our 64 Byte header
38 00 ## e_phentsize size of a program header table
01 00 ## e_phnum number of entries in program table
00 00 ## e_shentsize size of a section header table
00 00 ## e_shnum number of entries in section table
00 00 ## e_shstrndx index of the section names
## Program Header
:ELF_program_headers
01 00 00 00 ## p_type
05 00 00 00 ## ph_flags: PF-X|PF-R = 5
00 00 00 00 00 00 00 00 ## p_offset
&ELF_base 00 00 00 00 ## p_vaddr
&ELF_base 00 00 00 00 ## p_physaddr
%ELF_end>ELF_base 00 00 00 00 ## p_filesz
%ELF_end>ELF_base 00 00 00 00 ## p_memsz
00 10 00 00 00 00 00 00 ## Required alignment
# to deal with PowerPC64le not complying with the ELF spec
:__e_entry
&_start 00 00 00 00
:ELF_text
mescc-tools-Release_1.3/elf_headers/elf64.hex2 0000664 0000000 0000000 00000005022 14126326331 0021216 0 ustar 00root root 0000000 0000000 ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of stage0.
###
### stage0 is free software: you can redistribute it and/or modify
### it under the terms of the GNU General Public License as published by
### the Free Software Foundation, either version 3 of the License, or
### (at your option) any later version.
###
### stage0 is distributed in the hope that it will be useful,
### but WITHOUT ANY WARRANTY; without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with stage0. If not, see .
### elf64.hex2: 64 bit elf header in hex2
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
## ELF Header
:ELF_base
7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number
02 ## e_ident[EI_CLASS] Indicating 64 bit
01 ## e_ident[EI_DATA] Indicating little endianness
01 ## e_ident[EI_VERSION] Indicating original elf
03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 ## e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
3E 00 ## e_machine Indicating AMD64
01 00 00 00 ## e_version Indicating original elf
&_start 00 00 00 00 ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
%ELF_program_headers>ELF_base 00 00 00 00 ## e_phoff Address of program header table
00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
00 00 00 00 ## e_flags
40 00 ## e_ehsize Indicating our 64 Byte header
38 00 ## e_phentsize size of a program header table
01 00 ## e_phnum number of entries in program table
00 00 ## e_shentsize size of a section header table
00 00 ## e_shnum number of entries in section table
00 00 ## e_shstrndx index of the section names
## Program Header
:ELF_program_headers
01 00 00 00 ## p_type
07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 ## p_offset
&ELF_base 00 00 00 00 ## p_vaddr
&ELF_base 00 00 00 00 ## p_physaddr
%ELF_end>ELF_base 00 00 00 00 ## p_filesz
%ELF_end>ELF_base 00 00 00 00 ## p_memsz
01 00 00 00 00 00 00 00 ## Required alignment
:ELF_text
mescc-tools-Release_1.3/get_machine.c 0000664 0000000 0000000 00000006330 14126326331 0017657 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
int match(char* a, char* b);
#define TRUE 1
//CONSTANT TRUE 1
#define FALSE 0
//CONSTANT FALSE 0
/* Standard C main program */
int main(int argc, char **argv)
{
int exact = FALSE;
int override = FALSE;
char* override_string;
int option_index = 1;
struct utsname* unameData = calloc(1, sizeof(struct utsname));
uname(unameData);
while(option_index <= argc)
{
if(NULL == argv[option_index])
{
option_index = option_index + 1;
}
else if(match(argv[option_index], "--exact"))
{
exact = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--override"))
{
override = TRUE;
override_string = argv[option_index + 1];
option_index = option_index + 2;
}
else if(match(argv[option_index], "--os") || match(argv[option_index], "--OS"))
{
if(override) fputs(override_string, stdout);
else fputs(unameData->sysname, stdout);
fputc('\n', stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "--blood"))
{
if(override) fputs(override_string, stdout);
else if(match("aarch64", unameData->machine)
|| match("amd64", unameData->machine)
|| match("ppc64le", unameData->machine)
|| match("riscv64", unameData->machine)
|| match("x86_64", unameData->machine)) fputs("--64", stdout);
fputc('\n', stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
{
fputs("get_machine 1.1.0\n", stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
{
fputs("If you want exact architecture use --exact\n", stderr);
fputs("If you want to know the Operating system use --OS\n", stderr);
fputs("If you wish to override the output to anything you want use --override\n", stderr);
exit(EXIT_SUCCESS);
}
else
{
fputs("Unknown option\n", stderr);
exit(EXIT_FAILURE);
}
}
if(override) fputs(override_string, stdout);
else if(!exact)
{
if(match("i386", unameData->machine) ||
match("i486", unameData->machine) ||
match("i586", unameData->machine) ||
match("i686", unameData->machine) ||
match("i686-pae", unameData->machine)) fputs("x86", stdout);
else if(match("x86_64", unameData->machine)) fputs("amd64", stdout);
else fputs(unameData->machine, stdout);
}
else fputs(unameData->machine, stdout);
fputs("\n", stdout);
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/guix.scm 0000664 0000000 0000000 00000006461 14126326331 0016735 0 ustar 00root root 0000000 0000000 ;;; guix.scm -- Guix package definition
;;; mescc-tools
;;; Copyright © 2017 Jan Nieuwenhuizen
;;; Copyright 2016 Jeremiah Orians
;;; Also borrowing code from:
;;; guile-sdl2 --- FFI bindings for SDL2
;;; Copyright © 2015 David Thompson
;;;
;;; guix.scm: This file is part of mescc-tools.
;;;
;;; mescc-tools is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; mescc-tools is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with mescc-tools. If not, see .
;;; Commentary:
;; GNU Guix development package. To build and install, run:
;; guix package -f guix.scm
;;
;; To build it, but not install it, run:
;; guix build -f guix.scm
;;
;; To use as the basis for a development environment, run:
;; guix environment -l guix.scm
;;
;;; Code:
(use-modules (srfi srfi-1)
(srfi srfi-26)
(ice-9 match)
(ice-9 popen)
(ice-9 rdelim)
(gnu packages)
(gnu packages gcc)
(gnu packages base)
((guix build utils) #:select (with-directory-excursion))
(guix build-system gnu)
(guix gexp)
(guix git-download)
(guix licenses)
(guix packages))
(define %source-dir (dirname (current-filename)))
(define git-file?
(let* ((pipe (with-directory-excursion %source-dir
(open-pipe* OPEN_READ "git" "ls-files")))
(files (let loop ((lines '()))
(match (read-line pipe)
((? eof-object?)
(reverse lines))
(line
(loop (cons line lines))))))
(status (close-pipe pipe)))
(lambda (file stat)
(match (stat:type stat)
('directory #t)
((or 'regular 'symlink)
(any (cut string-suffix? <> file) files))
(_ #f)))))
(define-public mescc-tools.git
(package
(name "mescc-tools.git")
(build-system gnu-build-system)
(inputs `(("which", which) ("coreutils", coreutils)))
(arguments
`(#:make-flags (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
#:test-target "test"
#:phases
(modify-phases %standard-phases
(delete 'configure))))
(synopsis "tools for the full source bootstrapping process")
(description
"Mescc-tools is a collection of tools for use in full source bootstrapping process.
Currently consists of the M0 macro assembler and the hex2 linker.")
(home-page "https://github.com/oriansj/mescc-tools")
(license gpl3+)
(version (string-append "HEAD-" (string-take (read-string (open-pipe "git show HEAD | head -1 | cut -d ' ' -f 2" OPEN_READ)) 7)))
(source (local-file %source-dir #:recursive? #t #:select? git-file?))))
;; Return it here so `guix build/environment/package' can consume it directly.
mescc-tools.git
mescc-tools-Release_1.3/hex2.c 0000664 0000000 0000000 00000016310 14126326331 0016261 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include "hex2_globals.h"
/* The essential functions */
void first_pass(struct input_files* input);
void second_pass(struct input_files* input);
void WordFirstPass(struct input_files* input);
void WordSecondPass(struct input_files* input);
/* Standard C main program */
int main(int argc, char **argv)
{
int InsaneArchitecture = FALSE;
ALIGNED = FALSE;
BigEndian = TRUE;
jump_tables = calloc(65537, sizeof(struct entry*));
Architecture = KNIGHT;
Base_Address = 0;
struct input_files* input = NULL;
output = stdout;
char* output_file = "";
exec_enable = TRUE;
ByteMode = HEX;
scratch = calloc(max_string + 1, sizeof(char));
char* arch;
struct input_files* temp;
int option_index = 1;
while(option_index <= argc)
{
if(NULL == argv[option_index])
{
option_index = option_index + 1;
}
else if(match(argv[option_index], "--BigEndian"))
{
fputs("--BigEndian is now depreciated and replaced by --big-endian\nAnd will stop working in a future release\n", stderr);
BigEndian = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--big-endian"))
{
BigEndian = TRUE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--LittleEndian"))
{
fputs("--LittleEndian is now depreciated and replaced by --little-endian\nAnd will stop working in a future release\n", stderr);
BigEndian = FALSE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--little-endian"))
{
BigEndian = FALSE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--exec_enable"))
{
fputs("--exec_enable is now depreciated as the output is assumed executable unless given the --non-executable flag.\nAnd --exec_enable will stop working in a future release\n", stderr);
/* Effectively a NOP */
option_index = option_index + 1;
}
else if(match(argv[option_index], "--non-executable"))
{
exec_enable = FALSE;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-A") || match(argv[option_index], "--architecture"))
{
arch = argv[option_index + 1];
if(match("knight-native", arch) || match("knight-posix", arch)) Architecture = KNIGHT;
else if(match("x86", arch)) Architecture = X86;
else if(match("amd64", arch)) Architecture = AMD64;
else if(match("armv7l", arch)) Architecture = ARMV7L;
else if(match("aarch64", arch)) Architecture = AARM64;
else if(match("ppc64le", arch)) Architecture = PPC64LE;
else if(match("riscv32", arch)) Architecture = RISCV32;
else if(match("riscv64", arch)) Architecture = RISCV64;
else
{
fputs("Unknown architecture: ", stderr);
fputs(arch, stderr);
fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, riscv32 and riscv64", stderr);
}
option_index = option_index + 2;
}
else if(match(argv[option_index], "-b") || match(argv[option_index], "--binary"))
{
ByteMode = BINARY;
option_index = option_index + 1;
}
else if(match(argv[option_index], "--BaseAddress"))
{
fputs("--BaseAddress is now depreciated and replaced by --base-address\nAnd will stop working in a future release\n", stderr);
Base_Address = strtoint(argv[option_index + 1]);
option_index = option_index + 2;
}
else if(match(argv[option_index], "-B") || match(argv[option_index], "--base-address"))
{
Base_Address = strtoint(argv[option_index + 1]);
option_index = option_index + 2;
}
else if(match(argv[option_index], "-h") || match(argv[option_index], "--help"))
{
fputs("Usage: ", stderr);
fputs(argv[0], stderr);
fputs(" --file FILENAME1 {-f FILENAME2} (--big-endian|--little-endian)", stderr);
fputs(" [--base-address 0x12345] [--architecture name]\nArchitecture:", stderr);
fputs(" knight-native, knight-posix, x86, amd64, armv7l, aarch64, riscv32 and riscv64\n", stderr);
fputs("To leverage octal or binary input: --octal, --binary\n", stderr);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "-f") || match(argv[option_index], "--file"))
{
temp = calloc(1, sizeof(struct input_files));
temp->filename = argv[option_index + 1];
temp->next = input;
input = temp;
option_index = option_index + 2;
}
else if(match(argv[option_index], "-o") || match(argv[option_index], "--output"))
{
output_file = argv[option_index + 1];
output = fopen(output_file, "w");
if(NULL == output)
{
fputs("The file: ", stderr);
fputs(argv[option_index + 1], stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
option_index = option_index + 2;
}
else if(match(argv[option_index], "-O") || match(argv[option_index], "--octal"))
{
ByteMode = OCTAL;
option_index = option_index + 1;
}
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
{
fputs("hex2 1.1.0\n", stdout);
exit(EXIT_SUCCESS);
}
else
{
fputs("Unknown option\n", stderr);
exit(EXIT_FAILURE);
}
}
if((Architecture == RISCV32) || (Architecture == RISCV64))
{
/* Forcing me to use words instead of just byting into the problem */
InsaneArchitecture = TRUE;
}
/* Catch a common mistake */
if((KNIGHT != Architecture) && (0 == Base_Address))
{
fputs(">> WARNING <<\n>> WARNING <<\n>> WARNING <<\n", stderr);
fputs("If you are not generating a ROM image this binary will likely not work\n", stderr);
}
/* Catch implicitly false assumptions */
if(BigEndian && ((X86 == Architecture) || ( AMD64 == Architecture) || (ARMV7L == Architecture) || (AARM64 == Architecture) || (RISCV32 == Architecture) || (RISCV64 == Architecture)))
{
fputs(">> WARNING <<\n>> WARNING <<\n>> WARNING <<\n", stderr);
fputs("You have specified big endian output on likely a little endian processor\n", stderr);
fputs("if this is a mistake please pass --little-endian next time\n", stderr);
}
/* Make sure we have a program tape to run */
if (NULL == input)
{
return EXIT_FAILURE;
}
/* Get all of the labels */
ip = Base_Address;
if(InsaneArchitecture) WordFirstPass(input);
else first_pass(input);
/* Fix all the references*/
ip = Base_Address;
if(InsaneArchitecture) WordSecondPass(input);
else second_pass(input);
/* flush all writes */
fflush(output);
/* Set file as executable */
if(exec_enable && (output != stdout))
{
/* Close output file */
fclose(output);
if(0 != chmod(output_file, 0750))
{
fputs("Unable to change permissions\n", stderr);
exit(EXIT_FAILURE);
}
}
return EXIT_SUCCESS;
}
mescc-tools-Release_1.3/hex2.h 0000664 0000000 0000000 00000002726 14126326331 0016274 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
#include
#include
#include
#include
#include "M2libc/bootstrappable.h"
#define max_string 4096
#define TRUE 1
#define FALSE 0
#define KNIGHT 0
#define X86 0x03
#define AMD64 0x3E
#define ARMV7L 0x28
#define AARM64 0xB7
#define PPC64LE 0x15
#define RISCV32 0xF3
#define RISCV64 0x100F3 /* Because RISC-V unlike all other architectures does get a seperate e_machine when changing from 32 to 64bit */
#define HEX 16
#define OCTAL 8
#define BINARY 2
struct input_files
{
struct input_files* next;
char* filename;
};
struct entry
{
struct entry* next;
unsigned target;
char* name;
};
mescc-tools-Release_1.3/hex2_globals.h 0000664 0000000 0000000 00000003206 14126326331 0017771 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include "hex2.h"
/* Global variables */
extern FILE* output;
extern char* filename;
extern char* scratch;
extern int ALIGNED;
extern int Architecture;
extern int Base_Address;
extern int BigEndian;
extern int ByteMode;
extern int exec_enable;
extern int hold;
extern int ip;
extern int linenumber;
extern int toggle;
extern struct entry** jump_tables;
/* Function prototypes */
int Architectural_displacement(int target, int base);
int Throwaway_token(FILE* source_file);
int consume_token(FILE* source_file);
int storeLabel(FILE* source_file, int ip);
unsigned GetTarget(char* c);
void Clear_Scratch(char* s);
void line_error();
void outputPointer(int displacement, int number_of_bytes);
void pad_to_align(int write);
int hex(int c, FILE* source_file);
int octal(int c, FILE* source_file);
int binary(int c, FILE* source_file);
mescc-tools-Release_1.3/hex2_linker.c 0000664 0000000 0000000 00000027564 14126326331 0017642 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include "hex2_globals.h"
/* Globals */
FILE* output;
struct entry** jump_tables;
int BigEndian;
int Base_Address;
int Architecture;
int ByteMode;
int exec_enable;
int ip;
char* scratch;
char* filename;
int linenumber;
int ALIGNED;
/* For processing bytes */
int hold;
int toggle;
void line_error()
{
fputs(filename, stderr);
fputs(":", stderr);
fputs(int2str(linenumber, 10, FALSE), stderr);
fputs(" :", stderr);
}
int consume_token(FILE* source_file)
{
int i = 0;
int c = fgetc(source_file);
while(!in_set(c, " \t\n>"))
{
scratch[i] = c;
i = i + 1;
c = fgetc(source_file);
require(max_string > i, "Consumed token exceeds length restriction\n");
if(EOF == c) break;
}
return c;
}
int Throwaway_token(FILE* source_file)
{
int c;
do
{
c = fgetc(source_file);
if(EOF == c) break;
} while(!in_set(c, " \t\n>"));
return c;
}
int length(char* s)
{
int i = 0;
while(0 != s[i]) i = i + 1;
return i;
}
void Clear_Scratch(char* s)
{
do
{
s[0] = 0;
s = s + 1;
} while(0 != s[0]);
}
void Copy_String(char* a, char* b)
{
while(0 != a[0])
{
b[0] = a[0];
a = a + 1;
b = b + 1;
}
}
int GetHash(char* s)
{
int i = 5381;
while(0 != s[0])
{
i = i * 31 + s[0];
s = s + 1;
}
return (i & 0xFFFF);
}
unsigned GetTarget(char* c)
{
struct entry* i;
for(i = jump_tables[GetHash(c)]; NULL != i; i = i->next)
{
if(match(c, i->name))
{
return i->target;
}
}
fputs("Target label ", stderr);
fputs(c, stderr);
fputs(" is not valid\n", stderr);
exit(EXIT_FAILURE);
}
int storeLabel(FILE* source_file, int ip)
{
struct entry* entry = calloc(1, sizeof(struct entry));
/* Ensure we have target address */
entry->target = ip;
/* Store string */
int c = consume_token(source_file);
entry->name = calloc(length(scratch) + 1, sizeof(char));
Copy_String(scratch, entry->name);
Clear_Scratch(scratch);
/* Prepend to list */
int h = GetHash(entry->name);
entry->next = jump_tables[h];
jump_tables[h] = entry;
return c;
}
void range_check(int displacement, int number_of_bytes)
{
if(4 == number_of_bytes) return;
else if (3 == number_of_bytes)
{
if((8388607 < displacement) || (displacement < -8388608))
{
fputs("A displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 3 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (2 == number_of_bytes)
{
if((32767 < displacement) || (displacement < -32768))
{
fputs("A displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 2 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (1 == number_of_bytes)
{
if((127 < displacement) || (displacement < -128))
{
fputs("A displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 1 byte\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
fputs("Invalid number of bytes given\n", stderr);
exit(EXIT_FAILURE);
}
void outputPointer(int displacement, int number_of_bytes)
{
unsigned value = displacement;
/* HALT HARD if we are going to do something BAD*/
range_check(displacement, number_of_bytes);
if(BigEndian)
{ /* Deal with BigEndian */
if(4 == number_of_bytes) fputc((value >> 24), output);
if(3 <= number_of_bytes) fputc(((value >> 16)%256), output);
if(2 <= number_of_bytes) fputc(((value >> 8)%256), output);
if(1 <= number_of_bytes) fputc((value % 256), output);
}
else
{ /* Deal with LittleEndian */
unsigned byte;
while(number_of_bytes > 0)
{
byte = value % 256;
value = value / 256;
fputc(byte, output);
number_of_bytes = number_of_bytes - 1;
}
}
}
int Architectural_displacement(int target, int base)
{
if(KNIGHT == Architecture) return (target - base);
else if(X86 == Architecture) return (target - base);
else if(AMD64 == Architecture) return (target - base);
else if(ALIGNED && (ARMV7L == Architecture))
{
ALIGNED = FALSE;
/* Note: Branch displacements on ARM are in number of instructions to skip, basically. */
if (target & 3)
{
line_error();
fputs("error: Unaligned branch target: ", stderr);
fputs(scratch, stderr);
fputs(", aborting\n", stderr);
exit(EXIT_FAILURE);
}
/*
* The "fetch" stage already moved forward by 8 from the
* beginning of the instruction because it is already
* prefetching the next instruction.
* Compensate for it by subtracting the space for
* two instructions (including the branch instruction).
* and the size of the aligned immediate.
*/
return (((target - base + (base & 3)) >> 2) - 2);
}
else if(ARMV7L == Architecture)
{
/*
* The size of the offset is 8 according to the spec but that value is
* based on the end of the immediate, which the documentation gets wrong
* and needs to be adjusted to the size of the immediate.
* Eg 1byte immediate => -8 + 1 = -7
*/
return ((target - base) - 8 + (3 & base));
}
else if(ALIGNED && (AARM64 == Architecture))
{
ALIGNED = FALSE;
return (target - (~3 & base)) >> 2;
}
else if (AARM64 == Architecture)
{
return ((target - base) - 8 + (3 & base));
}
else if(ALIGNED && (PPC64LE == Architecture))
{
ALIGNED = FALSE;
/* set Link register with branch */
return (target - (base & 0xFFFFFFFC )) | 1;
}
else if(PPC64LE == Architecture)
{
/* DO *NOT* set link register with branch */
return (target - (base & 0xFFFFFFFC));
}
else if(RISCV32 == Architecture || RISCV64 == Architecture) return (target - base);
fputs("Unknown Architecture, aborting before harm is done\n", stderr);
exit(EXIT_FAILURE);
}
void Update_Pointer(char ch)
{
/* Calculate pointer size*/
if(in_set(ch, "%&")) ip = ip + 4; /* Deal with % and & */
else if(in_set(ch, "@$")) ip = ip + 2; /* Deal with @ and $ */
else if('~' == ch) ip = ip + 3; /* Deal with ~ */
else if('!' == ch) ip = ip + 1; /* Deal with ! */
else
{
line_error();
fputs("storePointer given unknown\n", stderr);
exit(EXIT_FAILURE);
}
}
void storePointer(char ch, FILE* source_file)
{
/* Get string of pointer */
Clear_Scratch(scratch);
Update_Pointer(ch);
int base_sep_p = consume_token(source_file);
/* Lookup token */
int target = GetTarget(scratch);
int displacement;
int base = ip;
/* Change relative base address to : */
if ('>' == base_sep_p)
{
Clear_Scratch(scratch);
consume_token (source_file);
base = GetTarget (scratch);
/* Force universality of behavior */
displacement = (target - base);
}
else
{
displacement = Architectural_displacement(target, base);
}
/* output calculated difference */
if('!' == ch) outputPointer(displacement, 1); /* Deal with ! */
else if('$' == ch) outputPointer(target, 2); /* Deal with $ */
else if('@' == ch) outputPointer(displacement, 2); /* Deal with @ */
else if('~' == ch) outputPointer(displacement, 3); /* Deal with ~ */
else if('&' == ch) outputPointer(target, 4); /* Deal with & */
else if('%' == ch) outputPointer(displacement, 4); /* Deal with % */
else
{
line_error();
fputs("error: storePointer reached impossible case: ch=", stderr);
fputc(ch, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
void line_Comment(FILE* source_file)
{
int c = fgetc(source_file);
while(!in_set(c, "\n\r"))
{
if(EOF == c) break;
c = fgetc(source_file);
}
linenumber = linenumber + 1;
}
int hex(int c, FILE* source_file)
{
if (in_set(c, "0123456789")) return (c - 48);
else if (in_set(c, "abcdef")) return (c - 87);
else if (in_set(c, "ABCDEF")) return (c - 55);
else if (in_set(c, "#;")) line_Comment(source_file);
else if ('\n' == c) linenumber = linenumber + 1;
return -1;
}
int octal(int c, FILE* source_file)
{
if (in_set(c, "01234567")) return (c - 48);
else if (in_set(c, "#;")) line_Comment(source_file);
else if ('\n' == c) linenumber = linenumber + 1;
return -1;
}
int binary(int c, FILE* source_file)
{
if (in_set(c, "01")) return (c - 48);
else if (in_set(c, "#;")) line_Comment(source_file);
else if ('\n' == c) linenumber = linenumber + 1;
return -1;
}
void process_byte(char c, FILE* source_file, int write)
{
if(HEX == ByteMode)
{
if(0 <= hex(c, source_file))
{
if(toggle)
{
if(write) fputc(((hold * 16)) + hex(c, source_file), output);
ip = ip + 1;
hold = 0;
}
else
{
hold = hex(c, source_file);
}
toggle = !toggle;
}
}
else if(OCTAL ==ByteMode)
{
if(0 <= octal(c, source_file))
{
if(2 == toggle)
{
if(write) fputc(((hold * 8)) + octal(c, source_file), output);
ip = ip + 1;
hold = 0;
toggle = 0;
}
else if(1 == toggle)
{
hold = ((hold * 8) + octal(c, source_file));
toggle = 2;
}
else
{
hold = octal(c, source_file);
toggle = 1;
}
}
}
else if(BINARY == ByteMode)
{
if(0 <= binary(c, source_file))
{
if(7 == toggle)
{
if(write) fputc((hold * 2) + binary(c, source_file), output);
ip = ip + 1;
hold = 0;
toggle = 0;
}
else
{
hold = ((hold * 2) + binary(c, source_file));
toggle = toggle + 1;
}
}
}
}
void pad_to_align(int write)
{
if((ARMV7L == Architecture) || (AARM64 == Architecture) || (RISCV32 == Architecture) || (RISCV64 == Architecture))
{
if(1 == (ip & 0x1))
{
ip = ip + 1;
if(write) fputc('\0', output);
}
if(2 == (ip & 0x2))
{
ip = ip + 2;
if(write)
{
fputc('\0', output);
fputc('\0', output);
}
}
}
}
void first_pass(struct input_files* input)
{
if(NULL == input) return;
first_pass(input->next);
filename = input->filename;
linenumber = 1;
FILE* source_file = fopen(filename, "r");
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(input->filename, stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
toggle = FALSE;
int c;
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
{
/* Check for and deal with label */
if(':' == c)
{
c = storeLabel(source_file, ip);
}
/* check for and deal with relative/absolute pointers to labels */
if(in_set(c, "!@$~%&"))
{ /* deal with 1byte pointer !; 2byte pointers (@ and $); 3byte pointers ~; 4byte pointers (% and &) */
Update_Pointer(c);
c = Throwaway_token(source_file);
if ('>' == c)
{ /* deal with label>base */
c = Throwaway_token(source_file);
}
}
else if('<' == c)
{
pad_to_align(FALSE);
}
else if('^' == c)
{
/* Just ignore */
continue;
}
else process_byte(c, source_file, FALSE);
}
fclose(source_file);
}
void second_pass(struct input_files* input)
{
if(NULL == input) return;
second_pass(input->next);
filename = input->filename;
linenumber = 1;
FILE* source_file = fopen(filename, "r");
/* Something that should never happen */
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(input->filename, stderr);
fputs(" can not be opened!\nWTF-pass2\n", stderr);
exit(EXIT_FAILURE);
}
toggle = FALSE;
hold = 0;
int c;
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
{
if(':' == c) c = Throwaway_token(source_file); /* Deal with : */
else if(in_set(c, "!@$~%&")) storePointer(c, source_file); /* Deal with !, @, $, ~, % and & */
else if('<' == c) pad_to_align(TRUE);
else if('^' == c) ALIGNED = TRUE;
else process_byte(c, source_file, TRUE);
}
fclose(source_file);
}
mescc-tools-Release_1.3/hex2_word.c 0000664 0000000 0000000 00000021673 14126326331 0017324 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2017 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include "hex2_globals.h"
unsigned shiftregister;
unsigned tempword;
int updates;
void outOfRange(char* s, int value)
{
line_error();
fputs("error: value ", stderr);
fputs(int2str(value, 10, TRUE), stderr);
fputs(" out of range for field type ", stderr);
fputs(s, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
void UpdateShiftRegister(char ch, int value)
{
if ('.' == ch)
{
unsigned swap;
/* Assume the user knows what they are doing */
if(!BigEndian)
{
/* Swap from big-endian to little endian order */
swap = (((value >> 24) & 0xFF) |
((value << 8) & 0xFF0000) |
((value >> 8) & 0xFF00) |
((value & 0xFF) << 24));
}
else
{
/* Big endian needs no change */
swap = value;
}
/* we just take the 4 bytes after the . and shove in the shift register */
swap = swap & ((0xFFFF << 16) | 0xFFFF);
shiftregister = shiftregister ^ swap;
}
else if ('!' == ch)
{
/* Corresponds to RISC-V I format */
/* Will need architecture specific logic if more architectures go this route */
/* no range check because it needs to work with labels for lui/addi + AUIPC combos */
/* !label is used in the second instruction of AUIPC combo but we want an offset from */
/* the first instruction */
value = value + 4;
tempword = (value & 0xFFF) << 20;
/* Update shift register */
tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
shiftregister = shiftregister ^ tempword;
}
else if ('@' == ch)
{
/* Corresponds to RISC-V B format (formerly known as SB) */
/* Will need architecture specific logic if more architectures go this route */
if ((value < -0x1000 || value > 0xFFF) || (value & 1)) outOfRange("B", value);
/* Prepare the immediate's word */
tempword = ((value & 0x1E) << 7)
| ((value & 0x7E0) << (31 - 11))
| ((value & 0x800) >> 4)
| ((value & 0x1000) << (31 - 12));
tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
/* Update shift register */
shiftregister = shiftregister ^ tempword;
}
else if ('$' == ch)
{
/* Corresponds with RISC-V J format (formerly known as UJ) */
/* Will need architecture specific logic if more architectures go this route */
if ((value < -0x100000 || value > 0xFFFFF) || (value & 1)) outOfRange("J", value);
tempword = ((value & 0x7FE) << (30 - 10))
| ((value & 0x800) << (20 - 11))
| ((value & 0xFF000))
| ((value & 0x100000) << (31 - 20));
tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
shiftregister = shiftregister ^ tempword;
}
else if ('~' == ch)
{
/* Corresponds with RISC-V U format */
/* Will need architecture specific logic if more architectures go this route */
if ((value & 0xFFF) < 0x800) tempword = value & (0xFFFFF << 12);
else tempword = (value & (0xFFFFF << 12)) + 0x1000;
tempword = tempword & ((0xFFFF << 16) | 0xFFFF);
shiftregister = shiftregister ^ tempword;
}
else
{
line_error();
fputs("error: UpdateShiftRegister reached impossible case: ch=", stderr);
fputc(ch, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
void WordStorePointer(char ch, FILE* source_file)
{
/* Get string of pointer */
ip = ip + 4;
Clear_Scratch(scratch);
int base_sep_p = consume_token(source_file);
/* Lookup token */
int target = GetTarget(scratch);
int displacement;
int base = ip;
/* Change relative base address to : */
if ('>' == base_sep_p)
{
Clear_Scratch(scratch);
consume_token (source_file);
base = GetTarget (scratch);
/* Force universality of behavior */
displacement = (target - base);
}
else
{
displacement = Architectural_displacement(target, base);
}
/* output calculated difference */
if('&' == ch) outputPointer(target, 4); /* Deal with & */
else if('%' == ch) outputPointer(displacement, 4); /* Deal with % */
else
{
line_error();
fputs("error: WordStorePointer reached impossible case: ch=", stderr);
fputc(ch, stderr);
fputs("\n", stderr);
exit(EXIT_FAILURE);
}
}
unsigned sr_nextb()
{
unsigned rv = shiftregister & 0xff;
shiftregister = shiftregister >> 8;
return rv;
}
void DoByte(char c, FILE* source_file, int write, int update)
{
if(HEX == ByteMode)
{
if(0 <= hex(c, source_file))
{
if(toggle)
{
if(write) fputc(((hold * 16)) + hex(c, source_file) ^ sr_nextb(), output);
ip = ip + 1;
if(update)
{
hold = (hold * 16) + hex(c, source_file);
tempword = (tempword << 8) ^ hold;
updates = updates + 1;
}
hold = 0;
}
else
{
hold = hex(c, source_file);
}
toggle = !toggle;
}
}
else if(OCTAL ==ByteMode)
{
if(0 <= octal(c, source_file))
{
if(2 == toggle)
{
if(write) fputc(((hold * 8)) + octal(c, source_file) ^ sr_nextb(), output);
ip = ip + 1;
if(update)
{
hold = ((hold * 8) + octal(c, source_file));
tempword = (tempword << 8) ^ hold;
updates = updates + 1;
}
hold = 0;
toggle = 0;
}
else if(1 == toggle)
{
hold = ((hold * 8) + octal(c, source_file));
toggle = 2;
}
else
{
hold = octal(c, source_file);
toggle = 1;
}
}
}
else if(BINARY == ByteMode)
{
if(0 <= binary(c, source_file))
{
if(7 == toggle)
{
if(write) fputc((hold * 2) + binary(c, source_file) ^ sr_nextb(), output);
ip = ip + 1;
if(update)
{
hold = ((hold * 2) + binary(c, source_file));
tempword = (tempword << 8) ^ hold;
updates = updates + 1;
}
hold = 0;
toggle = 0;
}
else
{
hold = ((hold * 2) + binary(c, source_file));
toggle = toggle + 1;
}
}
}
}
void WordFirstPass(struct input_files* input)
{
if(NULL == input) return;
WordFirstPass(input->next);
filename = input->filename;
linenumber = 1;
FILE* source_file = fopen(filename, "r");
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(input->filename, stderr);
fputs(" can not be opened!\n", stderr);
exit(EXIT_FAILURE);
}
toggle = FALSE;
int c;
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
{
/* Check for and deal with label */
if(':' == c)
{
c = storeLabel(source_file, ip);
}
/* check for and deal with relative/absolute pointers to labels */
if('.' == c)
{
/* Read architecture specific number of bytes for what is defined as a word */
/* 4bytes in RISC-V's case */
updates = 0;
tempword = 0;
while (updates < 4)
{
c = fgetc(source_file);
DoByte(c, source_file, FALSE, TRUE);
}
ip = ip - 4;
}
else if(in_set(c, "!@$~"))
{
/* Don't update IP */
c = Throwaway_token(source_file);
}
else if(in_set(c, "%&"))
{
ip = ip + 4;
c = Throwaway_token(source_file);
if ('>' == c)
{ /* deal with label>base */
c = Throwaway_token(source_file);
}
}
else if('<' == c)
{
pad_to_align(FALSE);
}
else if('^' == c)
{
/* Just ignore */
continue;
}
else DoByte(c, source_file, FALSE, FALSE);
}
fclose(source_file);
}
void WordSecondPass(struct input_files* input)
{
shiftregister = 0;
tempword = 0;
if(NULL == input) return;
WordSecondPass(input->next);
filename = input->filename;
linenumber = 1;
FILE* source_file = fopen(filename, "r");
/* Something that should never happen */
if(NULL == source_file)
{
fputs("The file: ", stderr);
fputs(input->filename, stderr);
fputs(" can not be opened!\nWTF-pass2\n", stderr);
exit(EXIT_FAILURE);
}
toggle = FALSE;
hold = 0;
int c;
for(c = fgetc(source_file); EOF != c; c = fgetc(source_file))
{
if(':' == c) c = Throwaway_token(source_file); /* Deal with : */
else if('.' == c)
{
/* Read architecture specific number of bytes for what is defined as a word */
/* 4bytes in RISC-V's case */
updates = 0;
tempword = 0;
while (updates < 4)
{
c = fgetc(source_file);
DoByte(c, source_file, FALSE, TRUE);
}
UpdateShiftRegister('.', tempword);
ip = ip - 4;
}
else if(in_set(c, "%&")) WordStorePointer(c, source_file); /* Deal with % and & */
else if(in_set(c, "!@$~"))
{
Clear_Scratch(scratch);
consume_token(source_file);
UpdateShiftRegister(c, Architectural_displacement(GetTarget(scratch), ip)); /* Play with shift register */
}
else if('<' == c) pad_to_align(TRUE);
else if('^' == c) ALIGNED = TRUE;
else DoByte(c, source_file, TRUE, FALSE);
}
fclose(source_file);
}
mescc-tools-Release_1.3/makefile 0000664 0000000 0000000 00000010370 14126326331 0016747 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
# Prevent rebuilding
VPATH = bin:test/results
PACKAGE = mescc-tools
all: M1 hex2 get_machine blood-elf kaem catm
.NOTPARALLEL:
CC=gcc
CFLAGS:=$(CFLAGS) -D_GNU_SOURCE -std=c99 -ggdb -fno-common
M1: M1-macro.c stringify.c M2libc/bootstrappable.c | bin
$(CC) $(CFLAGS) M1-macro.c \
stringify.c \
M2libc/bootstrappable.c \
-o bin/M1
hex2: hex2.c hex2_linker.c hex2_word.c M2libc/bootstrappable.c | bin
$(CC) $(CFLAGS) hex2.c \
hex2_linker.c \
hex2_word.c \
M2libc/bootstrappable.c \
-o bin/hex2
get_machine: get_machine.c M2libc/bootstrappable.c | bin
$(CC) $(CFLAGS) get_machine.c \
M2libc/bootstrappable.c \
-o bin/get_machine
blood-elf: blood-elf.c stringify.c M2libc/bootstrappable.c | bin
$(CC) $(CFLAGS) blood-elf.c \
stringify.c \
M2libc/bootstrappable.c \
-o bin/blood-elf
kaem: Kaem/kaem.c Kaem/variable.c Kaem/kaem_globals.c M2libc/bootstrappable.c | bin
cd Kaem && make kaem
catm: catm.c | bin
$(CC) $(CFLAGS) catm.c -o bin/catm
# Clean up after ourselves
.PHONY: clean
clean:
rm -rf bin/ test/results/
./test/test1/cleanup.sh
./test/test2/cleanup.sh
./test/test3/cleanup.sh
./test/test4/cleanup.sh
./test/test5/cleanup.sh
./test/test6/cleanup.sh
./test/test7/cleanup.sh
./test/test8/cleanup.sh
./test/test9/cleanup.sh
./test/test10/cleanup.sh
./test/test11/cleanup.sh
cd Kaem && make clean
# A cleanup option we probably don't need
.PHONY: clean-hard
clean-hard: clean
git reset --hard
git clean -fd
# Directories
bin:
mkdir -p bin
results:
mkdir -p test/results
# tests
test: test0-binary \
test1-binary \
test2-binary \
test3-binary \
test4-binary \
test5-binary \
test6-binary \
test7-binary \
test8-binary \
test9-binary \
test10-binary \
test11-binary \
test12-binary \
test13-binary | results
./test.sh
test0-binary: results hex2 get_machine
test/test0/hello.sh
test1-binary: results hex2 M1 get_machine
test/test1/hello.sh
test2-binary: results hex2 M1 get_machine
test/test2/hello.sh
test3-binary: results hex2 M1 get_machine
test/test3/hello.sh
test4-binary: results hex2 M1 get_machine
test/test4/hello.sh
test5-binary: results hex2 M1 get_machine
test/test5/hello.sh
test6-binary: results hex2 M1 get_machine
test/test6/hello.sh
test7-binary: results hex2 M1 get_machine
test/test7/hello.sh
test8-binary: results hex2 M1 get_machine
test/test8/hello.sh
test9-binary: results hex2 M1 blood-elf get_machine
test/test9/hello.sh
test10-binary: results hex2 M1 get_machine
test/test10/hello.sh
test11-binary: results hex2 M1 blood-elf get_machine
test/test11/hello.sh
test12-binary: results hex2 M1 blood-elf get_machine
test/test12/hello.sh
test13-binary: results hex2 M1 blood-elf get_machine
test/test13/hello.sh
# Generate test answers
.PHONY: Generate-test-answers
Generate-test-answers:
sha256sum test/results/* >| test/test.answers
DESTDIR:=
PREFIX:=/usr/local
bindir:=$(DESTDIR)$(PREFIX)/bin
.PHONY: install
install: M1 hex2 blood-elf kaem get_machine
mkdir -p $(bindir)
cp $^ $(bindir)
### dist
.PHONY: dist
COMMIT=$(shell git describe --dirty)
TARBALL_VERSION=$(COMMIT:Release_%=%)
TARBALL_DIR:=$(PACKAGE)-$(TARBALL_VERSION)
TARBALL=$(TARBALL_DIR).tar.gz
# Be friendly to Debian; avoid using EPOCH
MTIME=$(shell git show HEAD --format=%ct --no-patch)
# Reproducible tarball
TAR_FLAGS=--sort=name --mtime=@$(MTIME) --owner=0 --group=0 --numeric-owner --mode=go=rX,u+rw,a-s
$(TARBALL):
(git ls-files \
--exclude=$(TARBALL_DIR); \
echo $^ | tr ' ' '\n') \
| tar $(TAR_FLAGS) \
--transform=s,^,$(TARBALL_DIR)/,S -T- -cf- \
| gzip -c --no-name > $@
dist: $(TARBALL)
mescc-tools-Release_1.3/mescc-tools.scm 0000664 0000000 0000000 00000004727 14126326331 0020214 0 ustar 00root root 0000000 0000000 ;;; mescc-tools.scm -- Guix package definition
;;; Copyright © 2017 Jan Nieuwenhuizen
;;; Copyright 2016 Jeremiah Orians
;;; guix.scm: This file is part of mescc-tools.
;;;
;;; mescc-tools is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; mescc-tools is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with mescc-tools. If not, see .
;;; Commentary:
;; GNU Guix development package. To build and install, run:
;; guix package -f guix.scm
;;
;; To build it, but not install it, run:
;; guix build -f guix.scm
;;
;; To use as the basis for a development environment, run:
;; guix environment -l guix.scm
;;
;;; Code:
(use-modules (ice-9 match)
(gnu packages)
(gnu packages gcc)
(gnu packages base)
(guix build-system gnu)
(guix download)
(guix licenses)
(guix packages))
(define-public mescc-tools
(package
(name "mescc-tools")
(version "1.0.1")
(inputs `(("which", which) ("coreutils", coreutils)))
(source (origin
(method url-fetch)
(uri (string-append "http://git.savannah.nongnu.org/cgit/mescc-tools.git/snapshot/mescc-tools-Release_" version ".tar.gz"))
(sha256
(base32 "1wqj70h4rrxl1d1aqpxhy47964r5dilvll6gvqv75y9qk6pwx5is"))))
(build-system gnu-build-system)
(arguments
`(#:make-flags (list (string-append "PREFIX=" (assoc-ref %outputs "out")))
#:test-target "test"
#:phases
(modify-phases %standard-phases
(delete 'configure))))
(synopsis "tools for the full source bootstrapping process")
(description
"Mescc-tools is a collection of tools for use in full source bootstrapping process.
Currently consists of the M0 macro assembler and the hex2 linker.")
(home-page "https://github.com/oriansj/mescc-tools")
(license gpl3+)))
;; Return it here so `guix build/environment/package' can consume it directly.
mescc-tools
mescc-tools-Release_1.3/sha256.sh 0000664 0000000 0000000 00000003230 14126326331 0016610 0 ustar 00root root 0000000 0000000 #! /usr/bin/env sh
# Copyright (C) 2019 ng0
# Copyright (C) 2019 Jeremiah Orians
#
# This file is part of mescc-tools
#
# mescc-tools is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# mescc-tools is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with mescc-tools. If not, see .
set -ex
# It's bad to rely on the uname here, but it's a start.
# What this does is to consider the major implementations of
# sha256sum tools and their differences and call them
# accordingly.
sha256_check()
{
# Address locale behaviors
export LC_ALL=C
export LANG=C
export LANGUAGE=C
# Sort out what tool they have that can do SHA256SUM calculations and then use it
if [ -e "$(which sha256sum)" ]; then
sha256sum -c "$1"
elif [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "FreeBSD" ]; then
awk '
BEGIN { status = 0 }
{
rc=system(">/dev/null sha256 -q -c "$1" "$2);
if (rc == 0) print($2": OK")
else {
print($2": NOT OK");
status=rc
}
}
END { exit status}
' "$1"
elif [ -e "$(which sum)" ]; then
sum -a SHA256 -n -c "$1"
elif [ -e "$(which sha256)" ]; then
sha256 -r -c "$1"
else
echo "Unsupported sha256 tool, please send a patch to support it"
exit 77
fi
}
mescc-tools-Release_1.3/stringify.c 0000664 0000000 0000000 00000005023 14126326331 0017430 0 ustar 00root root 0000000 0000000 /* -*- c-file-style: "linux";indent-tabs-mode:t -*- */
/* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2017 Jan Nieuwenhuizen
* This file is part of mescc-tools.
*
* mescc-tools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* mescc-tools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with mescc-tools. If not, see .
*/
#include
// CONSTANT HEX 16
#define HEX 16
// CONSTANT OCTAL 8
#define OCTAL 8
// CONSTANT BINARY 2
#define BINARY 2
/***********************************************************
* Needed for current implementation of little endian *
* Can be used to support little bit endian instruction *
* sets if we ever find one that might be useful *
* But I seriously doubt it *
***********************************************************/
void reverseBitOrder(char* c, int ByteMode)
{
if(NULL == c) return;
if(0 == c[1]) return;
int hold = c[0];
if(HEX == ByteMode)
{
c[0] = c[1];
c[1] = hold;
reverseBitOrder(c+2, ByteMode);
}
else if(OCTAL == ByteMode)
{
c[0] = c[2];
c[2] = hold;
reverseBitOrder(c+3, ByteMode);
}
else if(BINARY == ByteMode)
{
c[0] = c[7];
c[7] = hold;
hold = c[1];
c[1] = c[6];
c[6] = hold;
hold = c[2];
c[2] = c[5];
c[5] = hold;
hold = c[3];
c[3] = c[4];
c[4] = hold;
reverseBitOrder(c+8, ByteMode);
}
}
void LittleEndian(char* start, int ByteMode)
{
char* end = start;
char* c = start;
while(0 != end[0]) end = end + 1;
int hold;
for(end = end - 1; start < end; start = start + 1)
{
hold = start[0];
start[0] = end[0];
end[0] = hold;
end = end - 1;
}
/* The above makes a reversed bit order */
reverseBitOrder(c, ByteMode);
}
int hex2char(int c)
{
if((c >= 0) && (c <= 9)) return (c + 48);
else if((c >= 10) && (c <= 15)) return (c + 55);
else return -1;
}
int stringify(char* s, int digits, int divisor, int value, int shift)
{
int i = value;
if(digits > 1)
{
i = stringify(s+1, (digits - 1), divisor, value, shift);
}
s[0] = hex2char(i & (divisor - 1));
return (i >> shift);
}
mescc-tools-Release_1.3/test.sh 0000775 0000000 0000000 00000001524 14126326331 0016566 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
set -ex
. ./sha256.sh
echo "Beginning mescc-tools-tests"
sha256_check test/test.answers
cd Kaem && make test
echo "mescc-tools-tests done"
mescc-tools-Release_1.3/test/ 0000775 0000000 0000000 00000000000 14126326331 0016225 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test.answers 0000664 0000000 0000000 00000002414 14126326331 0020611 0 ustar 00root root 0000000 0000000 054359eb2b4e4f75aa212a41f90654b18b1efdde7ba08aac12bd9c21b1a12cf6 test/results/test0-binary
4f1bf2ce18cd6d182745501d1a3812037ab95e826780bebc37adc4f49f4eba52 test/results/test1-binary
2027e0c8d6295f041d338a430c5a3d3aae042294e5ba4ad1eb08bed16b147671 test/results/test10-binary
bd0fba222284869f35b1ddcc3469d579d862e844122bcacc9b5d673e8bfe2aaf test/results/test11-binary
611c702f74f931cff6f010023b0ff5da48dc262167e79e3de31eea2ea5ba20ce test/results/test12-binary
71bd38e9d077dd339046fe44f47b277981e768902491baeeb97199a86101a320 test/results/test13-binary
793e619fa6ec1adb99c7b65f92f0e713370d56cf503a10d967a9494ce7ef40a9 test/results/test2-binary
96ade767f30e3d9037a6c597cefb103942c8ec104264a3551017f091b10646e1 test/results/test3-binary
310bea3129335b2cbda70fd591b2cf079b6f7fc19b22f12061a5379ba96dbdae test/results/test4-binary
1b09d2b8a3848d691d5d5927f80b6acaad57174b7653d88fe07cd1f6f4bd6f3d test/results/test5-binary
61d70db94077ee71b5522f44344baf3943c02559fb1c3e311cfe2fb6cb652d55 test/results/test6-binary
5cba7bcb9de863c721613b5fafa17277e9e83336e32c8e7e59ee76d003ed5f29 test/results/test7-binary
a71dc25bcba2a7298b9b9024a7927e215c5081a9ff90a6afa9b583be6c0a7e06 test/results/test8-binary
7fb2aa7451ea132a98f3900b140c8eb3d50751aa6adeac23fd2d766fce2635d4 test/results/test9-binary
mescc-tools-Release_1.3/test/test0/ 0000775 0000000 0000000 00000000000 14126326331 0017264 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test0/hello.hex2 0000664 0000000 0000000 00000002372 14126326331 0021163 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## stage0's hex2 format for x86
## ! 1 byte relative
## $ 2 byte address
## @ 2 byte relative
## % 4 byte relative
## & 4 byte address
## label_ function-local
## string_ string
##
#.text
:main
55 89 e5 83 ec 40
# eputs("Hello, Mescc!\n");
68 &string_0
e8 %eputs 83 c4 04
85 c0
b8 2a 00 00 00
c9 c3
#.data
:g_environment
00 00 00 00
:g_stdin
00 00 00 00
:g_stdout
00 00 00 00
:string_0
48 65 6c 6c 6f 2c 20 4d 65 73 63 63 21 0a 00
:ELF_end
mescc-tools-Release_1.3/test/test0/hello.sh 0000775 0000000 0000000 00000002232 14126326331 0020725 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -x
./bin/hex2 -f elf_headers/elf32.hex2 -f test/test0/mini-libc-mes.hex2 -f test/test0/hello.hex2 --little-endian --architecture x86 --base-address 0x8048000 -o test/results/test0-binary
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "x86" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
out=$(./test/results/test0-binary 2>&1)
r=$?
[ $r = 42 ] || exit 1
[ "$out" = "Hello, Mescc!" ] || exit 2
fi
exit 0
mescc-tools-Release_1.3/test/test0/mini-libc-mes.hex2 0000664 0000000 0000000 00000003706 14126326331 0022507 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## stage0's hex2 format for x86
## ! 1 byte relative
## $ 2 byte address
## @ 2 byte relative
## % 4 byte relative
## & 4 byte address
## label_ function-local
## string_ string
##
#.text
:_start
55 89 e5 83 ec 40
e8 %main 83 c4 00
89 45 fc
# exit(r);
ff 75 fc
e8 %exit 83 c4 04
85 c0
c9 c3
:_env
55 89 e5 83 ec 40
8b 45 08
c9 c3
:exit
55 89 e5 83 ec 40
# asm(".byte 0x8b 0x5d 0x08");
8b 5d 08
# asm(".byte 0xb8 0x01 0x00 0x00 0x00");
b8 01 00 00 00
# asm(".byte 0xcd 0x80");
cd 80
c9 c3
:write
55 89 e5 83 ec 40
# asm(".byte 0x8b 0x5d 0x08");
8b 5d 08
# asm(".byte 0x8b 0x4d 0x0c");
8b 4d 0c
# asm(".byte 0x8b 0x55 0x10");
8b 55 10
# asm(".byte 0xb8 0x04 0x00 0x00 0x00");
b8 04 00 00 00
# asm(".byte 0xcd 0x80");
cd 80
c9 c3
:strlen
# while (s[i]) ...
55 89 e5 83 ec 40
c7 45 fc 00 00 00 00
e9 09 00 00 00
8b 45 fc
83 45 fc 01
85 c0
8b 45 fc
89 c2
8b 55 08
01 d0
0f b6 00
85 c0
85 c0
84 c0 74 05
e9 dd ff ff ff
8b 45 fc
c9 c3
:eputs
55 89 e5 83 ec 40
ff 75 08
e8 %strlen 83 c4 04
89 45 fc
# write(2, s, i);
ff 75 fc
ff 75 08
b8 02 00 00 00
50
e8 %write 83 c4 0c
85 c0
b8 00 00 00 00
c9 c3
#.data
:g_stdin
00 00 00 00
:g_environment
00 00 00 00
mescc-tools-Release_1.3/test/test1/ 0000775 0000000 0000000 00000000000 14126326331 0017265 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test1/.gitignore 0000664 0000000 0000000 00000001436 14126326331 0021261 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
example
example.hex2
hold
proof1
proof2
mescc-tools-Release_1.3/test/test1/cleanup.sh 0000775 0000000 0000000 00000001436 14126326331 0021257 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test1/hold test/test1/proof1 test/test1/proof2
exit 0
mescc-tools-Release_1.3/test/test1/hello.sh 0000775 0000000 0000000 00000003011 14126326331 0020722 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test1/hex.M1 --little-endian --architecture amd64 -o test/test1/hold
./bin/hex2 -f elf_headers/elf64.hex2 -f test/test1/hold --little-endian --architecture amd64 --base-address 0x00600000 -o test/results/test1-binary
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "amd64" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test1-binary < test/test1/hex0.hex0 > test/test1/proof1
r=$?
[ $r = 0 ] || exit 1
out=$(sha256_check test/test1/proof1.answer)
[ "$out" = "test/test1/proof1: OK" ] || exit 2
chmod u+x test/test1/proof1
./test/test1/proof1 < test/test1/hex1.hex0 > test/test1/proof2
r=$?
[ $r = 0 ] || exit 3
out=$(sha256_check test/test1/proof2.answer)
[ "$out" = "test/test1/proof2: OK" ] || exit 4
fi
exit 0
mescc-tools-Release_1.3/test/test1/hex.M1 0000664 0000000 0000000 00000010732 14126326331 0020253 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE ADD_RAX_R14 4C01F0
DEFINE CMP_RAX_Immediate8 4883F8
DEFINE CMP_R15_Immediate8 4983FF
DEFINE JE8 74
DEFINE JNE8 75
DEFINE JGE8 7D
DEFINE JE32 0F84
DEFINE JL8 7C
DEFINE JMP8 EB
DEFINE JMP32 E9
DEFINE LOAD32I_RDX 48C7C2
DEFINE LOAD32I_RSI 48C7C6
DEFINE LOAD32I_RDI 48C7C7
DEFINE LOAD32I_RAX 48C7C0
DEFINE LOAD32I_R14 49C7C6
DEFINE LOAD32I_R15 49C7C7
DEFINE LOAD8_al_Absolute32 8A0425
DEFINE STORE8_al_Absolute32 880425
DEFINE SYSCALL 0F05
DEFINE SHL_R14_Immediate8 49C1E6
DEFINE TEST_RAX_RAX 4885C0
DEFINE MOVE_R14_RAX 4989C6
DEFINE MOVZBQ_RAX_AL 480FB6C0
DEFINE RETQ C3
DEFINE SUB_RAX_Immediate8 4883E8
DEFINE CALLI32 E8
DEFINE NULL 00000000
# Where the ELF Header is going to hit is :_start
:hex
# Purge Comment Lines (#)
CMP_RAX_Immediate8 !35
JE8 !purge_comment
# Purge Comment Lines (;)
CMP_RAX_Immediate8 !59
JE8 !purge_comment
# deal all ascii less than '0'
CMP_RAX_Immediate8 !48
JL8 !ascii_other
# deal with 0-9
CMP_RAX_Immediate8 !58
JL8 !ascii_num
# deal with all ascii less than 'A'
CMP_RAX_Immediate8 !65
JL8 !ascii_other
# deal with 'A'-'F'
CMP_RAX_Immediate8 !71
JL8 !ascii_high
# deal with all ascii less than 'a'
CMP_RAX_Immediate8 !97
JL8 !ascii_other
#deal with 'a'-'f'
CMP_RAX_Immediate8 !103
JL8 !ascii_low
# The rest that remains needs to be ignored
JMP8 !ascii_other
:purge_comment
# Attempt to read 1 byte from STDIN
LOAD32I_RDX %1 # set the size of chars we want
LOAD32I_RSI &input # Where to put it
LOAD32I_RDI %0 # Where are we reading from
LOAD32I_RAX %0 # the syscall number for read
SYSCALL # call the Kernel
TEST_RAX_RAX # check what we got
JE32 %Done # Got EOF call it done
# load byte
LOAD8_al_Absolute32 &input # load char
MOVZBQ_RAX_AL # We have to zero extend it to use it
# Loop if not LF
CMP_RAX_Immediate8 !10
JNE8 !purge_comment
# Otherwise return -1
LOAD32I_RAX %-1
RETQ
:ascii_num
SUB_RAX_Immediate8 !48
RETQ
:ascii_low
SUB_RAX_Immediate8 !87
RETQ
:ascii_high
SUB_RAX_Immediate8 !55
RETQ
:ascii_other
LOAD32I_RAX %-1
RETQ
# Our main function
:_start
# Our flag for byte processing
LOAD32I_R15 %-1
# temp storage for the sum
LOAD32I_R14 %0
:loop
# Attempt to read 1 byte from STDIN
LOAD32I_RDX %1 # set the size of chars we want
LOAD32I_RSI &input # Where to put it
LOAD32I_RDI %0 # Where are we reading from
LOAD32I_RAX %0 # the syscall number for read
SYSCALL # call the Kernel
TEST_RAX_RAX # check what we got
JE8 !Done # Got EOF call it done
# load byte
LOAD8_al_Absolute32 &input # load char
MOVZBQ_RAX_AL # We have to zero extend it to use it
# process byte
CALLI32 %hex
# deal with -1 values
CMP_RAX_Immediate8 !0
JL8 !loop
# deal with toggle
CMP_R15_Immediate8 !0
JGE8 !print
# process first byte of pair
MOVE_R14_RAX
LOAD32I_R15 %0
JMP8 !loop
# process second byte of pair
:print
# update the sum and store in output
SHL_R14_Immediate8 !4
ADD_RAX_R14
STORE8_al_Absolute32 &output
# flip the toggle
LOAD32I_R15 %-1
# Print our Hex
LOAD32I_RDX %1 # set the size of chars we want
LOAD32I_RSI &output # What we are writing
LOAD32I_RDI %1 # Stdout File Descriptor
LOAD32I_RAX %1 # the syscall number for write
SYSCALL # call the Kernel
JMP8 !loop
:Done
# program completed Successfully
LOAD32I_RDI %0 # All is well
LOAD32I_RAX %60 # put the exit syscall number in rax
SYSCALL # Call it a good day
# Where we are putting our output
:output
# Reserve 4bytes of Zeros
NULL
# Where we get our input
:input
# Reserve 4bytes of Zeros
NULL
:ELF_end
mescc-tools-Release_1.3/test/test1/hex0.hex0 0000664 0000000 0000000 00000013420 14126326331 0020717 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## Self Bootstrapping Hex Assembler written in Hex
## And a shitload of comments
## That can be converted to assembly and compiled
## If you were linked to this file and have come to assume that the elf header
## is indicative of a dependency of on linux, unix or even operating systems you
## would be mistaken, this is not the bootstrap work that is hardware native,
## that work would be located here: http://git.savannah.nongnu.org/cgit/stage0.git
## This repository is for solely providing tools enabling one to arbitrary verify
## All of the steps and the binaries produced for arbitrary hardware platforms on
## Any arbitrary hardware platform they choose.
## This of course being an example of an arbitrary Linux bootstrap for those not
## Comfortable with native hardware bootstraps and need a simple example to follow
## ELF Header
7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number
02 ## e_ident[EI_CLASS] Indicating 64 bit
01 ## e_ident[EI_DATA] Indicating little endianness
01 ## e_ident[EI_VERSION] Indicating original elf
03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 ## e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
3E 00 ## e_machine Indicating AMD64
01 00 00 00 ## e_version Indicating original elf
FB 00 60 00 00 00 00 00 ## e_entry Address of the entry point
40 00 00 00 00 00 00 00 ## e_phoff Address of program header table
00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
00 00 00 00 ## e_flags
40 00 ## e_ehsize Indicating our 64 Byte header
38 00 ## e_phentsize size of a program header table
01 00 ## e_phnum number of entries in program table
00 00 ## e_shentsize size of a section header table
00 00 ## e_shnum number of entries in section table
00 00 ## e_shstrndx index of the section names
## Program Header table
01 00 00 00 ## p_type
07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 ## p_offset
00 00 60 00 00 00 00 00 ## p_vaddr
00 00 00 00 00 00 00 00 ## Undefined
9B 01 00 00 00 00 00 00 ## p_filesz
9B 01 00 00 00 00 00 00 ## p_memsz
00 00 20 00 00 00 00 00 ## Required alignment
## Hex
48 83 f8 23 # cmp $0x23,%rax
74 26 # je 6000a4
48 83 f8 30 # cmp $0x30,%rax
7c 6f # jl 6000f3
48 83 f8 3a # cmp $0x3a,%rax
7c 5a # jl 6000e4
48 83 f8 41 # cmp $0x41,%rax
7c 63 # jl 6000f3
48 83 f8 47 # cmp $0x47,%rax
7c 58 # jl 6000ee
48 83 f8 61 # cmp $0x61,%rax
7c 57 # jl 6000f3
48 83 f8 67 # cmp $0x67,%rax
7c 47 # jl 6000e9
eb 4f # jmp 6000f3
## Purge Comment
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 99 01 60 00 # mov $0x600199,%rsi
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 00 00 00 00 # mov $0x0,%rax
0f 05 # syscall
48 85 c0 # test %rax,%rax
0f 84 be 00 00 00 # je 600189
8a 04 25 99 01 60 00 # mov 0x600199,%al
48 0f b6 c0 # movzbq %al,%rax
48 83 f8 0a # cmp $0xa,%rax
75 c8 # jne 6000a4
48 c7 c0 ff ff ff ff # mov $0xffffffffffffffff,%rax
c3 # retq
## ascii num
48 83 e8 30 # sub $0x30,%rax
c3 # retq
## ascii low
48 83 e8 57 # sub $0x57,%rax
c3 # retq
## ascii high
48 83 e8 37 # sub $0x37,%rax
c3 # retq
## ascii other
48 c7 c0 ff ff ff ff # mov $0xffffffffffffffff,%rax
c3 # retq
## start
49 c7 c7 ff ff ff ff # mov $0xffffffffffffffff,%r15
49 c7 c6 00 00 00 00 # mov $0x0,%r14
## Loop
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 99 01 60 00 # mov $0x600199,%rsi
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 00 00 00 00 # mov $0x0,%rax
0f 05 # syscall
48 85 c0 # test %rax,%rax
74 5d # je 600189
8a 04 25 99 01 60 00 # mov 0x600199,%al
48 0f b6 c0 # movzbq %al,%rax
e8 3c ff ff ff # callq 600078
48 83 f8 00 # cmp $0x0,%rax
7c c7 # jl 600109
49 83 ff 00 # cmp $0x0,%r15
7d 0c # jge 600154
49 89 c6 # mov %rax,%r14
49 c7 c7 00 00 00 00 # mov $0x0,%r15
eb b5 # jmp 600109
## print
49 c1 e6 04 # shl $0x4,%r14
4c 01 f0 # add %r14,%rax
88 04 25 9a 01 60 00 # mov %al,0x60019a
49 c7 c7 ff ff ff ff # mov $0xffffffffffffffff,%r15
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 9a 01 60 00 # mov $0x60019a,%rsi
48 c7 c7 01 00 00 00 # mov $0x1,%rdi
48 c7 c0 01 00 00 00 # mov $0x1,%rax
0f 05 # syscall
eb 80 # jmp 600109
## Done
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 3c 00 00 00 # mov $0x3c,%rax
0f 05 # syscall
## Place for input, This actually isn't required but here it is
02 00 00
mescc-tools-Release_1.3/test/test1/hex1.hex0 0000664 0000000 0000000 00000027047 14126326331 0020732 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## ELF Header
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
02 # e_ident[EI_CLASS] Indicating 64 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
3E 00 # e_machine Indicating AMD64
01 00 00 00 # e_version Indicating original elf
78 00 60 00 00 00 00 00 # e_entry Address of the entry point (Number of bytes this header is + Base Address)
40 00 00 00 00 00 00 00 # e_phoff Address of program header table
00 00 00 00 00 00 00 00 # e_shoff Address of section header table
00 00 00 00 # e_flags
40 00 # e_ehsize Indicating our 64 Byte header
38 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
00 00 # e_shentsize size of a section header table
00 00 # e_shnum number of entries in section table
00 00 # e_shstrndx index of the section names
## Program Header table
01 00 00 00 # p_type
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # p_offset
00 00 60 00 00 00 00 00 # p_vaddr
00 00 00 00 00 00 00 00 # Undefined
00 00 00 0F 00 00 00 00 # p_filesz
00 00 00 0F 00 00 00 00 # p_memsz
00 00 20 00 00 00 00 00 # Required alignment
# :_start
58 # POP_RAX # Get the number of arguments
5F # POP_RDI # Get the program name$
5F # POP_RDI # Get the actual input name
48C7C6 00000000 # LOADI32_RSI %0 # prepare read_only
48C7C0 02000000 # LOADI32_RAX %2 # the syscall number for open()
0F05 # SYSCALL # Now open that damn file
4989C1 # COPY_RAX_to_R9 # Preserve the file pointer we were given
49C7C7 FFFFFFFF # LOADI32_R15 %-1 # Our flag for byte processing
49C7C6 00000000 # LOADI32_R14 %0 # temp storage for the sum
49C7C5 00000000 # LOADI32_R13 %0 # Our starting IP
E8 39000000 # CALLI32 %First_pass # Process it
# rewind input file
4C89CF # COPY_R9_to_RDI # Using our input file
48C7C6 00000000 # LOADI32_RSI %0 # Offset Zero
48C7C2 00000000 # LOADI32_RDX %0 # Whence Zero
48C7C0 08000000 # LOADI32_RAX %8 # lseek
0F05 # SYSCALL
49C7C7 FFFFFFFF # LOADI32_R15 %-1 # Our flag for byte processing
49C7C6 00000000 # LOADI32_R14 %0 # temp storage for the sum
49C7C5 00000000 # LOADI32_R13 %0 # Our starting IP
E8 EF000000 # CALLI32 %Second_pass # Process it
E9 C7010000 # JMP32 %Done
# :First_pass
E8 D2010000 # CALLI32 %Read_byte
# Deal with EOF
483D FCFFFFFF # CMPI32_RAX %-4
0F84 67000000 # JE32 %First_pass_done
# Check for :
483D 3A000000 # CMPI32_RAX %0x3a
0F85 05000000 # JNE32 %First_pass_0
# Deal with label
E8 14020000 # CALLI32 %StoreLabel
# :First_pass_0
# Check for %
483D 25000000 # CMPI32_RAX %0x25
0F84 39000000 # JE32 %First_pass_pointer
# Deal with everything else
E8 46000000 # CALLI32 %hex # Process our char
# Deal with EOF
483D FCFFFFFF # CMPI32_RAX %-4
0F84 39000000 # JE32 %First_pass_done
# deal with -1 values
483D 00000000 # CMPI32_RAX %0
0F8C B5FFFFFF # JL32 %First_pass
# deal with toggle
4981FF 00000000 # CMPI32_R15 %0
0F84 07000000 # JE32 %First_pass_1
4981C5 01000000 # ADDI32_to_R13 %1 # Increment IP
# :First_pass_1
49F7D7 # NOT_R15
E9 99FFFFFF # JMP32 %First_pass
# :First_pass_pointer
# Deal with Pointer to label
E8 6B010000 # CALLI32 %Read_byte # Drop the char
4981C5 04000000 # ADDI32_to_R13 %4 # Increment IP
E9 88FFFFFF # JMP32 %First_pass # Loop again
# :First_pass_done
C3 # RET
# :hex
# deal with EOF
483D FCFFFFFF # CMPI32_RAX %-4
0F84 DC000000 # JE32 %EOF
# deal with line comments starting with #
483D 23000000 # CMPI32_RAX %0x23
0F84 E8000000 # JE32 %ascii_comment
# deal with line comments starting with ;
483D 3B000000 # CMPI32_RAX %0x3b
0F84 DC000000 # JE32 %ascii_comment
# deal all ascii less than 0
483D 30000000 # CMPI32_RAX %0x30
0F8C C8000000 # JL32 %ascii_other
# deal with 0-9
483D 3A000000 # CMPI32_RAX %0x3a
0F8C AD000000 # JL32 %ascii_num
# deal with all ascii less than A
483D 41000000 # CMPI32_RAX %0x41
0F8C B0000000 # JL32 %ascii_other
# deal with A-F
483D 47000000 # CMPI32_RAX %0x47
0F8C 9F000000 # JL32 %ascii_high
#deal with all ascii less than a
483D 61000000 # CMPI32_RAX %0x61
0F8C 98000000 # JL32 %ascii_other
#deal with a-f
483D 67000000 # CMPI32_RAX %0x67
0F8C 82000000 # JL32 %ascii_low
# The rest that remains needs to be ignored
E9 87000000 # JMP32 %ascii_other
# :Second_pass
E8 E8000000 # CALLI32 %Read_byte
# Deal with EOF
483D FCFFFFFF # CMPI32_RAX %-4
0F84 65000000 # JE32 %Second_pass_done
# Simply drop the label
483D 3A000000 # CMPI32_RAX %0x3a
0F85 0A000000 # JNE32 %Second_pass_0
E8 CB000000 # CALLI32 %Read_byte
E9 D9FFFFFF # JMP32 %Second_pass
# :Second_pass_0
# Deal with % pointer
483D 25000000 # CMPI32_RAX %0x25
0F85 0A000000 # JNE32 %Second_pass_1
E8 1D010000 # CALLI32 %StorePointer
E9 C3FFFFFF # JMP32 %Second_pass
# :Second_pass_1
# Deal with everything else
E8 4DFFFFFF # CALLI32 %hex # Process our char
# Deal with EOF
483D FCFFFFFF # CMPI32_RAX %-4
0F84 28000000 # JE32 %Second_pass_done
# deal with -1 values
483D 00000000 # CMPI32_RAX %0
0F8C A6FFFFFF # JL32 %Second_pass
# deal with toggle
4981FF 00000000 # CMPI32_R15 %0
0F84 4D000000 # JE32 %print
# process first byte of pair
4989C6 # COPY_RAX_to_R14
49C7C7 00000000 # LOADI32_R15 %0
E9 8AFFFFFF # JMP32 %Second_pass
# :Second_pass_done
C3 # RET
# :EOF
C3 # RET
# :ascii_num
4883E8 30 # SUBI8_from_RAX !0x30
C3 # RET
# :ascii_low
4883E8 57 # SUBI8_from_RAX !0x57
C3 # RET
# :ascii_high
4883E8 37 # SUBI8_from_RAX !0x37
C3 # RET
# :ascii_other
48C7C0 FFFFFFFF # LOADI32_RAX %-1
C3 # RET
# :ascii_comment
E8 59000000 # CALLI32 %Read_byte
483D 0D000000 # CMPI32_RAX %0xd
0F84 0C000000 # JE32 %ascii_comment_cr
483D 0A000000 # CMPI32_RAX %0xa
0F85 E3FFFFFF # JNE32 %ascii_comment
# :ascii_comment_cr
48C7C0 FFFFFFFF # LOADI32_RAX %-1
C3 # RET
# process second byte of pair
# :print
# update the sum and store in output
49C1E6 04 # SHL8_R14 !4
4C01F0 # ADD_R14_to_RAX
880425 46036000 # STORE8_al_Absolute32 &table
# flip the toggle
49F7D7 # NOT_R15
# Print our first Hex
48C7C2 01000000 # LOADI32_RDX %1 # set the size of chars we want
E8 53000000 # CALLI32 %print_chars
4981C5 01000000 # ADDI32_to_R13 %1 # Increment IP
E9 23FFFFFF # JMP32 %Second_pass
# :Done
# program completed Successfully
48C7C7 00000000 # LOADI32_RDI %0 # All is well
48C7C0 3C000000 # LOADI32_RAX %0x3c # put the exit syscall number in eax
0F05 # SYSCALL # Call it a good day
# :Read_byte
# Attempt to read 1 byte from STDIN
48C7C2 01000000 # LOADI32_RDX %1 # set the size of chars we want
48C7C6 46036000 # LOADI32_RSI &table # Where to put it
4C89CF # COPY_R9_to_RDI # Where are we reading from
48C7C0 00000000 # LOADI32_RAX %0 # the syscall number for read
0F05 # SYSCALL # call the Kernel
4885C0 # TEST_RAX_RAX # check what we got
0F84 0C000000 # JE32 %Read_byte_1 # Got EOF call it done
# load byte
8A0425 46036000 # LOAD8_al_Absolute32 &table # load char
480FB6C0 # MOVZBQ_RAX_AL # We have to zero extend it to use it
C3 # RET
# Deal with EOF
# :Read_byte_1
48C7C0 FCFFFFFF # LOADI32_RAX %-4 # Put EOF in rax
C3 # RET
# :print_chars
48C7C6 46036000 # LOADI32_RSI &table # What we are writing
48C7C7 01000000 # LOADI32_RDI %1 # Stdout File Descriptor
48C7C0 01000000 # LOADI32_RAX %1 # the syscall number for write
0F05 # SYSCALL # call the Kernel
C3 # RET
# :Get_table_target
E8 ACFFFFFF # CALLI32 %Read_byte # Get single char label
48C1E0 02 # SHL8_RAX !2 # Each label in table takes 4 bytes to store
4805 46036000 # ADDI32_to_RAX &table # Calculate offset
C3 # RET
# :StoreLabel
E8 EBFFFFFF # CALLI32 %Get_table_target
4C8928 # STORE32_R13_to_Address_in_RAX # Write out pointer to table
C3 # RET
# :StorePointer
4981C5 04000000 # ADDI32_to_R13 %4 # Increment IP
E8 DBFFFFFF # CALLI32 %Get_table_target # Get address of pointer
678B00 # LOAD32_Address_in_RAX_into_RAX # Get pointer
4C29E8 # SUB_R13_from_RAX # target - ip
890425 46036000 # STORE32_RAX_Absolute32 &table # put value in output
48C7C2 04000000 # LOADI32_RDX %4 # set the size of chars we want
E8 AAFFFFFF # CALLI32 %print_chars
C3 # RET
# :table
mescc-tools-Release_1.3/test/test1/proof1.answer 0000664 0000000 0000000 00000000124 14126326331 0021711 0 ustar 00root root 0000000 0000000 a9a48fdbff46b4d7e1596bae4bd44c23f554a285b404dc151b63a073b2efce62 test/test1/proof1
mescc-tools-Release_1.3/test/test1/proof2.answer 0000664 0000000 0000000 00000000124 14126326331 0021712 0 ustar 00root root 0000000 0000000 bcf188a5ea5afb1a56a716f21715d554b95f1babc679b2a9596aeeee6a7c09e3 test/test1/proof2
mescc-tools-Release_1.3/test/test10/ 0000775 0000000 0000000 00000000000 14126326331 0017345 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test10/.gitignore 0000664 0000000 0000000 00000001404 14126326331 0021334 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
exit_42.hex2
mescc-tools-Release_1.3/test/test10/cleanup.sh 0000775 0000000 0000000 00000001403 14126326331 0021331 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test10/exit_42.hex2
exit 0
mescc-tools-Release_1.3/test/test10/exit_42.M1 0000664 0000000 0000000 00000001521 14126326331 0021021 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE SYSCALL 000000EF
DEFINE LOADI_ALWAYS A0E3
DEFINE R0 0
DEFINE R7 7
:_start
!42 R0 '0' LOADI_ALWAYS
!1 R7 '0' LOADI_ALWAYS
SYSCALL
:ELF_end
mescc-tools-Release_1.3/test/test10/hello.sh 0000775 0000000 0000000 00000002312 14126326331 0021005 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -x
./bin/M1 --little-endian --architecture armv7l -f test/test10/exit_42.M1 -o test/test10/exit_42.hex2 || exit 1
./bin/hex2 --little-endian --architecture armv7l --base-address 0x10000 -f elf_headers/elf32-ARM.hex2 -f test/test10/exit_42.hex2 -o test/results/test10-binary || exit 2
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "armv7l" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test10-binary
r=$?
[ $r = 42 ] || exit 3
fi
exit 0
mescc-tools-Release_1.3/test/test11/ 0000775 0000000 0000000 00000000000 14126326331 0017346 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test11/.gitignore 0000664 0000000 0000000 00000001411 14126326331 0021333 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
*.hex2
footer.M1
mescc-tools-Release_1.3/test/test11/cleanup.sh 0000775 0000000 0000000 00000001434 14126326331 0021336 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test11/hello.hex2
rm -f test/test11/footer.M1
exit 0
mescc-tools-Release_1.3/test/test11/hello.M1 0000664 0000000 0000000 00000002274 14126326331 0020655 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE SYSCALL_ALWAYS 000000EF
DEFINE LOADI_ALWAYS A0E3
DEFINE ADDI_PC_ALWAYS 8FE2
DEFINE R0 0
DEFINE R1 1
DEFINE R2 2
DEFINE R7 7
:_start
!1 R0 '0' LOADI_ALWAYS
!string2 R1 '0' ADDI_PC_ALWAYS
!18 R2 '0' LOADI_ALWAYS
!4 R7 '0' LOADI_ALWAYS
SYSCALL_ALWAYS
!1 R0 '0' LOADI_ALWAYS
!string1 R1 '0' ADDI_PC_ALWAYS
!18 R2 '0' LOADI_ALWAYS
!4 R7 '0' LOADI_ALWAYS
SYSCALL_ALWAYS
!0 R0 '0' LOADI_ALWAYS
!1 R7 '0' LOADI_ALWAYS
SYSCALL_ALWAYS
:ELF_data
<
:string1
"Hello mescc-tools
"
<
:string2
"Hello tacos-tools
"
mescc-tools-Release_1.3/test/test11/hello.sh 0000775 0000000 0000000 00000002700 14126326331 0021007 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/blood-elf -f test/test11/hello.M1 --little-endian -o test/test11/footer.M1 || exit 1
./bin/M1 --little-endian --architecture armv7l -f test/test11/hello.M1 -f test/test11/footer.M1 -o test/test11/hello.hex2 || exit 2
./bin/hex2 --little-endian --architecture armv7l --base-address 0x10000 -f elf_headers/elf32-ARM-debug.hex2 -f test/test11/hello.hex2 -o test/results/test11-binary || exit 3
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "armv7l" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test11-binary > test/test11/proof
r=$?
[ $r = 0 ] || exit 4
out=$(sha256_check test/test11/proof.answer)
[ "$out" = "test/test11/proof: OK" ] || exit 5
fi
exit 0
mescc-tools-Release_1.3/test/test11/proof.answer 0000664 0000000 0000000 00000000124 14126326331 0021711 0 ustar 00root root 0000000 0000000 a6948a4bd82471e91d045417093336ed44fc0e36a6083dffb47a5a0b9cac0d1b test/test11/proof
mescc-tools-Release_1.3/test/test12/ 0000775 0000000 0000000 00000000000 14126326331 0017347 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test12/.gitignore 0000664 0000000 0000000 00000001411 14126326331 0021334 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
*.hex2
footer.M1
mescc-tools-Release_1.3/test/test12/cleanup.sh 0000775 0000000 0000000 00000001434 14126326331 0021337 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test12/hello.hex2
rm -f test/test12/footer.M1
exit 0
mescc-tools-Release_1.3/test/test12/hello.M1 0000664 0000000 0000000 00000002776 14126326331 0020665 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
DEFINE SYSCALL_ALWAYS 000000EF
DEFINE LOADI_ALWAYS A0E3
DEFINE ADDI_PC_ALWAYS 8FE2
DEFINE SUBI_ALWAYS 40E2
DEFINE MOVE_ALWAYS A0E1
DEFINE CMPI_ALWAYS 50E3
DEFINE BNE 1A
DEFINE BL_ALWAYS EB
DEFINE LOADB_FROM_R1_ALWAYS D1E5
DEFINE STOREB_TO_R1_ALWAYS C1E5
DEFINE R0 0
DEFINE R1 1
DEFINE R2 2
DEFINE R3 3
DEFINE R7 7
DEFINE R14 E
DEFINE PC F
:_start
:main
^~print BL_ALWAYS
!string1 R1 '0' ADDI_PC_ALWAYS
!0 R0 '0' LOADB_FROM_R1_ALWAYS
!1 R0 R0 SUBI_ALWAYS
!0 R0 '0' STOREB_TO_R1_ALWAYS
!0 R0 '0' CMPI_ALWAYS
^~main BNE
;; Exit returning success
!0 R0 '0' LOADI_ALWAYS
!1 R7 '0' LOADI_ALWAYS
SYSCALL_ALWAYS
<
:print
;; Print our char
!1 R0 '0' LOADI_ALWAYS
!string1 R1 '0' ADDI_PC_ALWAYS
!1 R2 '0' LOADI_ALWAYS
!4 R7 '0' LOADI_ALWAYS
SYSCALL_ALWAYS
'0' R14 PC '0' MOVE_ALWAYS
:ELF_data
<10
<
:string1
'FF00'
<
mescc-tools-Release_1.3/test/test12/hello.sh 0000775 0000000 0000000 00000002654 14126326331 0021020 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
set -ex
./bin/blood-elf -f test/test12/hello.M1 --little-endian -o test/test12/footer.M1 || exit 1
./bin/M1 --little-endian --architecture armv7l -f test/test12/hello.M1 -f test/test12/footer.M1 -o test/test12/hello.hex2 || exit 2
./bin/hex2 --little-endian --architecture armv7l --base-address 0x10000 -f elf_headers/elf32-ARM-debug.hex2 -f test/test12/hello.hex2 -o test/results/test12-binary || exit 3
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "armv7l" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test12-binary > test/test12/proof
r=$?
[ $r = 0 ] || exit 4
out=$(sha256_check test/test12/proof.answer)
[ "$out" = "test/test12/proof: OK" ] || exit 5
fi
exit 0
mescc-tools-Release_1.3/test/test12/proof.answer 0000664 0000000 0000000 00000000124 14126326331 0021712 0 ustar 00root root 0000000 0000000 618696ab3eaa0e64b2f72d75475a1497a33d59a408d99e73f278005b4b55ca43 test/test12/proof
mescc-tools-Release_1.3/test/test13/ 0000775 0000000 0000000 00000000000 14126326331 0017350 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test13/.gitignore 0000664 0000000 0000000 00000001376 14126326331 0021347 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
*.hex2
mescc-tools-Release_1.3/test/test13/cleanup.sh 0000775 0000000 0000000 00000001400 14126326331 0021331 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test13/hello.hex2
exit 0
mescc-tools-Release_1.3/test/test13/hello.M1 0000664 0000000 0000000 00000003557 14126326331 0020664 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
DEFINE CMPDI_R0 202C
DEFINE NULL 00000000
DEFINE BF 48
DEFINE BB 4B
DEFINE BNE 8240
DEFINE BEQ 8241
DEFINE LI_R0 0038
DEFINE LI_R3 6038
DEFINE LI_R5 A038
DEFINE LWZ_R4 8480
DEFINE SC 02000044
DEFINE MFLR_R4 A602887C
:_start
@1 CMPDI_R0 # cmpdi r0,1
^@overrr BNE # blne overrr
:backkk
@1 CMPDI_R0 # cmpdi r0,1
@overr BNE # bne overr
:backk
~over BF # bl over
:back
@4 LI_R0 # li r0, 4
@1 LI_R3 # li r3, 1
^~after BF # bl 0x8
&msg # Address of Message
NULL # garbage
NULL # garbage
:after
MFLR_R4 # mflr r4
@0 LWZ_R4 # lwz r4, 0(r4)
@15 LI_R5 # li r5, 15
SC # sc
@1 LI_R0 # li r0, 1
@42 LI_R3 # li r3, 0x2a
SC # sc
:over
~back BB # bl back
:overr
@0 CMPDI_R0 # cmpdi r0,0
@backk BEQ # beq backk
:overrr
@0 CMPDI_R0 # cmpdi r0,0
^@backkk BEQ # beq backk
:msg
"Hello World!!!
"
:ELF_end
mescc-tools-Release_1.3/test/test13/hello.sh 0000775 0000000 0000000 00000002464 14126326331 0021020 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
set -x
./bin/M1 --little-endian --architecture ppc64le -f test/test13/hello.M1 -o test/test13/hello.hex2 || exit 1
./bin/hex2 --little-endian --architecture ppc64le --base-address 0x10000 -f elf_headers/elf64-PPC64LE.hex2 -f test/test13/hello.hex2 -o test/results/test13-binary || exit 2
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "ppc64le" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test13-binary > test/test13/proof
[ $? = 42 ] || exit 3
. ./sha256.sh
out=$(sha256_check test/test13/proof.answer)
[ "$out" = "test/test13/proof: OK" ] || exit 4
fi
exit 0
mescc-tools-Release_1.3/test/test13/proof.answer 0000664 0000000 0000000 00000000124 14126326331 0021713 0 ustar 00root root 0000000 0000000 39f28142c18e15b9e9a2c0b96e98c25ba65dd6f8fd555f04bb1e2614df1c40c6 test/test13/proof
mescc-tools-Release_1.3/test/test2/ 0000775 0000000 0000000 00000000000 14126326331 0017266 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test2/.gitignore 0000664 0000000 0000000 00000001426 14126326331 0021261 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
example
example.hex2
hold
proof
mescc-tools-Release_1.3/test/test2/cleanup.sh 0000775 0000000 0000000 00000001413 14126326331 0021253 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test2/hold test/test2/proof
exit 0
mescc-tools-Release_1.3/test/test2/hello.sh 0000775 0000000 0000000 00000002450 14126326331 0020731 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test2/hex.M1 --little-endian --architecture x86 -o test/test2/hold
./bin/hex2 -f elf_headers/elf32.hex2 -f test/test2/hold --little-endian --architecture x86 --base-address 0x8048000 -o test/results/test2-binary
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "x86" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test2-binary < test/test2/hex0.hex0 > test/test2/proof
r=$?
[ $r = 0 ] || exit 1
out=$(sha256_check test/test2/proof.answer)
[ "$out" = "test/test2/proof: OK" ] || exit 2
fi
exit 0
mescc-tools-Release_1.3/test/test2/hex.M1 0000664 0000000 0000000 00000007461 14126326331 0020261 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE ADD_ebp_TO_eax 01E8
DEFINE CALLI32 E8
DEFINE CMP_eax_Immediate8 83F8
DEFINE CMP_edi_Immediate8 83FF
DEFINE INT_80 CD80
DEFINE JE32 0F84
DEFINE JE8 74
DEFINE JGE8 7D
DEFINE JL8 7C
DEFINE JMP32 E9
DEFINE JMP8 EB
DEFINE LOAD32I_eax B8
DEFINE LOAD32I_ebp BD
DEFINE LOAD32I_ebx BB
DEFINE LOAD32I_ecx B9
DEFINE LOAD32I_edi BF
DEFINE LOAD32I_edx BA
DEFINE LOAD8_al_Absolute32 A0
DEFINE MOVE_eax_TO_ebp 89C5
DEFINE MOVZBL_eax_al 0FB6C0
DEFINE NULL 00000000
DEFINE RET C3
DEFINE SHL_ebp_Immediate8 C1E5
DEFINE STORE8_al_Absolute32 A2
DEFINE SUB_eax_Immediate8 83E8
DEFINE TEST_eax_eax 85C0
# Where the ELF Header is going to hit :_start first
:read_byte
# Attempt to read 1 byte from STDIN
LOAD32I_edx %1 # set the size of chars we want
LOAD32I_ecx &input # Where to put it
LOAD32I_ebx %0 # Where are we reading from
LOAD32I_eax %3 # the syscall number for read
INT_80 # call the Kernel
TEST_eax_eax # check what we got
JE32 %Done # Got EOF call it done
# load byte
LOAD8_al_Absolute32 &input # load char
MOVZBL_eax_al # We have to zero extend it to use it
RET
:print_byte
# Print our first Hex
LOAD32I_edx %1 # set the size of chars we want
LOAD32I_ecx &output # What we are writing
LOAD32I_ebx %1 # Stdout File Descriptor
LOAD32I_eax %4 # the syscall number for write
INT_80 # call the Kernel
:hex
# Deal with #
CMP_eax_Immediate8 !35
JE8 !ascii_comment
# deal with ;
CMP_eax_Immediate8 !59
JE8 !ascii_comment
# deal all ascii less than 0
CMP_eax_Immediate8 !48
JL8 !ascii_other
# deal with 0-9
CMP_eax_Immediate8 !58
JL8 !ascii_num
# deal with all ascii less than A
CMP_eax_Immediate8 !65
JL8 !ascii_other
# deal with A-F
CMP_eax_Immediate8 !71
JL8 !ascii_high
#deal with all ascii less than a
CMP_eax_Immediate8 !97
JL8 !ascii_other
#deal with a-f
CMP_eax_Immediate8 !103
JL8 !ascii_low
# The rest that remains needs to be ignored
JMP8 !ascii_other
:ascii_num
SUB_eax_Immediate8 !48
RET
:ascii_low
SUB_eax_Immediate8 !87
RET
:ascii_high
SUB_eax_Immediate8 !55
RET
:ascii_other
LOAD32I_eax %-1
RET
:ascii_comment
CALLI32 %read_byte
CMP_eax_Immediate8 !10
JE8 !ascii_other
JMP8 !ascii_comment
:_start
# Our flag for byte processing
LOAD32I_edi %-1
# temp storage for the sum
LOAD32I_ebp %0
:loop
# Read in a byte
CALLI32 %read_byte
# process byte
CALLI32 %hex
# deal with -1 values
CMP_eax_Immediate8 !0
JL8 !loop
# deal with toggle
CMP_edi_Immediate8 !0
JGE8 !print
# process first byte of pair
MOVE_eax_TO_ebp
LOAD32I_edi %0
JMP8 !loop
# process second byte of pair
:print
# update the sum and store in output
SHL_ebp_Immediate8 !4
ADD_ebp_TO_eax
STORE8_al_Absolute32 &output
# flip the toggle
LOAD32I_edi %-1
CALLI32 %print_byte
JMP8 !loop
:Done
# program completed Successfully
LOAD32I_ebx %0 # All is well
LOAD32I_eax %1 # put the exit syscall number in eax
INT_80 # Call it a good day
# Our writable space
:input
NULL
:output
NULL
:ELF_end
mescc-tools-Release_1.3/test/test2/hex0.hex0 0000664 0000000 0000000 00000012126 14126326331 0020722 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## Self Bootstrapping Hex Assembler written in Hex
## And a shitload of comments
## That can be converted to assembly and compiled
## ELF Header
7F 45 4C 46 ## e_ident[EI_MAG0-3] ELF's magic number
02 ## e_ident[EI_CLASS] Indicating 64 bit
01 ## e_ident[EI_DATA] Indicating little endianness
01 ## e_ident[EI_VERSION] Indicating original elf
03 ## e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 ## e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
3E 00 ## e_machine Indicating AMD64
01 00 00 00 ## e_version Indicating original elf
FB 00 60 00 00 00 00 00 ## e_entry Address of the entry point
40 00 00 00 00 00 00 00 ## e_phoff Address of program header table
00 00 00 00 00 00 00 00 ## e_shoff Address of section header table
00 00 00 00 ## e_flags
40 00 ## e_ehsize Indicating our 64 Byte header
38 00 ## e_phentsize size of a program header table
01 00 ## e_phnum number of entries in program table
00 00 ## e_shentsize size of a section header table
00 00 ## e_shnum number of entries in section table
00 00 ## e_shstrndx index of the section names
## Program Header table
01 00 00 00 ## p_type
07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 ## p_offset
00 00 60 00 00 00 00 00 ## p_vaddr
00 00 00 00 00 00 00 00 ## Undefined
9B 01 00 00 00 00 00 00 ## p_filesz
9B 01 00 00 00 00 00 00 ## p_memsz
00 00 20 00 00 00 00 00 ## Required alignment
## Hex
48 83 f8 23 # cmp $0x23,%rax
74 26 # je 6000a4
48 83 f8 30 # cmp $0x30,%rax
7c 6f # jl 6000f3
48 83 f8 3a # cmp $0x3a,%rax
7c 5a # jl 6000e4
48 83 f8 41 # cmp $0x41,%rax
7c 63 # jl 6000f3
48 83 f8 47 # cmp $0x47,%rax
7c 58 # jl 6000ee
48 83 f8 61 # cmp $0x61,%rax
7c 57 # jl 6000f3
48 83 f8 67 # cmp $0x67,%rax
7c 47 # jl 6000e9
eb 4f # jmp 6000f3
## Purge Comment
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 99 01 60 00 # mov $0x600199,%rsi
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 00 00 00 00 # mov $0x0,%rax
0f 05 # syscall
48 85 c0 # test %rax,%rax
0f 84 be 00 00 00 # je 600189
8a 04 25 99 01 60 00 # mov 0x600199,%al
48 0f b6 c0 # movzbq %al,%rax
48 83 f8 0a # cmp $0xa,%rax
75 c8 # jne 6000a4
48 c7 c0 ff ff ff ff # mov $0xffffffffffffffff,%rax
c3 # retq
## ascii num
48 83 e8 30 # sub $0x30,%rax
c3 # retq
## ascii low
48 83 e8 57 # sub $0x57,%rax
c3 # retq
## ascii high
48 83 e8 37 # sub $0x37,%rax
c3 # retq
## ascii other
48 c7 c0 ff ff ff ff # mov $0xffffffffffffffff,%rax
c3 # retq
## start
49 c7 c7 ff ff ff ff # mov $0xffffffffffffffff,%r15
49 c7 c6 00 00 00 00 # mov $0x0,%r14
## Loop
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 99 01 60 00 # mov $0x600199,%rsi
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 00 00 00 00 # mov $0x0,%rax
0f 05 # syscall
48 85 c0 # test %rax,%rax
74 5d # je 600189
8a 04 25 99 01 60 00 # mov 0x600199,%al
48 0f b6 c0 # movzbq %al,%rax
e8 3c ff ff ff # callq 600078
48 83 f8 00 # cmp $0x0,%rax
7c c7 # jl 600109
49 83 ff 00 # cmp $0x0,%r15
7d 0c # jge 600154
49 89 c6 # mov %rax,%r14
49 c7 c7 00 00 00 00 # mov $0x0,%r15
eb b5 # jmp 600109
## print
49 c1 e6 04 # shl $0x4,%r14
4c 01 f0 # add %r14,%rax
88 04 25 9a 01 60 00 # mov %al,0x60019a
49 c7 c7 ff ff ff ff # mov $0xffffffffffffffff,%r15
48 c7 c2 01 00 00 00 # mov $0x1,%rdx
48 c7 c6 9a 01 60 00 # mov $0x60019a,%rsi
48 c7 c7 01 00 00 00 # mov $0x1,%rdi
48 c7 c0 01 00 00 00 # mov $0x1,%rax
0f 05 # syscall
eb 80 # jmp 600109
## Done
48 c7 c7 00 00 00 00 # mov $0x0,%rdi
48 c7 c0 3c 00 00 00 # mov $0x3c,%rax
0f 05 # syscall
## Place for input, This actually isn't required but here it is
02 00 00
mescc-tools-Release_1.3/test/test2/proof.answer 0000664 0000000 0000000 00000000123 14126326331 0021630 0 ustar 00root root 0000000 0000000 a9a48fdbff46b4d7e1596bae4bd44c23f554a285b404dc151b63a073b2efce62 test/test2/proof
mescc-tools-Release_1.3/test/test3/ 0000775 0000000 0000000 00000000000 14126326331 0017267 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test3/.gitignore 0000664 0000000 0000000 00000001374 14126326331 0021264 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
hold
mescc-tools-Release_1.3/test/test3/cleanup.sh 0000775 0000000 0000000 00000001372 14126326331 0021260 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test3/hold
exit 0
mescc-tools-Release_1.3/test/test3/defs 0000664 0000000 0000000 00000012320 14126326331 0020131 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2016 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
#Registers
DEFINE R0 0
DEFINE R1 1
DEFINE R2 2
DEFINE R3 3
DEFINE R4 4
DEFINE R5 5
DEFINE R6 6
DEFINE R7 7
DEFINE R8 8
DEFINE R9 9
DEFINE R10 A
DEFINE R11 B
DEFINE R12 C
DEFINE R13 D
DEFINE R14 E
DEFINE R15 F
# 4OP Integer Group
DEFINE ADD.CI 0100
DEFINE ADD.CO 0101
DEFINE ADD.CIO 0102
DEFINE ADDU.CI 0103
DEFINE ADDU.CO 0104
DEFINE ADDU.CIO 0105
DEFINE SUB.BI 0106
DEFINE SUB.BO 0107
DEFINE SUB.BIO 0108
DEFINE SUBU.BI 0109
DEFINE SUBU.BO 010A
DEFINE SUBU.BIO 010B
DEFINE MULTIPLY 010C
DEFINE MULTIPLYU 010D
DEFINE DIVIDE 010E
DEFINE DIVIDEU 010F
DEFINE MUX 0110
DEFINE NMUX 0111
DEFINE SORT 0112
DEFINE SORTU 0113
# 3OP Integer Group
DEFINE ADD 05000
DEFINE ADDU 05001
DEFINE SUB 05002
DEFINE SUBU 05003
DEFINE CMP 05004
DEFINE CMPU 05005
DEFINE MUL 05006
DEFINE MULH 05007
DEFINE MULU 05008
DEFINE MULUH 05009
DEFINE DIV 0500A
DEFINE MOD 0500B
DEFINE DIVU 0500C
DEFINE MODU 0500D
DEFINE MAX 05010
DEFINE MAXU 05011
DEFINE MIN 05012
DEFINE MINU 05013
DEFINE AND 05020
DEFINE OR 05021
DEFINE XOR 05022
DEFINE NAND 05023
DEFINE NOR 05024
DEFINE XNOR 05025
DEFINE MPQ 05026
DEFINE LPQ 05027
DEFINE CPQ 05028
DEFINE BPQ 05029
DEFINE SAL 05030
DEFINE SAR 05031
DEFINE SL0 05032
DEFINE SR0 05033
DEFINE SL1 05034
DEFINE SR1 05035
DEFINE ROL 05036
DEFINE ROR 05037
DEFINE LOADX 05038
DEFINE LOADX8 05039
DEFINE LOADXU8 0503A
DEFINE LOADX16 0503B
DEFINE LOADXU16 0503C
DEFINE LOADX32 0503D
DEFINE LOADXU32 0503E
DEFINE STOREX 05048
DEFINE STOREX8 05049
DEFINE STOREX16 0504A
DEFINE STOREX32 0504B
DEFINE CMPJUMP.G 05050
DEFINE CMPJUMP.GE 05051
DEFINE CMPJUMP.E 05052
DEFINE CMPJUMP.NE 05053
DEFINE CMPJUMP.LE 05054
DEFINE CMPJUMP.L 05055
DEFINE CMPJUMPU.G 05060
DEFINE CMPJUMPU.GE 05061
DEFINE CMPJUMPU.LE 05064
DEFINE CMPJUMPU.L 05065
# 2OP Integer Group
DEFINE NEG 090000
DEFINE ABS 090001
DEFINE NABS 090002
DEFINE SWAP 090003
DEFINE COPY 090004
DEFINE MOVE 090005
DEFINE NOT 090006
DEFINE BRANCH 090100
DEFINE CALL 090101
DEFINE PUSHR 090200
DEFINE PUSH8 090201
DEFINE PUSH16 090202
DEFINE PUSH32 090203
DEFINE POPR 090280
DEFINE POP8 090281
DEFINE POPU8 090282
DEFINE POP16 090283
DEFINE POPU16 090284
DEFINE POP32 090285
DEFINE POPU32 090286
DEFINE CMPSKIP.G 090300
DEFINE CMPSKIP.GE 090301
DEFINE CMPSKIP.E 090302
DEFINE CMPSKIP.NE 090303
DEFINE CMPSKIP.LE 090304
DEFINE CMPSKIP.L 090305
DEFINE CMPSKIPU.G 090380
DEFINE CMPSKIPU.GE 090381
DEFINE CMPSKIPU.LE 090384
DEFINE CMPSKIPU.L 090385
# 1OP Group
DEFINE READPC 0D00000
DEFINE READSCID 0D00001
DEFINE FALSE 0D00002
DEFINE TRUE 0D00003
DEFINE JSR_COROUTINE 0D01000
DEFINE RET 0D01001
DEFINE PUSHPC 0D02000
DEFINE POPPC 0D02001
# 2OPI Group
DEFINE ADDI E1000E
DEFINE ADDUI E1000F
DEFINE SUBI E10010
DEFINE SUBUI E10011
DEFINE CMPI E10012
DEFINE LOAD E10013
DEFINE LOAD8 E10014
DEFINE LOADU8 E10015
DEFINE LOAD16 E10016
DEFINE LOADU16 E10017
DEFINE LOAD32 E10018
DEFINE LOADU32 E10019
DEFINE CMPUI E1001F
DEFINE STORE E10020
DEFINE STORE8 E10021
DEFINE STORE16 E10022
DEFINE STORE32 E10023
DEFINE ANDI E100B0
DEFINE ORI E100B1
DEFINE XORI E100B2
DEFINE NANDI E100B3
DEFINE NORI E100B4
DEFINE XNORI E100B5
DEFINE CMPJUMPI.G E100C0
DEFINE CMPJUMPI.GE E100C1
DEFINE CMPJUMPI.E E100C2
DEFINE CMPJUMPI.NE E100C3
DEFINE CMPJUMPI.LE E100C4
DEFINE CMPJUMPI.L E100C5
DEFINE CMPJUMPUI.G E100D0
DEFINE CMPJUMPUI.GE E100D1
DEFINE CMPJUMPUI.LE E100D4
DEFINE CMPJUMPUI.L E100D5
# 1OPI Group
DEFINE JUMP.C E0002C0
DEFINE JUMP.B E0002C1
DEFINE JUMP.O E0002C2
DEFINE JUMP.G E0002C3
DEFINE JUMP.GE E0002C4
DEFINE JUMP.E E0002C5
DEFINE JUMP.NE E0002C6
DEFINE JUMP.LE E0002C7
DEFINE JUMP.L E0002C8
DEFINE JUMP.Z E0002C9
DEFINE JUMP.NZ E0002CA
DEFINE JUMP.P E0002CB
DEFINE JUMP.NP E0002CC
DEFINE CALLI E0002D0
DEFINE LOADI E0002D1
DEFINE LOADUI E0002D2
DEFINE SALI E0002D3
DEFINE SARI E0002D4
DEFINE SL0I E0002D5
DEFINE SR0I E0002D6
DEFINE SL1I E0002D7
DEFINE SR1I E0002D8
DEFINE LOADR E0002E0
DEFINE LOADR8 E0002E1
DEFINE LOADRU8 E0002E2
DEFINE LOADR16 E0002E3
DEFINE LOADRU16 E0002E4
DEFINE LOADR32 E0002E5
DEFINE LOADRU32 E0002E6
DEFINE STORER E0002F0
DEFINE STORER8 E0002F1
DEFINE STORER16 E0002F2
DEFINE STORER32 E0002F3
DEFINE CMPSKIPI.G E000A00
DEFINE CMPSKIPI.GE E000A01
DEFINE CMPSKIPI.E E000A02
DEFINE CMPSKIPI.NE E000A03
DEFINE CMPSKIPI.LE E000A04
DEFINE CMPSKIPI.L E000A05
DEFINE CMPSKIPUI.G E000A10
DEFINE CMPSKIPUI.GE E000A11
DEFINE CMPSKIPUI.LE E000A14
DEFINE CMPSKIPUI.L E000A15
# 0OPI Group
DEFINE JUMP 3C00
# HALCODE Group
DEFINE FOPEN_READ 42100000
DEFINE FOPEN_WRITE 42100001
DEFINE FCLOSE 42100002
DEFINE REWIND 42100003
DEFINE FSEEK 42100004
DEFINE FGETC 42100100
DEFINE FPUTC 42100200
DEFINE HAL_MEM 42110000
# 0OP Group
DEFINE NOP 00000000
DEFINE HALT FFFFFFFF
mescc-tools-Release_1.3/test/test3/hello.sh 0000775 0000000 0000000 00000002453 14126326331 0020735 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test3/defs -f test/test3/lisp.s --big-endian --architecture knight-native -o test/test3/hold
./bin/hex2 -f test/test3/hold --big-endian --architecture knight-native --base-address 0 -o test/results/test3-binary
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "knight*" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test3-binary < test/test3/example.s >| test/test3/proof
r=$?
[ $r = 0 ] || exit 1
out=$(sha256_check test/test3/proof.answer)
[ "$out" = "test/test3/proof: OK" ] || exit 2
fi
exit 0
mescc-tools-Release_1.3/test/test3/lisp.s 0000664 0000000 0000000 00000320275 14126326331 0020433 0 ustar 00root root 0000000 0000000 ; Copyright (C) 2016 Jeremiah Orians
; This file is part of stage0.
;
; stage0 is free software: you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation, either version 3 of the License, or
; (at your option) any later version.
;
; stage0 is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with stage0. If not, see .
;; A simple lisp with a precise garbage collector for cells
;; Cells are in the following form:
;; Type (0), CAR (4), CDR (8), ENV (12)
;; Each being the length of a register [32bits]
;;
;; Type maps to the following values
;; FREE = 1, MARKED = (1 << 1),INT = (1 << 2),SYM = (1 << 3),
;; CONS = (1 << 4),PROC = (1 << 5),PRIMOP = (1 << 6),CHAR = (1 << 7), STRING = (1 << 8)
;; CONS space: End of program -> 1MB (0x100000)
;; HEAP space: 1MB -> 1.5MB (0x180000)
;; STACK space: 1.5MB -> End of Memory (2MB (0x200000))
;; Start function
:start
;; Check if we are going to hit outside the world
HAL_MEM ; Get total amount of Memory
LOADR R1 @MINIMAL_MEMORY ; Get our Minimal Value
CMPSKIP.GE R0 R1 ; Check if we have enough
JUMP @FAILED_INITIALIZATION ; If not fail gracefully
LOADR R15 @stack_start ; Put stack after CONS and HEAP
;; We will be using R14 for our condition codes
;; We will be using R13 for which Input we will be using
;; We will be using R12 for which Output we will be using
;; Ensure a known good state
FALSE R0 ; Reset R0
FALSE R1 ; Reset R1
;; Initialize
CALLI R15 @garbage_init
CALLI R15 @init_sl3
;; Prep TAPE_01
LOADUI R0 0x1100
FOPEN_READ
;; We first read Tape_01 until completion
LOADUI R13 0x1100
;; Prep TAPE_02
LOADUI R0 0x1101
FOPEN_WRITE
;; Main loop
:main
CALLI R15 @garbage_collect ; Clean up unused cells
CALLI R15 @Readline ; Read another S-expression
JUMP.Z R1 @main ; Don't allow empty strings
CALLI R15 @parse ; Convert into tokens
LOADR R1 @top_env ; Get TOP_ENV
CALLI R15 @eval ; Evaluate tokens
CALLI R15 @writeobj ; Print result
LOADUI R0 10 ; Use LF
COPY R1 R12 ; And desired Output
FPUTC ; Write Line Feed
FALSE R0 ; Clear R0
FALSE R1 ; Clear R1
JUMP @main ; Loop forever
HALT ; If broken get the fuck out now
:stack_start
'00180000'
;; How much memory is too little
:MINIMAL_MEMORY
'00180000'
;; Halt the machine in the event of insufficient Memory
:FAILED_INITIALIZATION
FALSE R1 ; Set output to TTY
LOADUI R0 $FAILED_STRING ; Prepare our Message
CALLI R15 @Print_String ; Print it
HALT ; Prevent any further damage
:FAILED_STRING
"Please provide 1600KB of Memory for this Lisp to run (More is recommended for large programs)
"
;; Append_Cell
;; Adds a cell to the end of a CDR chain
;; Receives HEAD in R0 and Tail in R1
;; Returns HEAD if not NULL
:append_Cell
CMPSKIPI.NE R0 0 ; If HEAD is NULL
MOVE R0 R1 ; Swap TAIL and HEAD
PUSHR R3 R15 ; Protect R3
PUSHR R0 R15 ; Preserve HEAD
:append_Cell_loop
LOAD32 R3 R0 8 ; Load HEAD->CDR
CMPSKIPI.NE R3 0 ; If HEAD->CDR is NULL
JUMP @append_Cell_done ; Append and call it done
;; Walk down list
MOVE R0 R3 ; Make HEAD->CDR the new HEAD
JUMP @append_Cell_loop ; And try again
:append_Cell_done
STORE32 R1 R0 8 ; Store HEAD->CDR = Tail
POPR R0 R15 ; Ensure we are returning HEAD of list
POPR R3 R15 ; Restore R3
RET R15
;; Tokenize
;; Converts a string into a list of tokens
;; Receives HEAD in R0, Pointer to String in R1 and Size of string in R2
;; Returns HEAD of list in R0
:tokenize
;; Deal with Edge case
CMPSKIPI.NE R2 0 ; If remaining is 0
RET R15 ; Just return
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
FALSE R4 ; Set Counter to 0
;; Try to find whitespace Char
:tokenize_loop
LOADXU8 R3 R1 R4 ; Get char
CMPSKIPI.G R3 32 ; If control character or SPACE
JUMP @tokenize_append ; Stop
CMPSKIPI.NE R3 34 ; If raw string
JUMP @tokenize_string ; Process that whole thing
;; Walk further down string
ADDUI R4 R4 1 ; Next char
JUMP @tokenize_loop ; And try again
:tokenize_string
;; Walk further down string
ADDUI R4 R4 1 ; Next char
LOADXU8 R3 R1 R4 ; Get char
CMPSKIPI.NE R3 34 ; If Found matching quote
JUMP @tokenize_append ; Stop
JUMP @tokenize_string ; And try again
:tokenize_append
FALSE R3 ; NULL terminate
STOREX8 R3 R1 R4 ; Found Token
COPY R3 R1 ; Preserve pointer to string
CMPSKIPI.NE R4 0 ; If empty
JUMP @tokenize_iterate ; Don't bother to append
;; Make string token and append
SWAP R0 R1 ; Need to send string in R0 for call
CALLI R15 @make_sym ; Convert string to token
SWAP R0 R1 ; Put HEAD and Tail in proper order
CALLI R15 @append_Cell ; Append Token to HEAD
;; Loop down string until end, appending tokens along the way
:tokenize_iterate
ADDUI R4 R4 1 ; Move past NULL
ADD R1 R3 R4 ; Update string pointer
SUB R2 R2 R4 ; Decrement by size used
FALSE R4 ; Reset Counter
CMPSKIPI.LE R2 0 ; If NOT end of string
JUMP @tokenize_loop ; try to append another token
;; Clean up
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
RET R15
;; is_integer
;; Receives pointer to string in R0
;; Returns TRUE or FALSE in R0
:is_integer
PUSHR R1 R15 ; Protect R1
LOADU8 R1 R0 0 ; Read first Char
CMPSKIPI.NE R1 45 ; If starts with -
LOADU8 R1 R0 1 ; Get Second Char
FALSE R0 ; Assume FALSE
CMPSKIPI.GE R1 48 ; If below '0'
JUMP @is_integer_done ; Return FALSE
CMPSKIPI.G R1 57 ; If 0 to 9
TRUE R0 ; Set to TRUE
:is_integer_done
POPR R1 R15 ; Restore R1
RET R15
;; numerate_string function
;; Receives pointer To string in R0
;; Returns number in R0 equal to value of string
;; Or Zero in the event of invalid string
:numerate_string
;; Preserve Registers
PUSHR R1 R15
PUSHR R2 R15
PUSHR R3 R15
PUSHR R4 R15
;; Initialize
MOVE R1 R0 ; Get Text pointer out of the way
FALSE R2 ; Set Negative flag to false
FALSE R3 ; Set current count to Zero
LOAD8 R0 R1 1 ; Get second byte
CMPSKIPI.NE R0 120 ; If the second byte is x
JUMP @numerate_string_hex ; treat string like hex
;; Deal with Decimal input
LOADUI R4 10 ; Multiply by 10
LOAD8 R0 R1 0 ; Get a byte
CMPSKIPI.NE R0 45 ; If - toggle flag
TRUE R2 ; So that we know to negate
CMPSKIPI.E R2 0 ; If toggled
ADDUI R1 R1 1 ; Move to next
:numerate_string_dec
LOAD8 R0 R1 0 ; Get a byte
CMPSKIPI.NE R0 0 ; If NULL
JUMP @numerate_string_done ; Be done
MUL R3 R3 R4 ; Shift counter by 10
SUBI R0 R0 48 ; Convert ascii to number
CMPSKIPI.GE R0 0 ; If less than a number
JUMP @numerate_string_done ; Terminate NOW
CMPSKIPI.L R0 10 ; If more than a number
JUMP @numerate_string_done ; Terminate NOW
ADDU R3 R3 R0 ; Don't add to the count
ADDUI R1 R1 1 ; Move onto next byte
JUMP @numerate_string_dec
;; Deal with Hex input
:numerate_string_hex
LOAD8 R0 R1 0 ; Get a byte
CMPSKIPI.E R0 48 ; All hex strings start with 0x
JUMP @numerate_string_done ; Be done if not a match
ADDUI R1 R1 2 ; Move to after leading 0x
:numerate_string_hex_0
LOAD8 R0 R1 0 ; Get a byte
CMPSKIPI.NE R0 0 ; If NULL
JUMP @numerate_string_done ; Be done
SL0I R3 4 ; Shift counter by 16
SUBI R0 R0 48 ; Convert ascii number to number
CMPSKIPI.L R0 10 ; If A-F
SUBI R0 R0 7 ; Shove into Range
CMPSKIPI.L R0 16 ; If a-f
SUBI R0 R0 32 ; Shove into Range
ADDU R3 R3 R0 ; Add to the count
ADDUI R1 R1 1 ; Get next Hex
JUMP @numerate_string_hex_0
;; Clean up
:numerate_string_done
CMPSKIPI.E R2 0 ; If Negate flag has been set
NEG R3 R3 ; Make the number negative
MOVE R0 R3 ; Put number in R0
;; Restore Registers
POPR R4 R15
POPR R3 R15
POPR R2 R15
POPR R1 R15
RET R15
;; atom
;; Converts tokens into native forms
;; Aka numbers become numbers and everything else is a symbol
;; Receives a pointer to Token in R0
;; Returns a pointer to a Cell in R0
:atom
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOAD32 R1 R0 4 ; Get CAR
LOADU8 R2 R1 0 ; Get first Char
CMPSKIPI.E R2 39 ; If Not Quote Char
JUMP @atom_string ; Move to next type
;; When dealing with a quote
ADDUI R1 R1 1 ; Move past quote Char
STORE32 R1 R0 4 ; And write to CAR
LOADUI R1 $NIL ; Using NIL
CALLI R15 @make_cons ; Make a cons with the token
MOVE R1 R0 ; Put the resulting CONS in R1
LOADUI R0 $s_quote ; Using S_QUOTE
CALLI R15 @make_cons ; Make a CONS with the CONS
MOVE R1 R0 ; Put What is being returned into R1
JUMP @atom_done ; We are done
:atom_string
CMPSKIPI.E R2 34 ; If Not Double quote
JUMP @atom_integer ; Move to next type
;; a->string = a->string + 1
ADDUI R1 R1 1 ; Move past quote Char
STORE32 R1 R0 4 ; And write to CAR
;; a->type = STRING
LOADUI R1 256 ; Using STRING
STORE32 R1 R0 0 ; Set type to Integer
COPY R1 R0 ; Put the cell we were given in the right place
JUMP @atom_done ; We are done
:atom_integer
COPY R2 R1 ; Preserve String pointer
SWAP R0 R1 ; Put string Pointer in R0
CALLI R15 @is_integer ; Determine if it is an integer
JUMP.Z R0 @atom_functions ; If Not an integer move on
LOADUI R0 4 ; Using INT
STORE32 R0 R1 0 ; Set type to Integer
MOVE R0 R2 ; Using String pointer
CALLI R15 @numerate_string ; Convert to Number
STORE32 R0 R1 4 ; Store result in CAR
JUMP @atom_done ; We are done (Result is in R1)
:atom_functions
COPY R0 R2 ; Using String pointer
CALLI R15 @findsym ; Lookup Symbol
LOADUI R3 $NIL ; Using NIL
CMPSKIP.NE R0 R3 ; If NIL was Returned
JUMP @atom_new ; Make a new Symbol
LOAD32 R1 R0 4 ; Make OP->CAR our result
JUMP @atom_done ; We are done (Result is in R1)
:atom_new
LOADR32 R0 @all_symbols ; Get pointer to all symbols
SWAP R0 R1 ; Put pointers in correct order
COPY R3 R0 ; Protect A
CALLI R15 @make_cons ; Make a CONS out of Token and all_symbols
STORER32 R0 @all_symbols ; Update all_symbols
MOVE R1 R3 ; Put result in correct register
:atom_done
MOVE R0 R1 ; Put our result in R0
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
:token_stack
NOP ; Pointer to Unparsed Tokens
;; readobj
;; Breaks up tokens on the token_stack until its empty
;; Receives Nothing
;; Returns a Cell in R0
:readobj
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
LOADR32 R0 @token_stack ; Get HEAD
LOAD32 R1 R0 8 ; Get HEAD->CDR
STORER32 R1 @token_stack ; Update Token Stack
FALSE R1 ; Using NULL
STORE32 R1 R0 8 ; Set HEAD->CDR
LOAD32 R1 R0 4 ; Get HEAD->CAR
LOADU8 R1 R1 0 ; Get First Char of HEAD->CAR
CMPSKIPI.E R1 40 ; If NOT (
JUMP @readobj_0 ; Atomize HEAD
CALLI R15 @readlist ; Otherwise we want the result of readlist
JUMP @readobj_done
:readobj_0
CALLI R15 @atom ; Let Atom process HEAD for us
:readobj_done
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; readlist
;; CONS up Rest of elements until ) is found
;; Receives nothing
;; Returns A Cell in R0
:readlist
PUSHR R1 R15 ; Protect R1
LOADR32 R0 @token_stack ; Get HEAD
LOAD32 R1 R0 4 ; Get HEAD->CAR
LOADU8 R1 R1 0 ; Get first Char of HEAD->CAR
CMPSKIPI.E R1 41 ; If NOT )
JUMP @readlist_0 ; CONS up elements
LOAD32 R1 R0 8 ; Get HEAD->CDR
STORER32 R1 @token_stack ; Update token stack
LOADUI R0 $NIL ; Use NIL (Result in R0)
JUMP @readlist_done
:readlist_0
CALLI R15 @readobj ; Have readobj do its work
MOVE R1 R0 ; Put the result in a safe place
CALLI R15 @readlist ; Recursively call self
SWAP R0 R1 ; Put results in proper order
CALLI R15 @make_cons ; Make into a CONS (Result in R0)
:readlist_done
POPR R1 R15 ; Restore R1
RET R15
;; parse
;; Starts the recursive tokenizing and atomizing of input
;; Receives a string in R0 and its length in R1
;; Returns a list of Cells in R0
:parse
PUSHR R2 R15 ; Protect R2
MOVE R2 R1 ; Put Size in the correct place
MOVE R1 R0 ; Put string pointer in the correct place
CALLI R15 @tokenize ; Get a list of tokens from string
STORER32 R0 @token_stack ; Shove list to token_stack
JUMP.NZ R0 @parse_0 ; If not a NULL list atomize
LOADUI R0 $NIL ; Otherwise we return NIL
JUMP @parse_done ; Result in R0
:parse_0
CALLI R15 @readobj ; Start the atomization (Result in R0)
:parse_done
POPR R2 R15 ; Restore R2
RET R15
;; Our simple malloc function
;; Receives A number of bytes to allocate in R0
;; Returns a pointer to Segment in R0
:malloc
PUSHR R1 R15 ; Protect R1
LOADR R1 @malloc_pointer ; Get current malloc pointer
;; update malloc pointer
SWAP R0 R1
ADD R1 R0 R1
STORER R1 @malloc_pointer
;; Done
POPR R1 R15 ; Restore R1
RET R15
;; Our static value for malloc pointer
;; Starting at 1MB
:malloc_pointer
'00100000'
;; Switch_Input
;; If R13 is TTY, HALT
;; Else Set input to TTY
:Switch_Input
CMPSKIPI.NE R13 0 ; IF TTY
HALT ; Simply Done
FALSE R13 ; Otherwise switch to TTY
RET R15
;; Readline
;; Using IO source in R13 read a FULL S-expression
;; Returns String pointer in R0 and Length in R1
:Readline
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
PUSHR R5 R15 ; Protect R5
FALSE R0 ; Get where space is free
CALLI R15 @malloc
MOVE R2 R0 ; Preserve pointer
FALSE R3 ; Set index to 0
FALSE R4 ; Set Depth to 0
COPY R1 R13 ; Set desired IO
LOADUI R5 32 ; Keep SPACE for ()
;; Main Loop
:Readline_loop
FGETC ; Get a Byte
CMPSKIPI.G R0 4 ; If EOF
CALLI R15 @Switch_Input ; Do the correct thing
CMPSKIPI.NE R0 13 ; If CR
LOADUI R0 10 ; Replace with LF
CMPSKIPI.NE R13 0 ; Don't display unless TTY
FPUTC ; Display the Char we just pressed
CMPSKIPI.G R0 32 ; If SPACE or below
JUMP @Readline_1
CMPSKIPI.NE R0 34 ; Look for double quote
JUMP @Readline_string ; Keep looping until then
CMPSKIPI.NE R0 59 ; If LINE Comment (;)
JUMP @Readline_0 ; Drop until the end of Line
CMPSKIPI.NE R0 40 ; If (
JUMP @Readline_2 ; Deal with depth and spacing
CMPSKIPI.NE R0 41 ; If )
JUMP @Readline_2 ; Deal with depth and spacing
STOREX8 R0 R2 R3 ; Append to String
ADDUI R3 R3 1 ; Increment Size
JUMP @Readline_loop ; Keep Reading
;; Deal with Line comments
:Readline_0
FGETC ; Get another Byte
CMPSKIPI.NE R0 13 ; Deal with CR
LOADUI R0 10 ; Convert to LF
CMPSKIPI.NE R0 10 ; If LF
JUMP @Readline_loop ; Resume
JUMP @Readline_0 ; Otherwise Keep Looping
;; Deal with strings
:Readline_string
STOREX8 R0 R2 R3 ; Append to String
ADDUI R3 R3 1 ; Increment Size
FGETC ; Get a Byte
CMPSKIPI.NE R0 13 ; Deal with CR
LOADUI R0 10 ; Convert to LF
CMPSKIPI.NE R13 0 ; Don't display unless TTY
FPUTC ; Display the Char we just pressed
CMPSKIPI.E R0 34 ; Look for double quote
JUMP @Readline_string ; Keep looping until then
STOREX8 R0 R2 R3 ; Append to String
ADDUI R3 R3 1 ; Increment Size
JUMP @Readline_loop ; Resume
;; Deal with Whitespace and Control Chars
:Readline_1
CMPSKIPI.NE R4 0 ; IF Depth 0
JUMP @Readline_done ; We made it to the end
LOADUI R0 32 ; Otherwise convert to SPACE
STOREX8 R0 R2 R3 ; Append to String
ADDUI R3 R3 1 ; Increment Size
JUMP @Readline_loop ; Keep Looping
;; Deal with ()
:Readline_2
CMPSKIPI.NE R0 40 ; If (
ADDUI R4 R4 1 ; Increment Depth
CMPSKIPI.NE R0 41 ; If )
SUBUI R4 R4 1 ; Decrement Depth
STOREX8 R5 R2 R3 ; Put in leading SPACE
ADDUI R3 R3 1 ; Increment Size
STOREX8 R0 R2 R3 ; Put in Char
ADDUI R3 R3 1 ; Increment Size
STOREX8 R5 R2 R3 ; Put in Trailing SPACE
ADDUI R3 R3 1 ; Increment Size
JUMP @Readline_loop ; Resume
;; Clean up
:Readline_done
ADDUI R0 R3 4 ; Pad with 4 NULLs
CALLI R15 @malloc ; Correct Malloc
MOVE R1 R3 ; Put Size in R1
POPR R5 R15 ; Restore R5
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
RET R15
;; Write_Int
;; Writes desired integer to desired IO
;; Receives Integer in R0 and IO in R1
;; Returns Nothing
:Max_Decimal
'3B9ACA00'
:Write_Int
PUSHR R0 R15 ; Preserve R0
PUSHR R1 R15 ; Preserve R1
PUSHR R2 R15 ; Preserve R2
PUSHR R3 R15 ; Preserve R3
PUSHR R4 R15 ; Preserve R4
PUSHR R5 R15 ; Preserve R5
MOVE R3 R0 ; Move Integer out of the way
JUMP.Z R3 @Write_Int_ZERO ; Deal with Special case of ZERO
JUMP.P R3 @Write_Int_Positive
LOADUI R0 45 ; Using -
FPUTC ; Display leading -
NOT R3 R3 ; Flip into positive
ADDUI R3 R3 1 ; Adjust twos
:Write_Int_Positive
LOADR R2 @Max_Decimal ; Starting from the Top
LOADUI R5 10 ; We move down by 10
FALSE R4 ; Flag leading Zeros
:Write_Int_0
DIVIDE R0 R3 R3 R2 ; Break off top 10
CMPSKIPI.E R0 0 ; If Not Zero
TRUE R4 ; Flip the Flag
JUMP.Z R4 @Write_Int_1 ; Skip leading Zeros
ADDUI R0 R0 48 ; Shift into ASCII
FPUTC ; Print Top
:Write_Int_1
DIV R2 R2 R5 ; Look at next 10
CMPSKIPI.E R2 0 ; If we reached the bottom STOP
JUMP @Write_Int_0 ; Otherwise keep looping
:Write_Int_done
;; Cleanup
POPR R5 R15 ; Restore R5
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
:Write_Int_ZERO
LOADUI R0 48 ; Using Zero
FPUTC ; Display
JUMP @Write_Int_done ; Be done
;; Print_String
;; Prints the string pointed in R0 to IO in R1
;; Receives string pointer in R0 and IO in R1
;; Returns nothing
:Print_String
PUSHR R0 R15 ; Protect R0
PUSHR R2 R15 ; Protect R2
MOVE R2 R0 ; Get pointer out of the way
:Print_String_loop
LOADU8 R0 R2 0 ; Get Char
CMPSKIPI.NE R0 0 ; If NULL
JUMP @Print_String_done ; Call it done
FPUTC ; Otherwise write the Char
ADDUI R2 R2 1 ; Increment to next Char
JUMP @Print_String_loop ; And Keep looping
:Print_String_done
POPR R2 R15 ; Restore R2
POPR R0 R15 ; Restore R0
RET R15
;; writeobj
;; Outputs to the IO in R12
;; Receives a Cell list in R0
;; Returns nothing
:writeobj
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
COPY R3 R0 ; Protect HEAD
LOAD32 R2 R0 0 ; Load HEAD->Type
COPY R1 R12 ; Using desired output
CMPSKIPI.NE R2 4 ; If INT
JUMP @writeobj_INT ; Print it and be done
CMPSKIPI.NE R2 8 ; If SYM
JUMP @writeobj_SYM ; Print its string
CMPSKIPI.NE R2 16 ; If CONS
JUMP @writeobj_CONS ; Print it all recursively
CMPSKIPI.NE R2 32 ; If PROC
JUMP @writeobj_PROC ; Print Label
CMPSKIPI.NE R2 64 ; If PRIMOP
JUMP @writeobj_PRIMOP ; Print Label
CMPSKIPI.NE R2 128 ; If CHAR
JUMP @writeobj_CHAR ; Print the Char
CMPSKIPI.NE R2 256 ; If STRING
JUMP @writeobj_STRING ; Print the String
;; What the hell is that???
LOADUI R0 $writeobj_Error
FALSE R1
CALLI R15 @Print_String
HALT
:writeobj_Error
"What the fuck was that?"
:writeobj_INT
LOAD32 R0 R0 4 ; Get HEAD->CAR
CALLI R15 @Write_Int ; Write it output
JUMP @writeobj_done ; Be done
:writeobj_CONS
LOADUI R0 40 ; Using (
FPUTC ; Write to desired output
:writeobj_CONS_0
LOAD32 R0 R3 4 ; Get HEAD->CAR
CALLI R15 @writeobj ; Recurse on HEAD->CAR
LOAD32 R3 R3 8 ; Set HEAD to HEAD->CDR
LOADUI R0 $NIL ; Using NIL
CMPJUMPI.E R0 R3 @writeobj_CONS_1
LOAD32 R0 R3 0 ; Get HEAD->type
CMPSKIPI.E R0 16 ; if Not CONS
JUMP @writeobj_CONS_2 ; Deal with inner case
LOADUI R0 32 ; Using SPACE
FPUTC ; Write out desired space
JUMP @writeobj_CONS_0 ; Keep looping
;; Deal with case of op->cdr == nil
:writeobj_CONS_1
LOADUI R0 41 ; Using )
FPUTC ; Write to desired output
JUMP @writeobj_done ; Be Done
:writeobj_CONS_2
COPY R0 R3 ; Using HEAD
CALLI R15 @writeobj ; Recurse
LOADUI R0 41 ; Using )
FPUTC ; Write to desired output
JUMP @writeobj_done ; Be Done
:writeobj_SYM
LOAD32 R0 R3 4 ; Get HEAD->CAR
CALLI R15 @Print_String ; Write it to output
JUMP @writeobj_done ; Be Done
:PRIMOP_String
"#"
:writeobj_PRIMOP
LOADUI R0 $PRIMOP_String ; Using the desired string
CALLI R15 @Print_String ; Write it to output
JUMP @writeobj_done ; Be Done
:PROC_String
"#"
:writeobj_PROC
LOADUI R0 $PROC_String ; Using the desired string
CALLI R15 @Print_String ; Write it to output
JUMP @writeobj_done ; Be Done
:writeobj_STRING
LOAD32 R0 R3 4 ; Get HEAD->CAR
CALLI R15 @Print_String ; Write it to output
JUMP @writeobj_done ; Be Done
:writeobj_CHAR
LOADU8 R0 R3 7 ; Using bottom 8 bits of HEAD->CAR
FPUTC ; We write our desired output
:writeobj_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; strcmp
;; A simple string compare function
;; Receives string pointers in R0 and R1
;; Returns result of comparision in R0
:strcmp
;; Preserve registers
PUSHR R2 R15
PUSHR R3 R15
PUSHR R4 R15
;; Setup registers
MOVE R2 R0
MOVE R3 R1
LOADUI R4 0
:cmpbyte
LOADXU8 R0 R2 R4 ; Get a byte of our first string
LOADXU8 R1 R3 R4 ; Get a byte of our second string
ADDUI R4 R4 1 ; Prep for next loop
CMP R1 R0 R1 ; Compare the bytes
CMPSKIPI.E R0 0 ; Stop if byte is NULL
JUMP.E R1 @cmpbyte ; Loop if bytes are equal
;; Done
MOVE R0 R1 ; Prepare for return
;; Restore registers
POPR R4 R15
POPR R3 R15
POPR R2 R15
RET R15
;; findsym
;; Attempts to find a symbol in a CONS list
;; Receives a string in R0
;; Returns Cell or NIL in R0
:findsym
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
COPY R3 R0 ; Protect String
LOADR R2 @all_symbols ; Get all_symbols
:findsym_loop
LOADUI R0 $NIL ; Using NIL
CMPSKIP.NE R0 R2 ; Check if we reached the end
JUMP @findsym_done ; Use NIL as our result
LOAD32 R0 R2 4 ; Get symlist->CAR
LOAD32 R0 R0 4 ; Get symlist->CAR->CAR
COPY R1 R3 ; Prepare string to find
CALLI R15 @strcmp ; See if we have a match
JUMP.E R0 @findsym_found ; We have a match
LOAD32 R2 R2 8 ; symlist = symlist->CDR
JUMP @findsym_loop ; Keep looping
:findsym_found
MOVE R0 R2 ; We want symlist as our result
:findsym_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; intern
;; Either find symbol or make it
;; Receives string pointer in R0
;; Returns a Cell pointer in R0
:intern
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
COPY R1 R0 ; Protect String
CALLI R15 @findsym ; Lookup Symbol
CMPSKIPI.NE R0 $NIL ; Determine if Symbol was found
JUMP @intern_found ; And if so, use it
MOVE R0 R1 ; Using our string
CALLI R15 @make_sym ; Make a SYM
COPY R2 R0 ; Protect Cell
LOADR32 R1 @all_symbols ; Get all_symbols
CALLI R15 @make_cons ; CONS together
STORER32 R0 @all_symbols ; Update all_symbols
MOVE R0 R2 ; Restore Cell
JUMP @intern_done ; R0 has our result
:intern_found
LOAD32 R0 R0 4 ; Use op->CAR as our result
:intern_done
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; extend
;; CONS up symbols with an environment
;; Receives an environment in R0, symbol in R1 and Value in R2
;; Returns a CONS of CONS in R0
:extend
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
SWAP R2 R0 ; Protect the env until we need it
SWAP R0 R1 ; Put Symbol and Value in Correct Order
CALLI R15 @make_cons ; Make inner CONS
MOVE R1 R2 ; Get env now that we need it
CALLI R15 @make_cons ; Make outter CONS
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; multiple_extend
;; Receives an environment in R0, symbol in R1 and Values in R2
;; Returns an extended environment in R0
:multiple_extend
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
PUSHR R5 R15 ; Protect R5
LOADUI R5 $NIL ; We will need NIL
:multiple_extend_0
CMPJUMPI.E R1 R5 @multiple_extend_done
LOAD32 R3 R1 8 ; Protect SYMS->CDR
LOAD32 R4 R2 8 ; Protect VALS->CDR
LOAD32 R1 R1 4 ; Using SYMS->CAR
LOAD32 R2 R2 4 ; Using VALS->CAR
CALLI R15 @extend ; Extend Environment
MOVE R1 R3 ; USING SYMS->CDR
MOVE R2 R4 ; VALS->CDR
JUMP @multiple_extend_0 ; Iterate until fully extended
:multiple_extend_done
POPR R5 R15 ; Restore R5
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; extend_env
;; Receives a Symbol in R0, a Value in R1 and an environment pointer in R2
;; Returns Value in R0 after extending top
:extend_env
PUSHR R1 R15 ; Protect Val
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
CALLI R15 @make_cons ; Make a cons of SYM and VAL
MOVE R3 R0 ; Put safely out of way
LOAD32 R0 R2 4 ; Using ENV->CAR
LOAD32 R1 R2 8 ; And ENV->CDR
CALLI R15 @make_cons ; Make a cons of old environment
STORE32 R0 R2 8 ; SET ENV->CDR to old environment
STORE32 R3 R2 4 ; SET ENV->CAR to new CONS
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore Val
COPY R0 R1 ; Return Val
RET R15
;; assoc
;; Receives a Key in R0 and an alist in R1
;; Returns Value if Found or NIL in R0
:assoc
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 $NIL ; Using NIL
LOAD32 R0 R0 4 ; Using KEY->CAR
:assoc_0
CMPJUMPI.E R1 R4 @assoc_done
LOAD32 R2 R1 4 ; ALIST->CAR
LOAD32 R3 R2 4 ; ALIST->CAR->CAR
LOAD32 R3 R3 4 ; ALIST->CAR->CAR->CAR
LOAD32 R1 R1 8 ; ALIST = ALIST->CDR
CMPSKIP.E R0 R3 ; If ALIST->CAR->CAR->CAR != KEY->CAR
JUMP @assoc_0 ; Iterate using ALIST->CDR
;; Found KEY
MOVE R4 R2 ; Set ALIST->CAR as our return value
:assoc_done
MOVE R0 R4 ; Use whatever in R4 as our return
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; evlis
;; Receives Expressions in R0 and an Environment in R1
;; Returns the result of Evaluation of those Expressions
;; in respect to the given Environment in R0
:evlis
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
COPY R3 R1 ; Protect ENV
LOAD32 R2 R0 4 ; Protect EXPRS->CAR
LOAD32 R0 R0 8 ; Using EXPRS->CDR
CALLI R15 @evlis ; Recursively Call self Down Expressions
SWAP R0 R2 ; Using EXPRS->CDR
MOVE R1 R3 ; Restore ENV
CALLI R15 @eval ; EVAL
MOVE R1 R2 ; Using result of EVAL and EVLIS
CALLI R15 @make_cons ; Make a CONS of it all
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; progn
;; Receives Expressions in R0 and an Environment in R1
;; Returns the result of Evaluation of those Expressions
;; in respect to the given Environment in R0
:progn
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
:progn_0
LOAD32 R2 R0 8 ; Protect EXPS->CDR
LOAD32 R0 R0 4 ; Using EXPS->CAR
CALLI R15 @eval ; EVAL
CMPSKIP.E R2 R3 ; If EXPS->CDR NOT NIL
MOVE R0 R2 ; Use EXPS->CDR for next loop
JUMP.Z R2 @progn_0 ; Keep looping if EXPS->CDR isn't NIL
;; Finally broke out of loop
;; Desired result is in R0
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; Apply
;; Receives a Procedure in R0 and Values in R1
;; Applies the procedure to the values and returns the result in R0
:apply
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOAD32 R3 R0 0 ; Get PROC->TYPE
;; Deal with PRIMOPs
CMPSKIPI.E R3 64 ; If Not PRIMOP
JUMP @apply_0 ; Check NEXT
LOAD32 R3 R0 4 ; Using PROC->CAR
MOVE R0 R1 ; Apply to VALs
CALL R3 R15 ; Call PROC->CAR with VALs
JUMP @apply_done ; Simply Pass the results
;; Deal with Procedures
:apply_0
CMPSKIPI.E R3 32 ; If Not PROC
JUMP @apply_1 ; Abort with FIRE
MOVE R2 R1 ; Protect VALUE and put in future correct place
MOVE R3 R0 ; Protect PROC
LOAD32 R0 R3 12 ; Get PROC->ENV
LOAD32 R1 R0 8 ; Get PROC->ENV->CDR
LOAD32 R0 R0 4 ; Get PROC->ENV->CAR
CALLI R15 @make_cons ; ENV = MAKE_CONS(PROC->ENV->CAR, PROC->ENV->CDR)
LOAD32 R1 R3 4 ; Get PROC->CAR
CALLI R15 @multiple_extend ; R0 = MULTIPLE_EXTEND(ENV, PROC->CAR, VALS)
MOVE R1 R0 ; Put Extended_Env in the right place
LOAD32 R0 R3 8 ; Get PROC->CDR
CALLI R15 @progn ; PROGN(PROC->CDR, R0)
JUMP @apply_done ; Simply Pass the results
;; Deal with unknown shit
:apply_1
LOADUI R0 $apply_error ; Using designated Error Message
FALSE R1 ; Using TTY
CALLI R15 @Print_String ; Write Message
HALT ; And bring the FIRE
:apply_error
"Bad argument to apply"
;; Clean up and return
:apply_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; evcond
;; Receives an Expression in R0 and an Environment in R1
;; Walks down conditions until true one is found and return
;; Desired expression's result in R0
;; if none of the conditions are true, and the result of
;; the COND is undefined
:evcond
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 $TEE ; Using TEE
;; Truth Evaluation
:evcond_0
LOAD32 R3 R0 8 ; Protect EXP->CDR
LOAD32 R2 R0 4 ; Protect EXP->CAR
LOAD32 R0 R2 4 ; Using EXP->CAR->CAR
CALLI R15 @eval ; EVAL
CMPJUMPI.E R0 R4 @evcond_1 ; Its true !
MOVE R0 R3 ; Using EXP->CDR
CALLI R15 @evcond ; Recurse
JUMP @evcond_done ; Bail with just NIL
;; Expression Evaluation
:evcond_1
LOAD32 R0 R2 8 ; Get EXP->CAR->CDR
LOAD32 R0 R0 4 ; Using EXP->CAR->CDR->CAR
CALLI R15 @eval ; EVAL
;; Clean up and return
:evcond_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; eval
;; Receives an Expression in R0 and an Environment in R1
;; Evaluates the expression in the given environment and returns
;; The result in R0
:eval
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOAD32 R4 R0 0 ; Get EXP->TYPE
;; Deal with special case of Integers
CMPSKIPI.NE R4 4 ; If EXP->TYPE is Integer
JUMP @eval_done ; Simply return what was given
;; Deal with special case of Symbols
CMPSKIPI.E R4 8 ; If EXP->TYPE is NOT Symbol
JUMP @eval_cons ; Move onto next Case
CALLI R15 @process_sym ; process the symbol
JUMP @eval_done ; Return it
;; Deal with special cases of CONS
:eval_cons
CMPSKIPI.E R4 16 ; If EXP->TYPE is NOT CONS
JUMP @eval_proc ; Move onto next Case
CALLI R15 @process_cons ; Deal with all CONS
JUMP @eval_done ; Simply return the result
:eval_proc
CMPSKIPI.E R4 32 ; If EXP->TYPE is NOT PROC
JUMP @eval_primop ; Move onto next Case
JUMP @eval_done
:eval_primop
CMPSKIPI.E R4 64 ; If EXP->TYPE is NOT PRIMOP
JUMP @eval_char ; Move onto next Case
:eval_char
CMPSKIPI.E R4 128 ; If EXP->TYPE is NOT CHAR
JUMP @eval_string ; Move onto next Case
JUMP @eval_done
:eval_string
CMPSKIPI.E R4 256 ; If EXP->TYPE is NOT STRING
JUMP @eval_error ; Move onto next Case
JUMP @eval_done
:eval_error
LOADUI R0 $eval_error_Message ; Use a specific message to aid debugging
FALSE R1 ; Written to TTY
CALLI R15 @Print_String ; Write NOW
HALT
:eval_error_Message
"EVAL Received unknown Object"
;; Result must be in R0 by this point
;; Simply Clean up and return result in R0
:eval_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; process_sym
;; Receives Expression in R0 and an Environment in R1
;; Returns symbol in R0
:process_sym
CALLI R15 @assoc ; ASSOC to get tmp
CMPSKIPI.NE R0 $NIL ; If NIL is returned
JUMP @process_bad_Symbol ; Burn with FIRE
LOAD32 R0 R0 8 ; Return tmp->CDR
RET R15
:process_bad_Symbol
LOADUI R0 $sym_unbound ; Using the designated Error message
FALSE R1 ; Using TTY
CALLI R15 @Print_String ; Written for the user
HALT ; Simply toss the rest into the fire
:sym_unbound
"Unbound symbol"
;; process_if
;; Receives Expression in R0 and an Environment in R1
;; Returns the evaluation of the expression if true in R0
;; Or the evaluation of the CDR of the expression
:process_if
PUSHR R2 R15 ; Protect R2
LOAD32 R2 R0 8 ; Protect EXP->CDR
LOAD32 R0 R2 4 ; Using EXP->CDR->CAR
CALLI R15 @eval ; Recurse to get truth
CMPSKIPI.NE R0 $NIL ; If Result was NOT NIL
LOAD32 R2 R2 8 ; Update to EXP->CDR->CDR
LOAD32 R0 R2 8 ; Get EXP->CDR->CDR
LOAD32 R0 R0 4 ; Using EXP->CDR->CDR->CAR
CALLI R15 @eval ; Recurse to get result
POPR R2 R15 ; Restore R2
RET R15
;; process_setb
;; Receives Expression in R0 and an Environment in R1
;; Sets the desired variable to desired value/type
;; Returns the value/type in R0
:process_setb
PUSHR R2 R15 ; Protect R2
LOAD32 R2 R0 8 ; Protect EXP->CDR
LOAD32 R0 R2 8 ; Get EXP->CDR->CDR
LOAD32 R0 R0 4 ; Using EXP->CDR->CDR->CAR
CALLI R15 @eval ; Recurse to get New value
SWAP R0 R2 ; Protect New Value
LOAD32 R0 R0 4 ; Using EXP->CDR->CAR
CALLI R15 @assoc ; Get the associated Symbol
STORE32 R2 R0 8 ; SET Pair->CDR to New Value
MOVE R0 R2 ; Using New Value
POPR R2 R15 ; Restore R2
RET R15
;; process_let
;; Receives Expression in R0 and an Environment in R1
;; Creates lexical closure and evaluates inside of it
;; Returns the value/type in R0
:process_let
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
PUSHR R5 R15 ; Protect R5
LOADUI R4 $NIL ; Get NIL
MOVE R3 R1 ; Get ENV out of the way
MOVE R2 R0 ; Protect EXP
LOAD32 R5 R2 8 ; Get EXP->CDR
LOAD32 R5 R5 4 ; LETS = EXP->CDR->CAR
:process_let_0
CMPJUMPI.E R5 R4 @process_let_1
LOAD32 R0 R5 4 ; Get LETS->CAR
LOAD32 R0 R0 8 ; Get LETS->CAR->CDR
LOAD32 R0 R0 4 ; Get LETS->CAR->CDR->CAR
COPY R1 R3 ; Using ENV
CALLI R15 @eval ; CELL = EVAL(LETS->CAR->CDR->CAR, ENV)
MOVE R1 R0 ; Put CELL in the right place
LOAD32 R0 R5 4 ; Get LETS->CAR
LOAD32 R0 R0 4 ; Get LETS->CAR->CAR
CALLI R15 @make_cons ; CELL = MAKE_CONS(LETS->CAR->CAR, CELL)
COPY R1 R3 ; Using ENV
CALLI R15 @make_cons ; CELL = MAKE_CONS(CELL, ENV)
MOVE R3 R0 ; ENV = CELL
LOAD32 R5 R5 8 ; LETS = LETS->CDR
JUMP @process_let_0 ; Iterate through bindings
:process_let_1
MOVE R1 R3 ; Using ENV
LOAD32 R0 R2 8 ; Get EXP->CDR
LOAD32 R0 R0 8 ; Using EXP->CDR->CDR
CALLI R15 @progn ; Process inside of Closure
;; Cleanup
POPR R5 R15 ; Restore R5
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; process_cons
;; Receives Expression in R0 and an Environment in R1
;; Returns the evaluation of whatever special used or
;; The application of the evaluation in R0
:process_cons
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOAD32 R4 R0 4 ; Using EXP->CAR
LOADUI R3 $s_if ; Using s_if
CMPJUMPI.NE R4 R3 @process_cons_cond
CALLI R15 @process_if ; deal with special case of If statements
JUMP @process_cons_done ; Return it
:process_cons_cond
LOADUI R3 $s_cond ; Using s_cond
CMPJUMPI.NE R4 R3 @process_cons_begin
;; Deal with special case of COND statements
LOAD32 R0 R0 8 ; Using EXP->CDR
CALLI R15 @evcond ; EVCOND
JUMP @process_cons_done ; Simply use it's result
:process_cons_begin
LOADUI R3 $s_begin ; Using s_begin
CMPJUMPI.NE R4 R3 @process_cons_lambda
;; Deal with special case of BEGIN statements
LOAD32 R0 R0 8 ; Using EXP->CDR
CALLI R15 @progn ; PROGN
JUMP @process_cons_done ; Simply use it's result
:process_cons_lambda
LOADUI R3 $s_lambda ; Using s_lambda
CMPJUMPI.NE R4 R3 @process_cons_quote
;; Deal with special case of lambda statements
MOVE R2 R1 ; Put ENV in the right place
LOAD32 R1 R0 8 ; Get EXP->CDR
LOAD32 R0 R1 4 ; Using EXP->CDR->CAR
LOAD32 R1 R1 8 ; Using EXP->CDR->CDR
CALLI R15 @make_proc ; MAKE_PROC
JUMP @process_cons_done ; Simply return its result
:process_cons_quote
LOADUI R3 $s_quote ; Using s_quote
CMPJUMPI.NE R4 R3 @process_cons_define
;; Deal with special case of quote statements
LOAD32 R0 R0 8 ; Get EXP->CDR
LOAD32 R0 R0 4 ; Using EXP->CDR->CAR
JUMP @process_cons_done ; Simply use it as the result
:process_cons_define
LOADUI R3 $s_define ; Using s_define
CMPJUMPI.NE R4 R3 @process_cons_set
;; Deal with special case of Define statements
LOAD32 R2 R0 8 ; Using EXP->CDR
LOAD32 R0 R2 8 ; Get EXP->CDR->CDR
LOAD32 R0 R0 4 ; Using EXP->CDR->CDR->CAR
CALLI R15 @eval ; Recurse to figure out what it is
SWAP R2 R1 ; Put Environment in the right place
SWAP R1 R0 ; Put Evaluation in the right place
LOAD32 R0 R0 4 ; Using EXP->CDR->CAR
CALLI R15 @extend_env ; EXTEND_ENV
JUMP @process_cons_done ; Simply use what was returned
:process_cons_set
LOADUI R3 $s_setb ; Using s_setb
CMPJUMPI.NE R4 R3 @process_cons_let
CALLI R15 @process_setb ; Deal with special case of SET statements
JUMP @process_cons_done ; Simply Return Result
:process_cons_let
LOADUI R3 $s_let ; Using s_let
CMPJUMPI.NE R4 R3 @process_cons_apply
CALLI R15 @process_let ; Deal with special case of LET statements
JUMP @process_cons_done ; Simply Return Result
:process_cons_apply
;; Deal with the last option for a CONS, APPLY
LOAD32 R2 R0 4 ; Protect EXP->CAR
LOAD32 R0 R0 8 ; Using EXP->CDR
CALLI R15 @evlis ; EVLIS
SWAP R0 R2 ; Protect EVLIS result
CALLI R15 @eval ; Recurse to figure out what to APPLY
MOVE R1 R2 ; Put EVLIS result in right place
CALLI R15 @apply ; Apply what was found to the EVLIS result
:process_cons_done
POPR R4 R15 ; Restore R2
POPR R3 R15 ; Restore R2
POPR R2 R15 ; Restore R2
RET R15
;; prim_apply
;; Receives arglist in R0
;; Returns result of applying ARGS->CAR to ARGS->CDR->CAR
:prim_apply_String
"apply"
:prim_apply
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
LOAD32 R1 R0 8 ; Get ARGS->CDR
LOAD32 R1 R1 4 ; Get ARGS->CDR->CAR
LOAD32 R0 R0 4 ; Get ARGS->CAR
CALLI R15 @apply ; Use backing function
;; Cleanup
POPR R1 R15 ; Restore R1
RET R15
;; nullp
;; Receives a CELL in R0
;; Returns NIL if not NIL or TEE if NIL
:nullp_String
"null?"
:nullp
PUSHR R1 R15 ; Protect R1
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOADUI R1 $NIL ; Using NIL
CMPSKIPI.NE R0 $NIL ; If NIL Expression
LOADUI R1 $TEE ; Return TEE
MOVE R0 R1 ; Put result in correct register
POPR R1 R15 ; Restore R1
RET R15
;; prim_sum
;; Receives a list in R0
;; Adds all values and returns a Cell with result in R0
:prim_sum_String
"+"
:prim_sum
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
FALSE R2 ; Initialize our SUM at 0
:prim_sum_0
CMPJUMPI.E R0 R3 @prim_sum_done
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
ADD R2 R2 R1 ; sum = sum + value
JUMP @prim_sum_0 ; Go to next list item
:prim_sum_done
MOVE R0 R2 ; Put SUM in right spot
CALLI R15 @make_int ; Get our Cell
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_sub
;; Receives a list in R0
;; Subtracts all of the values and returns a Cell with the result in R0
:prim_sub_String
"-"
:prim_sub
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting SUM
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_sub_0
CMPJUMPI.E R0 R3 @prim_sub_done
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
SUB R2 R2 R1 ; sum = sum - value
JUMP @prim_sub_0 ; Go to next list item
:prim_sub_done
MOVE R0 R2 ; Put SUM in right spot
CALLI R15 @make_int ; Get our Cell
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_prod
;; Receives a list in R0
;; Multiplies all of the values and returns a Cell with the result in R0
:prim_prod_String
"*"
:prim_prod
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOADUI R2 1 ; Initialize our Product at 1
:prim_prod_0
CMPJUMPI.E R0 R3 @prim_prod_done
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
MUL R2 R2 R1 ; sum = sum + value
JUMP @prim_prod_0 ; Go to next list item
:prim_prod_done
MOVE R0 R2 ; Put SUM in right spot
CALLI R15 @make_int ; Get our Cell
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_div
;; Receives a list in R0
;; Divides all of the values and returns a Cell with the result in R0
:prim_div_String
"/"
:prim_div
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting SUM
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_div_0
CMPJUMPI.E R0 R3 @prim_div_done
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
DIV R2 R2 R1 ; sum = sum - value
JUMP @prim_div_0 ; Go to next list item
:prim_div_done
MOVE R0 R2 ; Put result in right spot
CALLI R15 @make_int ; Get our Cell
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_mod
;; Receives a list in R0
;; Remainders all of the values and returns a Cell with the result in R0
:prim_mod_String
"mod"
:prim_mod
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting SUM
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_mod_0
CMPJUMPI.E R0 R3 @prim_mod_done
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
MOD R2 R2 R1 ; sum = sum - value
JUMP @prim_mod_0 ; Go to next list item
:prim_mod_done
MOVE R0 R2 ; Put result in right spot
CALLI R15 @make_int ; Get our Cell
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_and
;; Receives a list in R0
;; ANDs all of the values and returns a Cell with the result in R0
:prim_and_String
"and"
:prim_and
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 $TEE ; Using TEE
LOADUI R3 $NIL ; Using NIL
:prim_and_0
CMPJUMPI.E R0 R3 @prim_and_done
LOAD32 R2 R0 4 ; Get ARGS->CAR
CMPJUMPI.NE R2 R4 @prim_and_1
LOAD32 R0 R0 8 ; Get ARGS->CDR
JUMP @prim_and_0 ; Go to next list item
:prim_and_1
COPY R2 R3 ; Return NIL
:prim_and_done
MOVE R0 R2 ; Put result in correct location
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_or
;; Receives a list in R0
;; ORs all of the values and returns a Cell with the result in R0
:prim_or_String
"or"
:prim_or
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 $TEE ; Using TEE
LOADUI R3 $NIL ; Using NIL
:prim_or_0
CMPJUMPI.E R0 R3 @prim_or_1
LOAD32 R2 R0 4 ; Get ARGS->CAR
CMPJUMPI.E R2 R4 @prim_or_done
LOAD32 R0 R0 8 ; Get ARGS->CDR
JUMP @prim_or_0 ; Go to next list item
:prim_or_1
COPY R2 R3 ; Couldn't find a true
:prim_or_done
MOVE R0 R2 ; Put result in correct location
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_not
;; Receives a list in R0
;; NOTs first of the values and returns a Cell with the result in R0
:prim_not_String
"not"
:prim_not
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
CMPSKIPI.E R0 $TEE ; If not TEE
JUMP @prim_not_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_not_done ; Return our NIL
:prim_not_0
LOADUI R0 $TEE ; Make TEE
:prim_not_done
RET R15
;; prim_numgt
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_numgt_String
">"
:prim_numgt
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting Value
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_numgt_0
CMPJUMPI.E R0 R3 @prim_numgt_1
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
CMPJUMPI.LE R2 R1 @prim_numgt_2
MOVE R2 R1 ; Prepare for next loop
JUMP @prim_numgt_0 ; Go to next list item
:prim_numgt_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_numgt_done ; Be done
:prim_numgt_2
LOADUI R0 $NIL ; Return NIL
:prim_numgt_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_numge
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_numge_String
">="
:prim_numge
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting Value
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_numge_0
CMPJUMPI.E R0 R3 @prim_numge_1
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
CMPJUMPI.L R2 R1 @prim_numge_2
MOVE R2 R1 ; Prepare for next loop
JUMP @prim_numge_0 ; Go to next list item
:prim_numge_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_numge_done ; Be done
:prim_numge_2
LOADUI R0 $NIL ; Return NIL
:prim_numge_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_numeq
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_numeq_String
"="
:prim_numeq
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting Value
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_numeq_0
CMPJUMPI.E R0 R3 @prim_numeq_1
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
CMPJUMPI.NE R2 R1 @prim_numeq_2
MOVE R2 R1 ; Prepare for next loop
JUMP @prim_numeq_0 ; Go to next list item
:prim_numeq_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_numge_done ; Be done
:prim_numeq_2
LOADUI R0 $NIL ; Return NIL
:prim_numeq_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_numle
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_numle_String
"<="
:prim_numle
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting Value
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_numle_0
CMPJUMPI.E R0 R3 @prim_numle_1
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
CMPJUMPI.G R2 R1 @prim_numle_2
MOVE R2 R1 ; Prepare for next loop
JUMP @prim_numle_0 ; Go to next list item
:prim_numle_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_numle_done ; Be done
:prim_numle_2
LOADUI R0 $NIL ; Return NIL
:prim_numle_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_numlt
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_numlt_String
"<"
:prim_numlt
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADUI R3 $NIL ; Using NIL
LOAD32 R2 R0 4 ; Get ARGS->CAR
LOAD32 R2 R2 4 ; Using ARGS->CAR->CAR as starting Value
LOAD32 R0 R0 8 ; Using ARGS->CDR as args
:prim_numlt_0
CMPJUMPI.E R0 R3 @prim_numlt_1
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R1 R1 4 ; Get ARGS->CAR->CAR
LOAD32 R0 R0 8 ; Set ARGS to ARGS->CDR
CMPJUMPI.GE R2 R1 @prim_numlt_2
MOVE R2 R1 ; Prepare for next loop
JUMP @prim_numlt_0 ; Go to next list item
:prim_numlt_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_numlt_done ; Be done
:prim_numlt_2
LOADUI R0 $NIL ; Return NIL
:prim_numlt_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_listp
;; Receives a list in R0
;; Compares values and returns a Cell with the result in R0
:prim_listp_String
"list?"
:prim_listp
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R0 16 ; If CONS
JUMP @prim_listp_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_listp_done ; Return our NIL
:prim_listp_0
LOADUI R0 $TEE ; Make TEE
:prim_listp_done
RET R15
;; prim_charp
;; Receives argslist in R0
;; Returns #t if CHAR else NIL
:prim_charp_String
"char?"
:prim_charp
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R0 128 ; If CHAR
JUMP @prim_charp_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_charp_done
:prim_charp_0
LOADUI R0 $TEE ; Make TEE
:prim_charp_done
RET R15
;; prim_numberp
;; Receives argslist in R0
;; Returns #t if NUMBER else NIL
:prim_numberp_String
"number?"
:prim_numberp
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R0 4 ; If NUMBER
JUMP @prim_numberp_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_numberp_done
:prim_numberp_0
LOADUI R0 $TEE ; Make TEE
:prim_numberp_done
RET R15
;; prim_symbolp
;; Receives argslist in R0
;; Returns #t if SYMBOL else NIL
:prim_symbolp_String
"symbol?"
:prim_symbolp
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R0 8 ; If SYMBOL
JUMP @prim_symbolp_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_symbolp_done
:prim_symbolp_0
LOADUI R0 $TEE ; Make TEE
:prim_symbolp_done
RET R15
;; prim_stringp
;; Receives argslist in R0
;; Returns #t if CHAR else NIL
:prim_stringp_String
"string?"
:prim_stringp
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R0 256 ; If CHAR
JUMP @prim_stringp_0 ; Return TEE
LOADUI R0 $NIL ; Otherwise return NIL
JUMP @prim_stringp_done
:prim_stringp_0
LOADUI R0 $TEE ; Make TEE
:prim_stringp_done
RET R15
;; prim_output
;; Receives argslist in R0
;; Outputs to whatever is specified in R12 and returns TEE
:prim_output
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 $NIL ; Using NIL
COPY R1 R12 ; Set to use desired output
:prim_output_0
CMPJUMPI.E R0 R4 @prim_output_done
LOAD32 R3 R0 4 ; Get ARGS->CAR
LOAD32 R2 R3 0 ; Get ARGS->CAR->TYPE
SWAP R0 R3 ; Protect ARGS
CMPSKIPI.NE R2 4 ; If INT
CALLI R15 @prim_output_INT ; Print the value
CMPSKIPI.NE R2 8 ; If SYM
CALLI R15 @prim_output_SYM ; Print the string
CMPSKIPI.NE R2 16 ; If CONS
CALLI R15 @prim_output ; Recurse
CMPSKIPI.NE R2 128 ; If CHAR
CALLI R15 @prim_output_CHAR ; Just print the last Char
LOAD32 R0 R3 8 ; Get ARGS->CDR
JUMP @prim_output_0 ; Loop until we hit NIL
:prim_output_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
LOADUI R0 $TEE ; Return TEE
RET R15
;; prim_output_INT
;; Receives an INT CELL in R0 and desired Output in R1
;; Outputs value and returns
:prim_output_INT
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
LOAD32 R0 R0 4 ; Get ARG->CAR
CALLI R15 @Write_Int ; Write it
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; prim_output_SYM
;; Receives a SYM CELL in R0 and desired Output in R1
;; Outputs string and returns
:prim_output_SYM
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
LOAD32 R0 R0 4 ; Get ARG->CAR
CALLI R15 @Print_String ; Print the string
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; prim_output_CHAR
;; Receives an CHAR CELL in R0 and desired Output in R1
;; Outputs Last CHAR and returns
:prim_output_CHAR
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
LOADU8 R0 R0 7 ; Get ARG->CAR [bottom 8 bits]
FPUTC ; Display desired CHAR
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; prim_stringeq
;; Receives a list in R0
;; Compares strings and returns a Cell with the result in R0
:prim_stringeq_String
"string=?"
:prim_stringeq
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R3 $NIL ; Using NIL
LOAD32 R1 R0 4 ; Get ARGS->CAR
LOAD32 R4 R1 4 ; Using ARGS->CAR->CAR as TEMP
LOAD32 R2 R0 8 ; Using ARGS->CDR as args
:prim_stringeq_0
CMPJUMPI.E R2 R3 @prim_stringeq_1
LOAD32 R0 R2 4 ; Get ARGS->CAR
LOAD32 R0 R0 4 ; Get ARGS->CAR->CAR
COPY R1 R4 ; Restore TEMP for string comparison
CALLI R15 @strcmp ; Compare the strings
JUMP.NE R0 @prim_stringeq_2 ; Stop if not equal
LOAD32 R2 R2 8 ; Set ARGS to ARGS->CDR
JUMP @prim_stringeq_0 ; Go to next list item
:prim_stringeq_1
LOADUI R0 $TEE ; Return TEE
JUMP @prim_stringeq_done ; Be done
:prim_stringeq_2
LOADUI R0 $NIL ; Return NIL
:prim_stringeq_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_display
;; Receives argslist in R0
;; Outputs to TTY R12 and returns TEE
:prim_display_String
"display"
:prim_display
CALLI R15 @prim_output
RET R15
;; prim_write
;; Receives argslist in R0
;; Write to Tape_02 and returns TEE
:prim_write_String
"write"
:prim_write
LOADUI R12 0x1101 ; Write to Tape_02
CALLI R15 @prim_output ; Use shared prim_output
FALSE R12 ; Revert to TTY
RET R15
;; prim_freecell
;; Receives either NIL or a list in R0
;; If NIL displays header, otherwise just returns number of free cells in R0
:prim_freecell_String
"free_mem"
:prim_freecell
PUSHR R1 R15 ; Protect R1
CMPSKIPI.E R0 $NIL ; If NOT NIL
JUMP @prim_freecell_0 ; Skip message
LOADUI R0 $prim_freecell_Message
COPY R1 R12 ; Using Selected Output
CALLI R15 @Print_String ; Display our header
:prim_freecell_0
CALLI R15 @cells_remaining ; Get number of remaining Cells
CALLI R15 @make_int ; Convert integer in R0 to a Cell
:prim_freecell_done
POPR R1 R15 ; Restore R1
RET R15
:prim_freecell_Message
"Remaining Cells: "
;; prim_integer_to_char
;; Receives a list in R0
;; Converts INT to CHAR
:prim_integer_to_char_String
"integer->char"
:prim_integer_to_char
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
LOADUI R2 128 ; Using Type CHAR
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R1 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R1 4 ; If Type INT
STORE32 R2 R0 0 ; Update ARGS->CAR->TYPE
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_char_to_integer
;; Receives a list in R0
;; Converts CHAR to INT
:prim_char_to_integer_String
"char->integer"
:prim_char_to_integer
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
LOADUI R2 4 ; Using Type INT
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R1 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R1 128 ; If Type CHAR
STORE32 R2 R0 0 ; Update ARGS->CAR->TYPE
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; string_to_list
;; Receives a pointer to string in R0
;; Returns a list of chars
:string_to_list
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
MOVE R1 R0 ; Put string safely out of the way
LOAD8 R0 R1 0 ; Get string[0]
JUMP.Z R0 @string_to_list_null
CALLI R15 @make_char ; Make seperate CHAR
SWAP R0 R1 ; Protect RESULT
ADDUI R0 R0 1 ; Increment to next iteration
CALLI R15 @string_to_list ; Recurse down STRING
SWAP R0 R1 ; Put RESULT and TAIL in right spot
CALLI R15 @make_cons ; Combine into a Cons
JUMP @string_to_list_done ; And simply return result
:string_to_list_null
LOADUI R0 $NIL ; Nil terminate list
:string_to_list_done
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_string_to_list
;; Receives a pointer to a CONS whose CAR should be a STRING
;; Returns a list of CHARs in R0
:prim_string_to_list_String
"string->list"
:prim_string_to_list
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R1 R0 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.E R1 256 ; If Not Type STRING
JUMP @prim_string_to_list_fail
LOAD32 R0 R0 4 ; Get ARGS->CAR->STRING
CALLI R15 @string_to_list ; Convert to List
JUMP @prim_string_to_list_done
:prim_string_to_list_fail
LOADUI R0 $NIL ; Nil terminate list
:prim_string_to_list_done
POPR R1 R15 ; Restore R1
RET R15
;; list_to_string
;; Receives an index in R0, a String pointer in R1
;; And a list of arguments in R2
;; Alters only R0
:list_to_string
CMPSKIPI.NE R2 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
:list_to_string_0
CMPSKIPI.NE R2 $NIL ; If NIL Expression
JUMP @list_to_string_done ; We are done
LOAD32 R4 R2 4 ; Get ARGS->CAR
LOAD32 R3 R4 0 ; Get ARGS->CAR->TYPE
CMPSKIPI.NE R3 128 ; If Type CHAR
CALLI R15 @list_to_string_CHAR ; Process
;; Guess CONS
SWAP R2 R4 ; Put i->CAR in i's spot
CMPSKIPI.NE R3 16 ; If Type CONS
CALLI R15 @list_to_string ; Recurse
SWAP R2 R4 ; Undo the Guess
;; Everything else just iterate
LOAD32 R2 R2 8 ; i = i->CDR
JUMP @list_to_string_0 ; Lets go again
:list_to_string_CHAR
LOAD32 R3 R4 4 ; Get ARGS->CAR->VALUE
STOREX8 R3 R0 R1 ; STRING[INDEX] = i->CAR->VALUE
ADDUI R0 R0 1 ; INDEX = INDEX + 1
RET R15 ; Get back in there
:list_to_string_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_list_to_string
;; Receives a list in R0
;; Returns a String CELL in R0
:prim_list_to_string_String
"list->string"
:prim_list_to_string
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
MOVE R2 R0 ; Put Args in correct location and Zero R0
CALLI R15 @malloc ; Get where space is free
MOVE R1 R0 ; Put String pointer in correct location and Zero R0
CALLI R15 @list_to_string ; Call backing function
ADDUI R0 R0 1 ; NULL Terminate string
CALLI R15 @malloc ; Correct malloc
CALLI R15 @make_string ; Use pointer to make our string CELL
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; prim_halt
;; Simply HALTS
:prim_halt_String
"HALT"
:prim_halt
LOADUI R0 0x1101 ; Clean up after ourselves
FCLOSE ; Close our write tape
HALT
;; prim_list
;; Simply returns the argument list passed to it in R0
:prim_list_String
"list"
:prim_list
RET R15
;; prim_cons
;; Receives an arglist in R0 and returns a CONS in R0
:prim_cons_String
"cons"
:prim_cons
PUSHR R1 R15 ; Protect R1
LOAD32 R1 R0 8 ; Get ARGS->CDR
LOAD32 R1 R1 4 ; Use ARGS->CDR->CAR
LOAD32 R0 R0 4 ; Use ARGS->CAR
CALLI R15 @make_cons ; MAKE_CONS
POPR R1 R15 ; Restore R1
RET R15
;; prim_car
;; Receives an arglist in R0 and returns the CAR in R0
:prim_car_String
"car"
:prim_car
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 4 ; Using ARGS->CAR->CAR
RET R15
;; prim_cdr
;; Receives an arglist in R0 and returns the CDR in R0
:prim_cdr_String
"cdr"
:prim_cdr
CMPSKIPI.NE R0 $NIL ; If NIL Expression
RET R15 ; Just get the Hell out
LOAD32 R0 R0 4 ; Get ARGS->CAR
LOAD32 R0 R0 8 ; Using ARGS->CAR->CDR
RET R15
;; spinup
;; Receives a symbol in R0 and a primitive in R1
;; Returns nothing but CONS both to all_symbols and top_env
:spinup
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
COPY R3 R0 ; Protect SYM
MOVE R2 R1 ; Put PRIM in right Spot
LOADR R1 @all_symbols ; Get ALL_SYMBOLS
CALLI R15 @make_cons ; MAKE_CONS
STORER R0 @all_symbols ; Update ALL_SYMBOLS
MOVE R1 R3 ; Restore SYM
LOADR R0 @top_env ; Get TOP_ENV
CALLI R15 @extend ; EXTEND
STORER R0 @top_env ; Update TOP_ENV
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; Special symbols
;; NIL Object
:NIL
'00000008' ; A Symbol
&NIL_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:NIL_String
"nil"
;; TEE Object
:TEE
'00000008' ; A Symbol
&TEE_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:TEE_String
"#t"
;; Quote Object
:s_quote
'00000008' ; A Symbol
&s_quote_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_quote_String
"quote"
;; IF Object
:s_if
'00000008' ; A Symbol
&s_if_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_if_String
"if"
;; COND Object
:s_cond
'00000008' ; A Symbol
&s_cond_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_cond_String
"cond"
;; Lambda Object
:s_lambda
'00000008' ; A Symbol
&s_lambda_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_lambda_String
"lambda"
;; Define Object
:s_define
'00000008' ; A Symbol
&s_define_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_define_String
"define"
;; SET Object
:s_setb
'00000008' ; A Symbol
&s_setb_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_setb_String
"set!"
;; LET Object
:s_let
'00000008' ; A Symbol
&s_let_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_let_String
"let"
;; Begin Object
:s_begin
'00000008' ; A Symbol
&s_begin_String ; Pointer to string
'00000000' ; NUL CDR
'00000000' ; NUL ENV
:s_begin_String
"begin"
;; Globals of interest
:all_symbols
&all_symbols_init
:all_symbols_init
'00000010' ; A CONS
&NIL ; Pointer to NIL
&NIL ; Pointer to NIL
'00000000' ; NULL
:top_env
&top_env_init_1
:top_env_init_0
'00000010' ; A CONS
&NIL ; Pointer to NIL
&NIL ; Pointer to NIL
'00000000' ; NULL
:top_env_init_1
'00000010' ; A CONS
&top_env_init_0 ; Pointer to CONS of NIL
&NIL ; Pointer to NIL
'00000000' ; NULL
:free_cells
NOP ; Start with NULL
;; Global init function
;; Receives nothing
;; Returns nothing
;; sets up all_symbols and top_env
:init_sl3
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
;; Add Eval Specials
LOADUI R0 $TEE ; Get TEE
COPY R1 R0 ; Duplicate TEE
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_quote ; Get s_quote
COPY R1 R0 ; Duplicate s_quote
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_if ; Get s_if
COPY R1 R0 ; Duplicate s_if
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_cond ; Get s_cond
COPY R1 R0 ; Duplicate s_cond
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_lambda ; Get s_lambda
COPY R1 R0 ; Duplicate s_lambda
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_define ; Get s_define
COPY R1 R0 ; Duplicate s_define
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_setb ; Get s_setb
COPY R1 R0 ; Duplicate s_setb
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_let ; Get s_let
COPY R1 R0 ; Duplicate s_let
CALLI R15 @spinup ; SPINUP
LOADUI R0 $s_begin ; Get s_begin
COPY R1 R0 ; Duplicate s_if
CALLI R15 @spinup ; SPINUP
;; Add Primitive Specials
LOADUI R0 $prim_apply ; Using PRIM_APPLY
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_apply_String ; Using PRIM_APPLY_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $nullp ; Using NULLP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $nullp_String ; Using NULLP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_sum ; Using PRIM_SUM
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_sum_String ; Using PRIM_SUM_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_sub ; Using PRIM_SUB
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_sub_String ; Using PRIM_SUB_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_prod ; Using PRIM_PROD
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_prod_String ; Using PRIM_PROD_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_div ; Using PRIM_DIV
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_div_String ; Using PRIM_DIV_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_mod ; Using PRIM_MOD
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_mod_String ; Using PRIM_MOD_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_and ; Using PRIM_AND
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_and_String ; Using PRIM_AND_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_or ; Using PRIM_OR
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_or_String ; Using PRIM_OR_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_not ; Using PRIM_NOT
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_not_String ; Using PRIM_NOT_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numgt ; Using PRIM_NUMGT
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numgt_String ; Using PRIM_NUMGT_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numge ; Using PRIM_NUMGE
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numge_String ; Using PRIM_NUMGE_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numeq ; Using PRIM_NUMEQ
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numeq_String ; Using PRIM_NUMEQ_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numle ; Using PRIM_NUMLE
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numle_String ; Using PRIM_NUMLE_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numlt ; Using PRIM_NUMLT
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numlt_String ; Using PRIM_NUMLT_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_listp ; Using PRIM_LISTP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_listp_String ; Using PRIM_LISTP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_charp ; Using PRIM_CHARP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_charp_String ; Using PRIM_CHARP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_numberp ; Using PRIM_NUMBERP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_numberp_String ; Using PRIM_NUMBERP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_symbolp ; Using PRIM_SYMBOLP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_symbolp_String ; Using PRIM_SYMBOLP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_stringp ; Using PRIM_STRINGP
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_stringp_String ; Using PRIM_STRINGP_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_display ; Using PRIM_DISPLAY
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_display_String ; Using PRIM_DISPLAY_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_write ; Using PRIM_WRITE
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_write_String ; Using PRIM_WRITE_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_freecell ; Using PRIM_FREECELL
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_freecell_String ; Using PRIM_FREECELL_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_integer_to_char ; Using PRIM_INTEGER_TO_CHAR
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_integer_to_char_String ; Using PRIM_INTEGER_TO_CHAR_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_char_to_integer ; Using PRIM_CHAR_TO_INTEGER
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_char_to_integer_String ; Using PRIM_CHAR_TO_INTEGER_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_string_to_list ; Using PRIM_STRING_TO_LIST
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_string_to_list_String ; Using PRIM_STRING_TO_LIST_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_list_to_string ; Using PRIM_LIST_TO_STRING
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_list_to_string_String ; Using PRIM_LIST_TO_STRING_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_halt ; Using PRIM_HALT
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_halt_String ; Using PRIM_HALT_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_list ; Using PRIM_list
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_list_String ; Using PRIM_LIST_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_stringeq ; Using PRIM_STRINGEQ
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_stringeq_String ; Using PRIM_STRINGEQ_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_cons ; Using PRIM_CONS
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_cons_String ; Using PRIM_CONS_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_car ; Using PRIM_CAR
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_car_String ; Using PRIM_CAR_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
LOADUI R0 $prim_cdr ; Using PRIM_CDR
CALLI R15 @make_prim ; MAKE_PRIM
MOVE R1 R0 ; Put Primitive in correct location
LOADUI R0 $prim_cdr_String ; Using PRIM_CDR_STRING
CALLI R15 @make_sym ; MAKE_SYM
CALLI R15 @spinup ; SPINUP
;; Clean up
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; Left_to_take
;; The number of cells_remaining
:left_to_take
NOP
;; cells_remaining
;; Receives nothing and returns number of remaining cells in R0
:cells_remaining
LOADR R0 @left_to_take ; Get number of cells left
RET R15
;; update_remaining
;; Receives nothing
;; Returns nothing
;; Updates left_to_take via counting
:update_remaining
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
LOADR R0 @free_cells ; Get FREE_CELLS
FALSE R1 ; Set Count to 0
:update_remaining_0
JUMP.Z R0 @update_remaining_done
ADDUI R1 R1 1 ; Increment by 1
LOAD32 R0 R0 8 ; get I->CDR
JUMP @update_remaining_0 ; Keep looping til NULL
:update_remaining_done
STORER R1 @left_to_take ; update left_to_take
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; gc_block_start
:gc_block_start
&Start_CONS
;; top_allocated
:top_allocated
'000FFFF0'
;; insert_ordered
;; Receives a cell and a list of cells in R0 and R1
;; Inserts cell into the list from lowest to highest
;; Returns resulting list in R0
:insert_ordered
CMPSKIPI.NE R1 0 ; If List is NULL
RET R15 ; Just return CELL
CMPJUMPI.GE R0 R1 @insert_ordered_0
STORE32 R1 R0 8 ; Set I->CDR to LIST
RET R15 ; Simply return I
:insert_ordered_0
PUSHR R1 R15 ; Protect List from recursion
LOAD32 R1 R1 8 ; Using LIST->CDR
CALLI R15 @insert_ordered ; Recurse
POPR R1 R15 ; Restore LIST
STORE32 R0 R1 8 ; Set LIST->CDR to the result of recursion
MOVE R0 R1 ; Prepare for return
RET R15
;; reclaim_marked
;; Receives nothing
;; Returns nothing
;; Reclaims and updates free_cells
:reclaim_marked
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADR R3 @gc_block_start ; Using GC_BLOCK_START
LOADR R2 @top_allocated ; Using TOP_ALLOCATED
:reclaim_marked_0
CMPJUMPI.LE R2 R3 @reclaim_marked_done
LOAD32 R1 R2 0 ; Get I->TYPE
ANDI R1 R1 2 ; AND with MARKED
JUMP.Z R1 @reclaim_marked_1 ; Deal with MARKED CELLS or jump on NULL
;; Deal with Marked
LOADUI R0 1 ; Using FREE
STORE32 R0 R2 0 ; Set I->TYPE to FREE
FALSE R0 ; USING NULL
STORE32 R0 R2 4 ; SET I->CAR to NULL
STORE32 R0 R2 12 ; SET I->ENV to NULL
COPY R0 R2 ; Prepare for INSERT_ORDERED
LOADR R1 @free_cells ; Get FREE_CELLS
CALLI R15 @insert_ordered ; Get New FREE_CELLS Pointer
STORER R0 @free_cells ; Update FREE_CELLS to I
;; Deal with unmarked
:reclaim_marked_1
SUBUI R2 R2 16 ; Decrement I by the size of a CELL
JUMP @reclaim_marked_0 ; Iterate on next CELL
:reclaim_marked_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; mark_all_cells
;; Receives nothing
;; Returns nothing
;; Marks all unfree cells
:mark_all_cells
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
LOADR R0 @gc_block_start ; Using GC_BLOCK_START
LOADR R1 @top_allocated ; Using TOP_ALLOCATED
:mark_all_cells_0
CMPJUMPI.GE R0 R1 @mark_all_cells_done
LOAD32 R2 R0 0 ; Get I->TYPE
CMPSKIPI.NE R2 1 ; If NOT FREE
JUMP @mark_all_cells_1 ; Move onto the Next
;; Mark non-free cell
ORI R2 R2 2 ; Add MARK
STORE32 R2 R0 0 ; Write out MARK
:mark_all_cells_1
ADDUI R0 R0 16 ; Increment I by the size of a CELL
JUMP @mark_all_cells_0 ; Iterate on next CELL
:mark_all_cells_done
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; unmark_cells
;; Receives a List in R0 and R1 and a Count in R2
;; Returns nothing
;; Unmarks all connected Cells
:unmark_cells
CMPSKIPI.LE R2 2 ; If Greater than 1
RET R15 ; Just return
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
PUSHR R3 R15 ; Protect R3
PUSHR R4 R15 ; Protect R4
LOADUI R4 2 ; GET MARKED
NOT R4 R4 ; Use ~MARKED
:unmark_cells_0
JUMP.Z R0 @unmark_cells_done
CMPSKIP.NE R0 R1 ; If LIST == STOP
ADDUI R2 R2 1 ; Increment Count
LOAD32 R3 R0 0 ; Get I->TYPE
AND R3 R3 R4 ; Remove MARK
STORE32 R3 R0 0 ; Store the cleaned type
;; Deal with CONS
CMPSKIPI.NE R3 16 ; If A CONS
JUMP @unmark_cells_cons ; Deal with it
;; Deal with PROC
CMPSKIPI.NE R3 32 ; If A PROC
JUMP @unmark_cells_proc ; Deal with it
;; Everything else
JUMP @unmark_cells_1 ; Move onto NEXT
:unmark_cells_proc
LOAD32 R3 R0 12 ; Using list->ENV
CMPSKIPI.NE R3 0 ; If NULL
JUMP @unmark_cells_cons ; Skip
SWAP R0 R3 ; Protect list
CALLI R15 @unmark_cells ; Recurse until the ends
SWAP R0 R3 ; Put list back
:unmark_cells_cons
LOAD32 R3 R0 4 ; Using list->CAR
SWAP R0 R3 ; Protect list
CALLI R15 @unmark_cells ; Recurse until the ends
SWAP R0 R3 ; Put list back
:unmark_cells_1
LOAD32 R0 R0 8 ; Get list->CDR
JUMP @unmark_cells_0 ; Keep going down list
:unmark_cells_done
POPR R4 R15 ; Restore R4
POPR R3 R15 ; Restore R3
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; relocate_cell
;; Receives a current, target and List in R0, R1 and R2
;; Returns nothing
;; Relocate all references to a cell and walks down list
:relocate_cell
PUSHR R3 R15 ; Protect R3
:relocate_cell_0
JUMP.Z R2 @relocate_cell_done
;; Fix CAR References
LOAD32 R3 R2 4 ; Get LIST->CAR
CMPSKIP.NE R0 R3 ; If match with Current
STORE32 R1 R2 4 ; Fix LIST->CAR
;; Fix CDR References
LOAD32 R3 R2 8 ; Get LIST->CDR
CMPSKIP.NE R0 R3 ; If match with Current
STORE32 R1 R2 8 ; Fix LIST->CDR
;; Fix ENV References
LOAD32 R3 R2 12 ; Get LIST->ENV
CMPSKIP.NE R0 R3 ; If match with Current
STORE32 R1 R2 12 ; Fix LIST->ENV
LOAD32 R3 R2 0 ; Get LIST->TYPE
;; Deal with CONS
CMPSKIPI.NE R3 16 ; If A CONS
JUMP @relocate_cell_proc ; Deal with it
;; Deal with PROC
CMPSKIPI.NE R3 32 ; If A PROC
JUMP @relocate_cell_proc ; Deal with it
;; Everything else
JUMP @relocate_cell_1 ; Move onto NEXT
:relocate_cell_proc
PUSHR R2 R15 ; Protect LIST
LOAD32 R2 R2 4 ; Using list->CAR
CALLI R15 @relocate_cell ; Recurse until the ends
POPR R2 R15 ; Restore LIST
:relocate_cell_1
LOAD32 R2 R2 8 ; Get list->CDR
JUMP @relocate_cell_0 ; Keep going down list
:relocate_cell_done
POPR R3 R15 ; Restore R3
RET R15
;; compact
;; Receives a List in R0
;; Returns nothing
;; Finds cells to relocate and has all references updated
:compact
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
:compact_0
JUMP.Z R0 @compact_done
LOAD32 R2 R0 0 ; Get LIST->TYPE
CMPSKIPI.NE R2 1 ; If LIST->TYPE == FREE
JUMP @compact_1 ; Not worth relocating
LOADR R1 @free_cells ; Get FREE_CELLS
CMPJUMPI.LE R0 R1 @compact_1 ; Don't bother to relocate if Low
;; Found a better place for cell
SWAP R0 R1 ; Get LIST out of the way
CALLI R15 @pop_cons ; Get our New location
SWAP R0 R1 ; Put in correct order
;; Update temp to LIST
LOAD32 R2 R0 0 ; Get LIST->TYPE
STORE32 R2 R1 0 ; Set TEMP->TYPE
LOAD32 R2 R0 4 ; GET LIST->CAR
STORE32 R2 R1 4 ; Set TEMP->CAR
LOAD32 R2 R0 8 ; GET LIST->CDR
STORE32 R2 R1 8 ; Set TEMP->CDR
LOAD32 R2 R0 12 ; GET LIST->ENV
STORE32 R2 R1 12 ; Set TEMP->ENV
;; Fix Reference in Symbols list
LOADR R2 @all_symbols
CALLI R15 @relocate_cell
;; Fix References in Environment list
LOADR R2 @top_env
CALLI R15 @relocate_cell
LOAD32 R2 R0 0 ; Get LIST->TYPE
:compact_1
;; Deal with CONS
CMPSKIPI.NE R2 16 ; If A CONS
JUMP @compact_proc ; Deal with it
;; Deal with PROC
CMPSKIPI.NE R2 32 ; If A PROC
JUMP @compact_proc ; Deal with it
;; Everything else
JUMP @compact_2 ; Move onto NEXT
:compact_proc
PUSHR R0 R15 ; Protect LIST
LOAD32 R0 R0 4 ; Using list->CAR
CALLI R15 @compact ; Recurse until the ends
POPR R0 R15 ; Restore LIST
:compact_2
LOAD32 R0 R0 8 ; Get list->CDR
JUMP @compact_0 ; Keep going down list
:compact_done
POPR R2 R15 ; Restore R2
POPR R1 R15 ; Restore R1
RET R15
;; garbage_collect
;; Receives nothing
;; Returns nothing
;; The Core of Garbage Collection
:garbage_collect
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
PUSHR R2 R15 ; Protect R2
CALLI R15 @mark_all_cells ; MARK_ALL_CELLS
LOADR R0 @all_symbols ; Using ALL_SYMBOLS
COPY R1 R0 ; Using it as STOP
FALSE R2 ; Setting Counter to 0
CALLI R15 @unmark_cells ; UNMARK ALL_SYMBOLS
LOADR R0 @top_env ; Using TOP_ENV
COPY R1 R0 ; Using it as STOP
FALSE R2 ; Setting Counter to 0
CALLI R15 @unmark_cells ; UNMARK TOP_ENV
CALLI R15 @reclaim_marked ; RECLAIM_MARKED
CALLI R15 @update_remaining ; Fix the Count
LOADR R0 @all_symbols ; Using Symbols list
CALLI R15 @compact ; Compact
LOADR R0 @top_env ; Using TOP_ENV
CALLI R15 @compact ; Compact
FALSE R0 ; Using NULL
STORER R0 @top_allocated ; Clear TOP_ALLOCATED
POPR R2 R15 ; Restore R
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; garbage_init
;; Receives nothing
;; Returns nothing
;; Initializes Garbage Heap
:garbage_init
PUSHR R0 R15 ; Protect R0
PUSHR R1 R15 ; Protect R1
LOADR R0 @gc_block_start ; Get Starting Offset
ANDI R0 R0 0xF ; We only need the buttom 4 Bits
LOADR R1 @top_allocated ; Get End Address
ADD R1 R1 R0 ; Add the Offset
SUBUI R1 R1 16 ; Shift Back Down
STORER R1 @top_allocated ; Update Block End
CALLI R15 @mark_all_cells ; MARK_ALL_CELLS
CALLI R15 @reclaim_marked ; RECLAIM_MARKED
CALLI R15 @update_remaining ; Fix the Count
FALSE R0 ; Using NULL
STORER R0 @top_allocated ; Clear TOP_ALLOCATED
POPR R1 R15 ; Restore R1
POPR R0 R15 ; Restore R0
RET R15
;; pop_cons
;; Receives nothing
;; Returns a Free CONS in R0
;; Updates left_to_take
:pop_cons
PUSHR R1 R15 ; Protect R1
LOADR R0 @free_cells ; Get First Free Cell
JUMP.Z R0 @pop_cons_error ; If NULL BURN with FIRE
LOAD32 R1 R0 8 ; Get I->CDR
STORER R1 @free_cells ; Update FREE_CELLS
FALSE R1 ; Using NULL
STORE32 R1 R0 8 ; SET I->CDR to NULL
LOADR R1 @top_allocated ; Get top allocation
CMPSKIP.LE R0 R1 ; Skip if I <= TOP_ALLOCATED
STORER R0 @top_allocated ; Update TOP_ALLOCATED to new highest allocation
LOADR R1 @left_to_take ; Get LEFT_TO_TAKE
SUBUI R1 R1 1 ; Decrement by 1
STORER R1 @left_to_take ; Update LEFT_TO_TAKE
POPR R1 R15 ; Restore R1
RET R15
:pop_cons_error
LOADUI R0 $pop_cons_Message ; Using Message
FALSE R1 ; Using TTY
CALLI R15 @Print_String ; Display ERROR
HALT ; Burn with FIRE
:pop_cons_Message
"OOOPS we ran out of cells"
;; make_int
;; Receives an Integer in R0
;; Returns a CELL in R0
:make_int
PUSHR R1 R15 ; Protect R1
MOVE R1 R0 ; Protect Integer
CALLI R15 @pop_cons ; Get a CELL
STORE32 R1 R0 4 ; Set C->CAR
LOADUI R1 4 ; Using INT
STORE32 R1 R0 0 ; Set C->TYPE
POPR R1 R15 ; Restore R1
RET R15
;; make_char
;; Receives a CHAR in R0
;; Returns a CELL in R0
:make_char
PUSHR R1 R15 ; Protect R1
MOVE R1 R0 ; Protect Integer
CALLI R15 @pop_cons ; Get a CELL
STORE32 R1 R0 4 ; Set C->CAR
LOADUI R1 128 ; Using CHAR
STORE32 R1 R0 0 ; Set C->TYPE
POPR R1 R15 ; Restore R1
RET R15
;; make_string
;; Receives a string pointer in R0
;; Returns a CELL in R0
:make_string
PUSHR R1 R15 ; Protect R1
MOVE R1 R0 ; Protect Integer
CALLI R15 @pop_cons ; Get a CELL
STORE32 R1 R0 4 ; Set C->CAR
LOADUI R1 256 ; Using STRING
STORE32 R1 R0 0 ; Set C->TYPE
POPR R1 R15 ; Restore R1
RET R15
;; make_sym
;; Receives a string pointer in R0
;; Returns a Cell in R0
:make_sym
PUSHR R1 R15 ; Protect R1
MOVE R1 R0 ; Protect String Pointer
CALLI R15 @pop_cons ; Get a CELL
STORE32 R1 R0 4 ; Set C->CAR
LOADUI R1 8 ; Using SYM
STORE32 R1 R0 0 ; Set C->TYPE
POPR R1 R15 ; Restore R1
RET R15
;; make_cons
;; Receives a Cell in R0 and R1
;; Returns a combined Cell in R0
:make_cons
PUSHR R2 R15 ; Protect R2
MOVE R2 R0 ; Protect CELL A
CALLI R15 @pop_cons ; Get a CELL
STORE32 R2 R0 4 ; Set C->CAR
STORE32 R1 R0 8 ; SET C->CDR
LOADUI R2 16 ; Using CONS
STORE32 R2 R0 0 ; Set C->TYPE
POPR R2 R15 ; Restore R2
RET R15
;; make_proc
;; Receives Cells in R0, R1 and R2
;; Returns a combined Cell in R0
:make_proc
PUSHR R3 R15 ; Protect R3
MOVE R3 R0 ; Protect CELL
CALLI R15 @pop_cons ; Get a CELL
STORE32 R3 R0 4 ; Set C->CAR
STORE32 R1 R0 8 ; Set C->CDR
STORE32 R2 R0 12 ; Set C->ENV
LOADUI R3 32 ; Using PROC
STORE32 R3 R0 0 ; Set C->TYPE
POPR R3 R15 ; Restore R3
RET R15
;; make_prim
;; Receives pointer to function in R0
;; Returns a Cell in R0
:make_prim
PUSHR R1 R15 ; Protect R1
MOVE R1 R0 ; Protect Function Pointer
CALLI R15 @pop_cons ; Get a CELL
STORE32 R1 R0 4 ; Set C->CAR
LOADUI R1 64 ; Using PRIMOP
STORE32 R1 R0 0 ; Set C->TYPE
POPR R1 R15 ; Restore R1
RET R15
;; CONS starts at the end of the program
:Start_CONS
mescc-tools-Release_1.3/test/test4/ 0000775 0000000 0000000 00000000000 14126326331 0017270 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test4/.gitignore 0000664 0000000 0000000 00000001426 14126326331 0021263 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
example
example.hex2
hold
proof
mescc-tools-Release_1.3/test/test4/MES_defs.M1 0000664 0000000 0000000 00000002635 14126326331 0021122 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE PUSH_ebp 55
DEFINE MOVE_esp_To_ebp 89E5
DEFINE SUB_Immediate8_From_esp 83EC
DEFINE PUSH_Immediate32 68
DEFINE CALLI32 E8
DEFINE ADD_Immediate8_To_esp 83C4
DEFINE TEST_eax_eax 85C0
DEFINE TEST_al_al 84C0
DEFINE LOADI32_eax B8
DEFINE LEAVE C9
DEFINE RETURN C3
DEFINE STORE_eax_To_ebp_offset8 8945
DEFINE PUSH_ebp_offset8 FF75
DEFINE PUSH_eax 50
DEFINE LOAD_eax_From_ebp_offset8 8B45
DEFINE LOAD_ebx_From_ebp_offset8 8B5D
DEFINE LOAD_ecx_From_ebp_offset8 8B4D
DEFINE LOAD_edx_From_ebp_offset8 8B55
DEFINE LOAD8_eax_From_eax_pointer 0FB600
DEFINE STORE_To_ebp_offset8_Immediate32 C745
DEFINE ADD_To_ebp_offset8_Immediate8 8345
DEFINE COPY_edx_To_eax 89C2
DEFINE ADD_eax_To_edx 01D0
DEFINE JZ8 74
DEFINE JUMP32 E9
DEFINE INT_80 CD80
mescc-tools-Release_1.3/test/test4/cleanup.sh 0000775 0000000 0000000 00000001372 14126326331 0021261 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test4/hold
exit 0
mescc-tools-Release_1.3/test/test4/hello.M1 0000664 0000000 0000000 00000001614 14126326331 0020574 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
:main
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
PUSH_Immediate32 &string_0
CALLI32 %eputs
ADD_Immediate8_To_esp !4
TEST_eax_eax
LOADI32_eax %42
LEAVE
RETURN
:string_0
"Hello, Mescc!
"
:ELF_end
mescc-tools-Release_1.3/test/test4/hello.sh 0000775 0000000 0000000 00000002402 14126326331 0020730 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -x
./bin/M1 -f test/test4/MES_defs.M1 -f test/test4/mini-libc-mes.M1 -f test/test4/hello.M1 --little-endian --architecture x86 -o test/test4/hold
./bin/hex2 -f elf_headers/elf32.hex2 -f test/test4/hold --little-endian --architecture x86 --base-address 0x8048000 -o test/results/test4-binary
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "x86" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
out=$(./test/results/test4-binary 2>&1)
r=$?
[ $r = 42 ] || exit 1
[ "$out" = "Hello, Mescc!" ] || exit 2
fi
exit 0
mescc-tools-Release_1.3/test/test4/mini-libc-mes.M1 0000664 0000000 0000000 00000004225 14126326331 0022117 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
:_start
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
CALLI32 %main
ADD_Immediate8_To_esp !0
STORE_eax_To_ebp_offset8 !-4
# exit(r);
PUSH_ebp_offset8 !-4
CALLI32 %exit
ADD_Immediate8_To_esp !4
TEST_eax_eax
LEAVE
RETURN
:_env
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
LOAD_eax_From_ebp_offset8 !8
LEAVE
RETURN
:exit
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
LOAD_ebx_From_ebp_offset8 !8
LOADI32_eax %1
INT_80
LEAVE
RETURN
:write
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
LOAD_ebx_From_ebp_offset8 !8
LOAD_ecx_From_ebp_offset8 !12
LOAD_edx_From_ebp_offset8 !16
LOADI32_eax %4
INT_80
LEAVE
RETURN
:strlen
# while (s[i]) ...
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
STORE_To_ebp_offset8_Immediate32 !-4 %0
JUMP32 %strlen_1
:strlen_0
LOAD_eax_From_ebp_offset8 !-4
ADD_To_ebp_offset8_Immediate8 !-4 !1
TEST_eax_eax
:strlen_1
LOAD_eax_From_ebp_offset8 !-4
COPY_edx_To_eax
LOAD_edx_From_ebp_offset8 !8
ADD_eax_To_edx
LOAD8_eax_From_eax_pointer
TEST_eax_eax
TEST_eax_eax
TEST_al_al
JZ8 !strlen_2
JUMP32 %strlen_0
:strlen_2
LOAD_eax_From_ebp_offset8 !-4
LEAVE
RETURN
:eputs
PUSH_ebp
MOVE_esp_To_ebp
SUB_Immediate8_From_esp !64
PUSH_ebp_offset8 !8
CALLI32 %strlen
ADD_Immediate8_To_esp !4
STORE_eax_To_ebp_offset8 !-4
# write(2, s, i);
PUSH_ebp_offset8 !-4
PUSH_ebp_offset8 !8
LOADI32_eax %2
PUSH_eax
CALLI32 %write
ADD_Immediate8_To_esp !12
TEST_eax_eax
LOADI32_eax %0
LEAVE
RETURN
#.data
:g_stdin
'00 00 00 00'
:g_environment
'00 00 00 00'
mescc-tools-Release_1.3/test/test5/ 0000775 0000000 0000000 00000000000 14126326331 0017271 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test5/.gitignore 0000664 0000000 0000000 00000001426 14126326331 0021264 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
example
example.hex2
hold
proof
mescc-tools-Release_1.3/test/test5/cleanup.sh 0000775 0000000 0000000 00000001372 14126326331 0021262 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test5/hold
exit 0
mescc-tools-Release_1.3/test/test5/exec_enable_amd64.M1 0000664 0000000 0000000 00000004251 14126326331 0022717 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE POP_RAX 58
DEFINE POP_RDI 5F
DEFINE CMP_RAX_TO_IMMEDIATE8 4883f8
DEFINE JNE8 75
DEFINE LOADI32_RSI 48C7C6
DEFINE LOADI32_RAX 48C7C0
DEFINE LOADI32_RDI 48C7C7
DEFINE LOADI32_RDX 48C7C2
DEFINE SYSCALL 0F05
:_start
# first check that we got the correct number of inputs
POP_RAX # Get the number of arguments
POP_RDI # Get the program name
POP_RDI # Get the actual argument
# Check if we have the correct number of inputs
CMP_RAX_TO_IMMEDIATE8 !02
# Jump to Bail if the number is not correct
JNE8 !Bail
# Load our preferred mode (0777)
LOADI32_RSI %0x1ff
# Load the syscall number for chmod
LOADI32_RAX %90
# Call the kernel
SYSCALL
:Done
# program completed Successfully
LOADI32_RDI %0 # All is well
LOADI32_RAX %60 # put the exit syscall number in rax
SYSCALL # Call it a good day
:Bail
# first let the user know what was wrong
LOADI32_RDX %0x1a # third argument: message length
LOADI32_RSI &message # second argument: pointer to message to write
LOADI32_RDI %1 # first argument: file handle (stdout)
LOADI32_RAX %1 # system call number (sys_write)
SYSCALL # call kernel
# Second terminate with an error
LOADI32_RDI %1 # there was an error
LOADI32_RAX %60 # put the exit syscall number in eax
SYSCALL # bail out
:message
"needs a proper file name
"
:ELF_end
mescc-tools-Release_1.3/test/test5/hello.sh 0000775 0000000 0000000 00000001744 14126326331 0020741 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test5/exec_enable_amd64.M1 --little-endian --architecture amd64 -o test/test5/hold
./bin/hex2 -f elf_headers/elf64.hex2 -f test/test5/hold --little-endian --architecture amd64 --base-address 0x00600000 -o test/results/test5-binary
exit 0
mescc-tools-Release_1.3/test/test6/ 0000775 0000000 0000000 00000000000 14126326331 0017272 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test6/.gitignore 0000664 0000000 0000000 00000001426 14126326331 0021265 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
example
example.hex2
hold
proof
mescc-tools-Release_1.3/test/test6/cleanup.sh 0000775 0000000 0000000 00000001372 14126326331 0021263 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test6/hold
exit 0
mescc-tools-Release_1.3/test/test6/exec_enable_i386.M1 0000664 0000000 0000000 00000004222 14126326331 0022474 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE POP_eax 58
DEFINE POP_ebx 5B
DEFINE CMP_EAX_TO_IMMEDIATE8 83F8
DEFINE JNE8 75
DEFINE LOADI32_ECX B9
DEFINE LOADI32_EAX B8
DEFINE LOADI32_EBX BB
DEFINE LOADI32_EDX BA
DEFINE INT_80 CD80
:_start
# first check that we got the correct number of inputs
POP_eax # Get the number of arguments
POP_ebx # Get the program name
POP_ebx # Get the actual argument
# Check if we have the correct number of inputs
CMP_EAX_TO_IMMEDIATE8 !02
# Jump to Bail if the number is not correct
JNE8 !Bail
# Load our preferred mode (0777)
LOADI32_ECX %0x1ff
# Load the syscall number for chmod
LOADI32_EAX %15
# Call the kernel
INT_80
:Done
# program completed Successfully
LOADI32_EBX %0 # All is well
LOADI32_EAX %1 # put the exit syscall number in eax
INT_80 # Call it a good day
:Bail
# first let the user know what was wrong
LOADI32_EDX %0x1a # third argument: message length
LOADI32_ECX &msg # second argument: pointer to message to write
LOADI32_EBX %1 # first argument: file handle (stdout)
LOADI32_EAX %4 # system call number (sys_write)
INT_80 # call kernel
# Second terminate with an error
LOADI32_EBX %1 # there was an error
LOADI32_EAX %1 # put the exit syscall number in eax
INT_80 # bail out
:msg
"needs a proper file name
"
:ELF_end
mescc-tools-Release_1.3/test/test6/hello.sh 0000775 0000000 0000000 00000001736 14126326331 0020743 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test6/exec_enable_i386.M1 --little-endian --architecture x86 -o test/test6/hold
./bin/hex2 -f elf_headers/elf32.hex2 -f test/test6/hold --little-endian --architecture x86 --base-address 0x8048000 -o test/results/test6-binary
exit 0
mescc-tools-Release_1.3/test/test7/ 0000775 0000000 0000000 00000000000 14126326331 0017273 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test7/.gitignore 0000664 0000000 0000000 00000001401 14126326331 0021257 0 ustar 00root root 0000000 0000000 # Ignore the files created by scrip
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
hold
proof
mescc-tools-Release_1.3/test/test7/cleanup.sh 0000775 0000000 0000000 00000001413 14126326331 0021260 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test7/hold test/test7/proof
exit 0
mescc-tools-Release_1.3/test/test7/hello.sh 0000775 0000000 0000000 00000002464 14126326331 0020743 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/M1 -f test/test7/hex1_amd64.M1 --little-endian --architecture amd64 -o test/test7/hold
./bin/hex2 -f elf_headers/elf64.hex2 -f test/test7/hold --little-endian --architecture amd64 --base-address 0x00600000 -o test/results/test7-binary
. ./sha256.sh
if [ "$(./bin/get_machine ${GET_MACHINE_FLAGS})" = "amd64" ] && [ "$(./bin/get_machine ${GET_MACHINE_OS_FLAGS} --os)" = "Linux" ]
then
./test/results/test7-binary test/test7/hex1.hex1 > test/test7/proof
r=$?
[ $r = 0 ] || exit 1
out=$(sha256_check test/test7/proof.answer)
[ "$out" = "test/test7/proof: OK" ] || exit 2
fi
exit 0
mescc-tools-Release_1.3/test/test7/hex1.hex1 0000664 0000000 0000000 00000027140 14126326331 0020733 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
## ELF Header
7F 45 4C 46 # e_ident[EI_MAG0-3] ELF's magic number
02 # e_ident[EI_CLASS] Indicating 64 bit
01 # e_ident[EI_DATA] Indicating little endianness
01 # e_ident[EI_VERSION] Indicating original elf
03 # e_ident[EI_OSABI] Set at 3 because FreeBSD is strict
00 # e_ident[EI_ABIVERSION] See above
00 00 00 00 00 00 00 # e_ident[EI_PAD]
02 00 # e_type Indicating Executable
3E 00 # e_machine Indicating AMD64
01 00 00 00 # e_version Indicating original elf
78 00 60 00 00 00 00 00 # e_entry Address of the entry point (Number of bytes this header is + Base Address)
40 00 00 00 00 00 00 00 # e_phoff Address of program header table
00 00 00 00 00 00 00 00 # e_shoff Address of section header table
00 00 00 00 # e_flags
40 00 # e_ehsize Indicating our 64 Byte header
38 00 # e_phentsize size of a program header table
01 00 # e_phnum number of entries in program table
00 00 # e_shentsize size of a section header table
00 00 # e_shnum number of entries in section table
00 00 # e_shstrndx index of the section names
## Program Header table
01 00 00 00 # p_type
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # p_offset
00 00 60 00 00 00 00 00 # p_vaddr
00 00 00 00 00 00 00 00 # Undefined
00 00 00 0F 00 00 00 00 # p_filesz
00 00 00 0F 00 00 00 00 # p_memsz
00 00 20 00 00 00 00 00 # Required alignment
:a # :_start
58 ; POP_RAX # Get the number of arguments
5F ; POP_RDI # Get the program name$
5F ; POP_RDI # Get the actual input name
48C7C6 00000000 ; LOADI32_RSI %0 # prepare read_only
48C7C0 02000000 ; LOADI32_RAX %2 # the syscall number for open()
0F05 ; SYSCALL # Now open that damn file
4989C1 ; COPY_RAX_to_R9 # Preserve the file pointer we were given
49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing
49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum
49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP
E8 %b ; CALLI32 %First_pass # Process it
# rewind input file
4C89CF ; COPY_R9_to_RDI # Using our input file
48C7C6 00000000 ; LOADI32_RSI %0 # Offset Zero
48C7C2 00000000 ; LOADI32_RDX %0 # Whence Zero
48C7C0 08000000 ; LOADI32_RAX %8 # lseek
0F05 ; SYSCALL
49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing
49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum
49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP
E8 %h ; CALLI32 %Second_pass # Process it
E9 %t ; JMP32 %Done
:b # :First_pass
E8 %u ; CALLI32 %Read_byte
# Deal with EOF
483D FCFFFFFF ; CMPI32_RAX %-4
0F84 %f ; JE32 %First_pass_done
# Check for :
483D 3A000000 ; CMPI32_RAX %0x3a
0F85 %c ; JNE32 %First_pass_0
# Deal with label
E8 %y ; CALLI32 %StoreLabel
:c # :First_pass_0
# Check for %
483D 25000000 ; CMPI32_RAX %0x25
0F84 %e ; JE32 %First_pass_pointer
# Deal with everything else
E8 %g ; CALLI32 %hex # Process our char
# Deal with EOF
483D FCFFFFFF ; CMPI32_RAX %-4
0F84 %f ; JE32 %First_pass_done
# deal with -1 values
483D 00000000 ; CMPI32_RAX %0
0F8C %b ; JL32 %First_pass
# deal with toggle
4981FF 00000000 ; CMPI32_R15 %0
0F84 %d ; JE32 %First_pass_1
4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP
:d # :First_pass_1
49F7D7 ; NOT_R15
E9 %b ; JMP32 %First_pass
:e # :First_pass_pointer
# Deal with Pointer to label
E8 %u ; CALLI32 %Read_byte # Drop the char
4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP
E9 %b ; JMP32 %First_pass # Loop again
:f # :First_pass_done
C3 ; RET
:g # :hex
# deal with EOF
483D FCFFFFFF ; CMPI32_RAX %-4
0F84 %l ; JE32 %EOF
# deal with line comments starting with #
483D 23000000 ; CMPI32_RAX %0x23
0F84 %q ; JE32 %ascii_comment
# deal with line comments starting with ;
483D 3B000000 ; CMPI32_RAX %0x3b
0F84 %q ; JE32 %ascii_comment
# deal all ascii less than 0
483D 30000000 ; CMPI32_RAX %0x30
0F8C %p ; JL32 %ascii_other
# deal with 0-9
483D 3A000000 ; CMPI32_RAX %0x3a
0F8C %m ; JL32 %ascii_num
# deal with all ascii less than A
483D 41000000 ; CMPI32_RAX %0x41
0F8C %p ; JL32 %ascii_other
# deal with A-F
483D 47000000 ; CMPI32_RAX %0x47
0F8C %o ; JL32 %ascii_high
#deal with all ascii less than a
483D 61000000 ; CMPI32_RAX %0x61
0F8C %p ; JL32 %ascii_other
#deal with a-f
483D 67000000 ; CMPI32_RAX %0x67
0F8C %n ; JL32 %ascii_low
# The rest that remains needs to be ignored
E9 %p ; JMP32 %ascii_other
:h # :Second_pass
E8 %u ; CALLI32 %Read_byte
# Deal with EOF
483D FCFFFFFF ; CMPI32_RAX %-4
0F84 %k ; JE32 %Second_pass_done
# Simply drop the label
483D 3A000000 ; CMPI32_RAX %0x3a
0F85 %i ; JNE32 %Second_pass_0
E8 %u ; CALLI32 %Read_byte
E9 %h ; JMP32 %Second_pass
:i # :Second_pass_0
# Deal with % pointer
483D 25000000 ; CMPI32_RAX %0x25
0F85 %j ; JNE32 %Second_pass_1
E8 %z ; CALLI32 %StorePointer
E9 %h ; JMP32 %Second_pass
:j # :Second_pass_1
# Deal with everything else
E8 %g ; CALLI32 %hex # Process our char
# Deal with EOF
483D FCFFFFFF ; CMPI32_RAX %-4
0F84 %k ; JE32 %Second_pass_done
# deal with -1 values
483D 00000000 ; CMPI32_RAX %0
0F8C %h ; JL32 %Second_pass
# deal with toggle
4981FF 00000000 ; CMPI32_R15 %0
0F84 %s ; JE32 %print
# process first byte of pair
4989C6 ; COPY_RAX_to_R14
49C7C7 00000000 ; LOADI32_R15 %0
E9 %h ; JMP32 %Second_pass
:k # :Second_pass_done
C3 ; RET
:l # :EOF
C3 ; RET
:m # :ascii_num
4883E8 30 ; SUBI8_from_RAX !0x30
C3 ; RET
:n # :ascii_low
4883E8 57 ; SUBI8_from_RAX !0x57
C3 ; RET
:o # :ascii_high
4883E8 37 ; SUBI8_from_RAX !0x37
C3 ; RET
:p # :ascii_other
48C7C0 FFFFFFFF ; LOADI32_RAX %-1
C3 ; RET
:q # :ascii_comment
E8 %u ; CALLI32 %Read_byte
483D 0D000000 ; CMPI32_RAX %0xd
0F84 %r ; JE32 %ascii_comment_cr
483D 0A000000 ; CMPI32_RAX %0xa
0F85 %q ; JNE32 %ascii_comment
:r # :ascii_comment_cr
48C7C0 FFFFFFFF ; LOADI32_RAX %-1
C3 ; RET
# process second byte of pair
:s # :print
# update the sum and store in output
49C1E6 04 ; SHL8_R14 !4
4C01F0 ; ADD_R14_to_RAX
880425 46036000 ; STORE8_al_Absolute32 &table
# flip the toggle
49F7D7 ; NOT_R15
# Print our first Hex
48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want
E8 %w ; CALLI32 %print_chars
4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP
E9 %h ; JMP32 %Second_pass
:t # :Done
# program completed Successfully
48C7C7 00000000 ; LOADI32_RDI %0 # All is well
48C7C0 3C000000 ; LOADI32_RAX %0x3c # put the exit syscall number in eax
0F05 ; SYSCALL # Call it a good day
:u # :Read_byte
# Attempt to read 1 byte from STDIN
48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want
48C7C6 46036000 ; LOADI32_RSI &table # Where to put it
4C89CF ; COPY_R9_to_RDI # Where are we reading from
48C7C0 00000000 ; LOADI32_RAX %0 # the syscall number for read
0F05 ; SYSCALL # call the Kernel
4885C0 ; TEST_RAX_RAX # check what we got
0F84 %v ; JE32 %Read_byte_1 # Got EOF call it done
# load byte
8A0425 46036000 ; LOAD8_al_Absolute32 &table # load char
480FB6C0 ; MOVZBQ_RAX_AL # We have to zero extend it to use it
C3 ; RET
# Deal with EOF
:v # :Read_byte_1
48C7C0 FCFFFFFF ; LOADI32_RAX %-4 # Put EOF in rax
C3 ; RET
:w # :print_chars
48C7C6 46036000 ; LOADI32_RSI &table # What we are writing
48C7C7 01000000 ; LOADI32_RDI %1 # Stdout File Descriptor
48C7C0 01000000 ; LOADI32_RAX %1 # the syscall number for write
0F05 ; SYSCALL # call the Kernel
C3 ; RET
:x # :Get_table_target
E8 %u ; CALLI32 %Read_byte # Get single char label
48C1E0 02 ; SHL8_RAX !2 # Each label in table takes 4 bytes to store
4805 46036000 ; ADDI32_to_RAX &table # Calculate offset
C3 ; RET
:y # :StoreLabel
E8 %x ; CALLI32 %Get_table_target
4C8928 ; STORE32_R13_to_Address_in_RAX # Write out pointer to table
C3 ; RET
:z # :StorePointer
4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP
E8 %x ; CALLI32 %Get_table_target # Get address of pointer
678B00 ; LOAD32_Address_in_RAX_into_RAX # Get pointer
4C29E8 ; SUB_R13_from_RAX # target - ip
890425 46036000 ; STORE32_RAX_Absolute32 &table # put value in output
48C7C2 04000000 ; LOADI32_RDX %4 # set the size of chars we want
E8 %w ; CALLI32 %print_chars
C3 ; RET
# :table
mescc-tools-Release_1.3/test/test7/hex1_amd64.M1 0000664 0000000 0000000 00000016034 14126326331 0021336 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
DEFINE ADDI32_to_RAX 4805
DEFINE ADDI32_to_R13 4981C5
DEFINE ADD_R14_to_RAX 4C01F0
DEFINE CALLI32 E8
DEFINE CMPI32_R15 4981FF
DEFINE CMPI32_RAX 483D
DEFINE COPY_R9_to_RDI 4C89CF
DEFINE COPY_RAX_to_R14 4989C6
DEFINE COPY_RAX_to_R9 4989C1
DEFINE JE32 0F84
DEFINE JL32 0F8C
DEFINE JMP32 E9
DEFINE JNE32 0F85
DEFINE LOAD8_al_Absolute32 8A0425
DEFINE LOAD32_Address_in_RAX_into_RAX 678B00
DEFINE LOADI32_R13 49C7C5
DEFINE LOADI32_R14 49C7C6
DEFINE LOADI32_R15 49C7C7
DEFINE LOADI32_RAX 48C7C0
DEFINE LOADI32_RDI 48C7C7
DEFINE LOADI32_RDX 48C7C2
DEFINE LOADI32_RSI 48C7C6
DEFINE MOVZBQ_RAX_AL 480FB6C0
DEFINE NOT_R15 49F7D7
DEFINE POP_RAX 58
DEFINE POP_RDI 5F
DEFINE RET C3
DEFINE SHL8_R14 49C1E6
DEFINE SHL8_RAX 48C1E0
DEFINE STORE8_al_Absolute32 880425
DEFINE STORE32_RAX_Absolute32 890425
DEFINE STORE32_R13_to_Address_in_RAX 4C8928
DEFINE SUB_R13_from_RAX 4C29E8
DEFINE SUBI8_from_RAX 4883E8
DEFINE SYSCALL 0F05
DEFINE TEST_RAX_RAX 4885C0
:_start
POP_RAX # Get the number of arguments
POP_RDI # Get the program name$
POP_RDI # Get the actual input name
LOADI32_RSI %0 # prepare read_only
LOADI32_RAX %2 # the syscall number for open()
SYSCALL # Now open that damn file
COPY_RAX_to_R9 # Preserve the file pointer we were given
LOADI32_R15 %-1 # Our flag for byte processing
LOADI32_R14 %0 # temp storage for the sum
LOADI32_R13 %0 # Our starting IP
CALLI32 %First_pass # Process it
# rewind input file
COPY_R9_to_RDI # Using our input file
LOADI32_RSI %0 # Offset Zero
LOADI32_RDX %0 # Whence Zero
LOADI32_RAX %8 # lseek
SYSCALL
LOADI32_R15 %-1 # Our flag for byte processing
LOADI32_R14 %0 # temp storage for the sum
LOADI32_R13 %0 # Our starting IP
CALLI32 %Second_pass # Process it
JMP32 %Done
:First_pass
CALLI32 %Read_byte
# Deal with EOF
CMPI32_RAX %-4
JE32 %First_pass_done
# Check for :
CMPI32_RAX %0x3a
JNE32 %First_pass_0
# Deal with label
CALLI32 %StoreLabel
:First_pass_0
# Check for %
CMPI32_RAX %0x25
JE32 %First_pass_pointer
# Deal with everything else
CALLI32 %hex # Process our char
# Deal with EOF
CMPI32_RAX %-4
JE32 %First_pass_done
# deal with -1 values
CMPI32_RAX %0
JL32 %First_pass
# deal with toggle
CMPI32_R15 %0
JE32 %First_pass_1
ADDI32_to_R13 %1 # Increment IP
:First_pass_1
NOT_R15
JMP32 %First_pass
:First_pass_pointer
# Deal with Pointer to label
CALLI32 %Read_byte # Drop the char
ADDI32_to_R13 %4 # Increment IP
JMP32 %First_pass # Loop again
:First_pass_done
RET
:hex
# deal with EOF
CMPI32_RAX %-4
JE32 %EOF
# deal with line comments starting with #
CMPI32_RAX %0x23
JE32 %ascii_comment
# deal with line comments starting with ;
CMPI32_RAX %0x3b
JE32 %ascii_comment
# deal all ascii less than 0
CMPI32_RAX %0x30
JL32 %ascii_other
# deal with 0-9
CMPI32_RAX %0x3a
JL32 %ascii_num
# deal with all ascii less than A
CMPI32_RAX %0x41
JL32 %ascii_other
# deal with A-F
CMPI32_RAX %0x47
JL32 %ascii_high
#deal with all ascii less than a
CMPI32_RAX %0x61
JL32 %ascii_other
#deal with a-f
CMPI32_RAX %0x67
JL32 %ascii_low
# The rest that remains needs to be ignored
JMP32 %ascii_other
:Second_pass
CALLI32 %Read_byte
# Deal with EOF
CMPI32_RAX %-4
JE32 %Second_pass_done
# Simply drop the label
CMPI32_RAX %0x3a
JNE32 %Second_pass_0
CALLI32 %Read_byte
JMP32 %Second_pass
:Second_pass_0
# Deal with % pointer
CMPI32_RAX %0x25
JNE32 %Second_pass_1
CALLI32 %StorePointer
JMP32 %Second_pass
:Second_pass_1
# Deal with everything else
CALLI32 %hex # Process our char
# Deal with EOF
CMPI32_RAX %-4
JE32 %Second_pass_done
# deal with -1 values
CMPI32_RAX %0
JL32 %Second_pass
# deal with toggle
CMPI32_R15 %0
JE32 %print
# process first byte of pair
COPY_RAX_to_R14
LOADI32_R15 %0
JMP32 %Second_pass
:Second_pass_done
RET
:EOF
RET
:ascii_num
SUBI8_from_RAX !0x30
RET
:ascii_low
SUBI8_from_RAX !0x57
RET
:ascii_high
SUBI8_from_RAX !0x37
RET
:ascii_other
LOADI32_RAX %-1
RET
:ascii_comment
CALLI32 %Read_byte
CMPI32_RAX %0xd
JE32 %ascii_comment_cr
CMPI32_RAX %0xa
JNE32 %ascii_comment
:ascii_comment_cr
LOADI32_RAX %-1
RET
# process second byte of pair
:print
# update the sum and store in output
SHL8_R14 !4
ADD_R14_to_RAX
STORE8_al_Absolute32 &table
# flip the toggle
NOT_R15
# Print our first Hex
LOADI32_RDX %1 # set the size of chars we want
CALLI32 %print_chars
ADDI32_to_R13 %1 # Increment IP
JMP32 %Second_pass
:Done
# program completed Successfully
LOADI32_RDI %0 # All is well
LOADI32_RAX %0x3c # put the exit syscall number in eax
SYSCALL # Call it a good day
:Read_byte
# Attempt to read 1 byte from STDIN
LOADI32_RDX %1 # set the size of chars we want
LOADI32_RSI &table # Where to put it
COPY_R9_to_RDI # Where are we reading from
LOADI32_RAX %0 # the syscall number for read
SYSCALL # call the Kernel
TEST_RAX_RAX # check what we got
JE32 %Read_byte_1 # Got EOF call it done
# load byte
LOAD8_al_Absolute32 &table # load char
MOVZBQ_RAX_AL # We have to zero extend it to use it
RET
# Deal with EOF
:Read_byte_1
LOADI32_RAX %-4 # Put EOF in rax
RET
:print_chars
LOADI32_RSI &table # What we are writing
LOADI32_RDI %1 # Stdout File Descriptor
LOADI32_RAX %1 # the syscall number for write
SYSCALL # call the Kernel
RET
:Get_table_target
CALLI32 %Read_byte # Get single char label
SHL8_RAX !2 # Each label in table takes 4 bytes to store
ADDI32_to_RAX &table # Calculate offset
RET
:StoreLabel
CALLI32 %Get_table_target
STORE32_R13_to_Address_in_RAX # Write out pointer to table
RET
:StorePointer
ADDI32_to_R13 %4 # Increment IP
CALLI32 %Get_table_target # Get address of pointer
LOAD32_Address_in_RAX_into_RAX # Get pointer
SUB_R13_from_RAX # target - ip
STORE32_RAX_Absolute32 &table # put value in output
LOADI32_RDX %4 # set the size of chars we want
CALLI32 %print_chars
RET
:table
:ELF_end
mescc-tools-Release_1.3/test/test7/proof.answer 0000664 0000000 0000000 00000000123 14126326331 0021635 0 ustar 00root root 0000000 0000000 bcf188a5ea5afb1a56a716f21715d554b95f1babc679b2a9596aeeee6a7c09e3 test/test7/proof
mescc-tools-Release_1.3/test/test8/ 0000775 0000000 0000000 00000000000 14126326331 0017274 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test8/.gitignore 0000664 0000000 0000000 00000001375 14126326331 0021272 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
proof
mescc-tools-Release_1.3/test/test8/cleanup.sh 0000775 0000000 0000000 00000001373 14126326331 0021266 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test8/proof
exit 0
mescc-tools-Release_1.3/test/test8/hello.sh 0000775 0000000 0000000 00000002371 14126326331 0020741 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
{
./bin/M1 -f test/test8/sample.M1 --little-endian --architecture amd64
./bin/M1 -f test/test8/sample.M1 --big-endian --architecture amd64
./bin/M1 -f test/test8/sample.M1 --little-endian --architecture x86
./bin/M1 -f test/test8/sample.M1 --big-endian --architecture x86
} >| test/test8/proof
. ./sha256.sh
out=$(sha256_check test/test8/proof.answer)
[ "$out" = "test/test8/proof: OK" ] || exit 2
./bin/hex2 -f test/test8/proof --big-endian --architecture knight-native --base-address 0 -o test/results/test8-binary
exit 0
mescc-tools-Release_1.3/test/test8/proof.answer 0000664 0000000 0000000 00000000123 14126326331 0021636 0 ustar 00root root 0000000 0000000 e2a76ba3c64ab53b4d542c4031001df48e52861e5ab4872dda81910913a05fb4 test/test8/proof
mescc-tools-Release_1.3/test/test8/sample.M1 0000664 0000000 0000000 00000003542 14126326331 0020760 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
; 8bit tests
!0x-80 ; deal with -128
!0x-1 ; deal with -1
!0xFF ; deal with 255
!0x-0 ; deal with -0
!0x0 ; deal with 0
!-128 ; deal with -128
!-1 ; deal with -1
!255 ; deal with 255
!0 ; deal with 0
!0x12 ; Check for nybble order
!0x34 ; Check for nybble order
!0x56 ; Check for nybble order
!0x78 ; Check for nybble order
!0x90 ; Check for nybble order
; 16bit tests
@0x-8000 ; deal with -32768
@0x-1 ; deal with -1
@0xFFFF ; deal with 65535
@0x-0 ; deal with -0
@0x0 ; deal with 0
@-32768 ; deal with -32768
@-1 ; deal with -1
@65535 ; deal with 65535
@0 ; deal with 0
@0x1234 ; Check for nybble order across bytes
@0x5678 ; Check for nybble order across bytes
@0x9012 ; Check for nybble order across bytes
; 32bit tests
%0x-80000000 ; deal with -2147483648
%0x-1 ; deal with -1
%0xFFFFFFFF ; deal with 4294967295
%0x-0 ; deal with -0
%0x0 ; deal with 0
%-2147483648 ; deal with -2147483648
%-1 ; deal with -1
%4294967295 ; deal with 4294967295
%0 ; deal with 0
%0x12345678 ; Check for nybble order across bytes
%0x90123456 ; Check for nybble order across bytes
mescc-tools-Release_1.3/test/test8/test.answers 0000664 0000000 0000000 00000002745 14126326331 0021667 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
80
FF
FF
00
00
80
FF
FF
00
12
34
56
78
90
0080
FFFF
FFFF
0000
0000
0080
FFFF
FFFF
0000
3412
7856
1290
00000080
FFFFFFFF
FFFFFFFF
00000000
00000000
00000080
FFFFFFFF
FFFFFFFF
00000000
78563412
56341290
80
FF
FF
00
00
80
FF
FF
00
12
34
56
78
90
8000
FFFF
FFFF
0000
0000
8000
FFFF
FFFF
0000
1234
5678
9012
80000000
FFFFFFFF
FFFFFFFF
00000000
00000000
80000000
FFFFFFFF
FFFFFFFF
00000000
12345678
90123456
80
FF
FF
00
00
80
FF
FF
00
12
34
56
78
90
0080
FFFF
FFFF
0000
0000
0080
FFFF
FFFF
0000
3412
7856
1290
00000080
FFFFFFFF
FFFFFFFF
00000000
00000000
00000080
FFFFFFFF
FFFFFFFF
00000000
78563412
56341290
80
FF
FF
00
00
80
FF
FF
00
12
34
56
78
90
8000
FFFF
FFFF
0000
0000
8000
FFFF
FFFF
0000
1234
5678
9012
80000000
FFFFFFFF
FFFFFFFF
00000000
00000000
80000000
FFFFFFFF
FFFFFFFF
00000000
12345678
90123456
mescc-tools-Release_1.3/test/test9/ 0000775 0000000 0000000 00000000000 14126326331 0017275 5 ustar 00root root 0000000 0000000 mescc-tools-Release_1.3/test/test9/.gitignore 0000664 0000000 0000000 00000001417 14126326331 0021270 0 ustar 00root root 0000000 0000000 # Ignore the files created by script
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
proof
M1.hex2
footer.M1
mescc-tools-Release_1.3/test/test9/M1.M1 0000664 0000000 0000000 00000223253 14126326331 0017760 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
:newToken
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# struct Token *p;
# p = calloc(1, sizeof(struct Token))
mov____$i32,%eax %0x10
push___%eax
mov____$i32,%eax %0x1
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# if (0 == p) ...
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_newToken_10_break
# fprintf(2, "calloc failed.\n");
push___$i32 &string_open_0
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_newToken_10_break
:_newToken_10_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:reverse_list
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# struct Token *root = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-4
# while (0 != head) ...
jmp32 %_reverse_list_4_continue
:_reverse_list_4_loop
# struct Token *next = head->next;
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x0
# head->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-8
# head->next = root
mov____0x8(%ebp),%eax !0x-4
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# root = head
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# head = next
mov____0x8(%ebp),%eax !0x-8
mov____%eax,0x8(%ebp) !0x8
test___%eax,%eax
:_reverse_list_4_continue
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_reverse_list_4_break
jmp32 %_reverse_list_4_loop
:_reverse_list_4_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:purge_lineComment
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# int c = fgetc(source_file);
mov____0x32,%eax &source_file
push___%eax
call32 %fgetc
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-4
# while (10 != c && 13 != c) ...
jmp32 %_purge_lineComment_5_continue
:_purge_lineComment_5_loop
# c = fgetc(source_file)
mov____0x32,%eax &source_file
push___%eax
call32 %fgetc
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
:_purge_lineComment_5_continue
mov____$i32,%eax %0xa
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_purge_lineComment_5_break
mov____$i32,%eax %0xd
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_purge_lineComment_5_break
jmp32 %_purge_lineComment_5_loop
:_purge_lineComment_5_break
leave
ret
:store_atom
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# char *store = calloc(4096 + 1, sizeof(char));
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x1000
add____$i8,%eax !0x1
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
# if (0 == store) ...
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_store_atom_9_break
# fprintf(2, "Exhusted available memory\n");
push___$i32 &string_open_1
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_store_atom_9_break
:_store_atom_9_break
# int ch;
# int i = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-c
# ch = c
movzbl_0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# do 9 != ch && 10 != ch && 32 != ch && i <= 4096while (...);
:_store_atom_38_loop
# store[i] = (char)ch
mov____0x8(%ebp),%eax !0x-8
push___%eax
mov____0x8(%ebp),%eax !0x-c
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# ch = fgetc(source_file)
mov____0x32,%eax &source_file
push___%eax
call32 %fgetc
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# i = i + 1
mov____0x8(%ebp),%eax !0x-c
add____$i8,%eax !0x1
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
:_store_atom_38_continue
mov____$i32,%eax %0x9
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_store_atom_38_break
mov____$i32,%eax %0xa
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_store_atom_38_break
mov____$i32,%eax %0x20
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_store_atom_38_break
mov____0x8(%ebp),%eax !0x-c
push___%eax
mov____$i32,%eax %0x1000
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setle__%al
movzbl_%al,%eax
# jmp test LABEL
jg32 %_store_atom_38_break
jmp32 %_store_atom_38_loop
:_store_atom_38_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:store_string
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# char *store = calloc(4096 + 1, sizeof(char));
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x1000
add____$i8,%eax !0x1
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
# if (0 == store) ...
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_store_string_9_break
# fprintf(2, "Exhusted available memory\n");
push___$i32 &string_open_1
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_store_string_9_break
:_store_string_9_break
# int ch;
# int i = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-c
# ch = c
movzbl_0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# do ch != cwhile (...);
:_store_string_38_loop
# store[i] = (char)ch
mov____0x8(%ebp),%eax !0x-8
push___%eax
mov____0x8(%ebp),%eax !0x-c
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# i = i + 1
mov____0x8(%ebp),%eax !0x-c
add____$i8,%eax !0x1
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
# ch = fgetc(source_file)
mov____0x32,%eax &source_file
push___%eax
call32 %fgetc
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# if (-1 == ch) ...
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_store_string_63_break
# fprintf(2, "Unmatched \"!\n");
push___$i32 &string_open_2
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_store_string_63_break
:_store_string_63_break
# if (4096 == i) ...
mov____$i32,%eax %0x1000
push___%eax
mov____0x8(%ebp),%eax !0x-c
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_store_string_88_break
# fprintf(2, "String: %s exceeds max string size\n", store);
push___0x8(%ebp) !0x-4
push___$i32 &string_open_3
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_store_string_88_break
:_store_string_88_break
:_store_string_38_continue
mov____0x8(%ebp),%eax !0x-8
push___%eax
movzbl_0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_store_string_38_break
jmp32 %_store_string_38_loop
:_store_string_38_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:Tokenize_Line
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# int c;
:_Tokenize_Line_label_restart
# c = fgetc(source_file)
mov____0x32,%eax &source_file
push___%eax
call32 %fgetc
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# if (35 == c || 59 == c) ...
mov____$i32,%eax %0x23
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_8_break_b_9
jmp32 %_Tokenize_Line_8_break_skip_b_9
:_Tokenize_Line_8_break_b_9
mov____$i32,%eax %0x3b
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_8_break
:_Tokenize_Line_8_break_skip_b_9
# purge_lineComment();
call32 %purge_lineComment
add____$i8,%esp !0x0
test___%eax,%eax
jmp32 %_Tokenize_Line_label_restart
jmp32 %_Tokenize_Line_8_break
:_Tokenize_Line_8_break
# if ((9 == c || 10 == c) || 32 == c) ...
mov____$i32,%eax %0x9
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_32_break_b_33_b_33
jmp32 %_Tokenize_Line_32_break_b_33_skip_b_33
:_Tokenize_Line_32_break_b_33_b_33
mov____$i32,%eax %0xa
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_32_break_b_33
:_Tokenize_Line_32_break_b_33_skip_b_33
jmp32 %_Tokenize_Line_32_break_skip_b_33
:_Tokenize_Line_32_break_b_33
mov____$i32,%eax %0x20
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_32_break
:_Tokenize_Line_32_break_skip_b_33
jmp32 %_Tokenize_Line_label_restart
jmp32 %_Tokenize_Line_32_break
:_Tokenize_Line_32_break
# struct Token *p = newToken();
call32 %newToken
add____$i8,%esp !0x0
mov____%eax,0x8(%ebp) !0x-8
# if (-1 == c) ...else ...
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_66_else
# Reached_EOF = 1
mov____$i32,%eax %0x1
mov____%eax,0x32 &Reached_EOF
test___%eax,%eax
# free(p);
push___0x8(%ebp) !0x-8
call32 %free
add____$i8,%esp !0x4
test___%eax,%eax
mov____0x8(%ebp),%eax !0x8
leave
ret
jmp32 %_Tokenize_Line_66_break
:_Tokenize_Line_66_else
# if (34 == c || 39 == c) ...else ...
mov____$i32,%eax %0x22
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_90_else_b_91
jmp32 %_Tokenize_Line_90_else_skip_b_91
:_Tokenize_Line_90_else_b_91
mov____$i32,%eax %0x27
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_Tokenize_Line_90_else
:_Tokenize_Line_90_else_skip_b_91
# p->Text = store_string(c)
push___0x8(%ebp) !0x-4
call32 %store_string
add____$i8,%esp !0x4
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-8
mov____(%eax),%eax
add____$i8,%eax !0x8
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# p->type = 2
mov____$i32,%eax %0x2
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-8
mov____(%eax),%eax
add____$i8,%eax !0x4
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_Tokenize_Line_90_break
:_Tokenize_Line_90_else
# p->Text = store_atom(c)
push___0x8(%ebp) !0x-4
call32 %store_atom
add____$i8,%esp !0x4
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-8
mov____(%eax),%eax
add____$i8,%eax !0x8
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
:_Tokenize_Line_90_break
:_Tokenize_Line_66_break
# p->next = head
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-8
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
mov____0x8(%ebp),%eax !0x-8
leave
ret
:setExpression
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_setExpression_1_initial_skip
:_setExpression_1_loop
# if (i->type & 1) ...else ...
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_setExpression_7_else
jmp32 %_setExpression_1_continue
jmp32 %_setExpression_7_break
:_setExpression_7_else
# if (0 == strncmp(i->Text, match, 4096)) ...
mov____$i32,%eax %0x0
push___%eax
mov____$i32,%eax %0x1000
push___%eax
push___0x8(%ebp) !0xc
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
push___%eax
call32 %strncmp
add____$i8,%esp !0xc
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_setExpression_24_break
# i->Expression = Exp
mov____0x8(%ebp),%eax !0x10
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_setExpression_24_break
:_setExpression_24_break
:_setExpression_7_break
:_setExpression_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_setExpression_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_setExpression_1_break
jmp32 %_setExpression_1_loop
:_setExpression_1_break
leave
ret
:identify_macros
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_identify_macros_1_initial_skip
:_identify_macros_1_loop
# if (0 == strncmp(i->Text, "DEFINE", 4096)) ...
mov____$i32,%eax %0x0
push___%eax
mov____$i32,%eax %0x1000
push___%eax
push___$i32 &string_open_4
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
push___%eax
call32 %strncmp
add____$i8,%esp !0xc
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_identify_macros_7_break
# i->type = 1
mov____$i32,%eax %0x1
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# i->Text = i->next->Text
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->next->Text
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# if (i->next->next->type & 2) ...else ...
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->next->next->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x2
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_identify_macros_50_else
# i->Expression = i->next->next->Text + 1
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->next->next->Text
mov____(%eax),%eax
add____$i8,%eax !0x1
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_identify_macros_50_break
:_identify_macros_50_else
# i->Expression = i->next->next->Text
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->next->next->Text
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
:_identify_macros_50_break
# i->next = i->next->next->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next->next->next
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_identify_macros_7_break
:_identify_macros_7_break
:_identify_macros_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_identify_macros_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_identify_macros_1_break
jmp32 %_identify_macros_1_loop
:_identify_macros_1_break
leave
ret
:line_macro
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_line_macro_1_initial_skip
:_line_macro_1_loop
# if (i->type & 1) ...
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_line_macro_7_break
# setExpression(i->next, i->Text, i->Expression);
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
# i->Expression
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
push___%eax
call32 %setExpression
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_line_macro_7_break
:_line_macro_7_break
:_line_macro_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_line_macro_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_line_macro_1_break
jmp32 %_line_macro_1_loop
:_line_macro_1_break
leave
ret
:hexify_string
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, };
mov____$i32,%eax %0x30
mov____%al,0x8(%ebp) !0x-10
mov____$i32,%eax %0x31
mov____%al,0x8(%ebp) !0x-f
mov____$i32,%eax %0x32
mov____%al,0x8(%ebp) !0x-e
mov____$i32,%eax %0x33
mov____%al,0x8(%ebp) !0x-d
mov____$i32,%eax %0x34
mov____%al,0x8(%ebp) !0x-c
mov____$i32,%eax %0x35
mov____%al,0x8(%ebp) !0x-b
mov____$i32,%eax %0x36
mov____%al,0x8(%ebp) !0x-a
mov____$i32,%eax %0x37
mov____%al,0x8(%ebp) !0x-9
mov____$i32,%eax %0x38
mov____%al,0x8(%ebp) !0x-8
mov____$i32,%eax %0x39
mov____%al,0x8(%ebp) !0x-7
mov____$i32,%eax %0x41
mov____%al,0x8(%ebp) !0x-6
mov____$i32,%eax %0x42
mov____%al,0x8(%ebp) !0x-5
mov____$i32,%eax %0x43
mov____%al,0x8(%ebp) !0x-4
mov____$i32,%eax %0x44
mov____%al,0x8(%ebp) !0x-3
mov____$i32,%eax %0x45
mov____%al,0x8(%ebp) !0x-2
mov____$i32,%eax %0x46
mov____%al,0x8(%ebp) !0x-1
# int i = (strlen(p->Text + 1)/4 + 1)*8;
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x8
# p->Text
mov____(%eax),%eax
add____$i8,%eax !0x1
push___%eax
call32 %strlen
add____$i8,%esp !0x4
push___%eax
mov____$i32,%eax %0x4
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
add____$i8,%eax !0x1
push___%eax
mov____$i32,%eax %0x8
mov____%eax,%edx
pop____%eax
mul____%edx
mov____%eax,0x8(%ebp) !0x-14
# char *d = calloc(4096, sizeof(char));
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x1000
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-18
# p->Expression = d
mov____0x8(%ebp),%eax !0x-18
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# while (0 < i) ...
jmp32 %_hexify_string_70_continue
:_hexify_string_70_loop
# i = i - 1
mov____0x8(%ebp),%eax !0x-14
add____$i8,%eax !0x-1
mov____%eax,0x8(%ebp) !0x-14
test___%eax,%eax
# d[i] = 0x30
mov____$i32,%eax %0x30
push___%eax
mov____0x8(%ebp),%eax !0x-14
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x-18
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
:_hexify_string_70_continue
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-14
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_hexify_string_70_break
jmp32 %_hexify_string_70_loop
:_hexify_string_70_break
# while (i < 4096) ...
jmp32 %_hexify_string_101_continue
:_hexify_string_101_loop
# if (0 == p->Text[i + 1]) ...else ...
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-14
add____$i8,%eax !0x1
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x8
# p->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_hexify_string_104_else
# i = 4096
mov____$i32,%eax %0x1000
mov____%eax,0x8(%ebp) !0x-14
test___%eax,%eax
jmp32 %_hexify_string_104_break
:_hexify_string_104_else
# d[2*i] = table[p->Text[i + 1]/16]
mov____0x8(%ebp),%eax !0x-14
add____$i8,%eax !0x1
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x8
# p->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x2
push___%eax
mov____0x8(%ebp),%eax !0x-14
mov____%eax,%edx
pop____%eax
mul____%edx
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x-18
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# d[2*i + 1] = table[p->Text[i + 1]%16]
mov____0x8(%ebp),%eax !0x-14
add____$i8,%eax !0x1
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x8
mov____(%eax),%eax
add____$i8,%eax !0x8
# p->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x2
push___%eax
mov____0x8(%ebp),%eax !0x-14
mov____%eax,%edx
pop____%eax
mul____%edx
add____$i8,%eax !0x1
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x-18
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# i = i + 1
mov____0x8(%ebp),%eax !0x-14
add____$i8,%eax !0x1
mov____%eax,0x8(%ebp) !0x-14
test___%eax,%eax
:_hexify_string_104_break
:_hexify_string_101_continue
mov____0x8(%ebp),%eax !0x-14
push___%eax
mov____$i32,%eax %0x1000
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_hexify_string_101_break
jmp32 %_hexify_string_101_loop
:_hexify_string_101_break
leave
ret
:process_string
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_process_string_1_initial_skip
:_process_string_1_loop
# if (i->type & 2) ...
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x2
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_process_string_7_break
# if (''' == i->Text[0]) ...else ...
mov____$i32,%eax %0x27
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_process_string_21_else
# i->Expression = i->Text + 1
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
add____$i8,%eax !0x1
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_process_string_21_break
:_process_string_21_else
# if ('"' == i->Text[0]) ...
mov____$i32,%eax %0x22
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_process_string_56_break
# hexify_string(i);
push___0x8(%ebp) !0x-4
call32 %hexify_string
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_process_string_56_break
:_process_string_56_break
:_process_string_21_break
jmp32 %_process_string_7_break
:_process_string_7_break
:_process_string_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_process_string_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_process_string_1_break
jmp32 %_process_string_1_loop
:_process_string_1_break
leave
ret
:preserve_other
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_preserve_other_1_initial_skip
:_preserve_other_1_loop
# if (0 == i->Expression && !(i->type & 1)) ...
mov____$i32,%eax %0x0
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
# i->Expression
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_preserve_other_7_break
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
sete___%al
movzbl_%al,%eax
test___%eax,%eax
# jmp test LABEL
je32 %_preserve_other_7_break
# i->Expression = i->Text
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_preserve_other_7_break
:_preserve_other_7_break
:_preserve_other_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_preserve_other_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_preserve_other_1_break
jmp32 %_preserve_other_1_loop
:_preserve_other_1_break
leave
ret
:range_check
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# switch (number_of_bytes) { ...}
mov____0x8(%ebp),%eax !0xc
:_range_check_1_clause0
cmp____$i8,%eax !0x4
je32 %_range_check_1_body0
jmp32 %_range_check_1_clause1
:_range_check_1_body0
jmp32 %_range_check_1_break
jmp32 %_range_check_1_body1
:_range_check_1_clause1
cmp____$i8,%eax !0x3
je32 %_range_check_1_body1
jmp32 %_range_check_1_clause2
:_range_check_1_body1
# if (16777216 < displacement || displacement < -8388608) ...
mov____$i32,%eax %0x1000000
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_15_break_b_16
jmp32 %_range_check_15_break_skip_b_16
:_range_check_15_break_b_16
mov____0x8(%ebp),%eax !0x8
push___%eax
push___%eax
mov____$i32,%eax %0x800000
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_15_break
:_range_check_15_break_skip_b_16
# fprintf(2, "A displacement of %d does not fit in 3 bytes", displacement);
push___0x8(%ebp) !0x8
push___$i32 &string_open_5
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_range_check_15_break
:_range_check_15_break
jmp32 %_range_check_1_break
jmp32 %_range_check_1_body2
:_range_check_1_clause2
cmp____$i8,%eax !0x2
je32 %_range_check_1_body2
jmp32 %_range_check_1_clause3
:_range_check_1_body2
# if (65535 < displacement || displacement < -32768) ...
mov____$i32,%eax %0xffff
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_58_break_b_59
jmp32 %_range_check_58_break_skip_b_59
:_range_check_58_break_b_59
mov____0x8(%ebp),%eax !0x8
push___%eax
push___%eax
mov____$i32,%eax %0x8000
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_58_break
:_range_check_58_break_skip_b_59
# fprintf(2, "A displacement of %d does not fit in 2 bytes", displacement);
push___0x8(%ebp) !0x8
push___$i32 &string_open_6
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_range_check_58_break
:_range_check_58_break
jmp32 %_range_check_1_break
jmp32 %_range_check_1_body3
:_range_check_1_clause3
cmp____$i8,%eax !0x1
je32 %_range_check_1_body3
jmp32 %_range_check_1_clause4
:_range_check_1_body3
# if (255 < displacement || displacement < -128) ...
mov____$i32,%eax %0xff
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_101_break_b_102
jmp32 %_range_check_101_break_skip_b_102
:_range_check_101_break_b_102
mov____0x8(%ebp),%eax !0x8
push___%eax
push___%eax
mov____$i32,%eax %0x80
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setl___%al
movzbl_%al,%eax
# jmp test LABEL
jge32 %_range_check_101_break
:_range_check_101_break_skip_b_102
# fprintf(2, "A displacement of %d does not fit in 1 byte", displacement);
push___0x8(%ebp) !0x8
push___$i32 &string_open_7
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_range_check_101_break
:_range_check_101_break
jmp32 %_range_check_1_break
jmp32 %_range_check_1_body4
:_range_check_1_clause4
:_range_check_1_body4
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
:_range_check_1_break
leave
ret
:hex
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# if (c >= '0' && c <= '9') ...else ...
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x30
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setge__%al
movzbl_%al,%eax
# jmp test LABEL
jl32 %_hex_1_else
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x39
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setle__%al
movzbl_%al,%eax
# jmp test LABEL
jg32 %_hex_1_else
mov____0x8(%ebp),%eax !0x8
add____$i8,%eax !0x-30
leave
ret
jmp32 %_hex_1_break
:_hex_1_else
# if (c >= 'a' && c <= 'f') ...else ...
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x61
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setge__%al
movzbl_%al,%eax
# jmp test LABEL
jl32 %_hex_21_else
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x66
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setle__%al
movzbl_%al,%eax
# jmp test LABEL
jg32 %_hex_21_else
mov____0x8(%ebp),%eax !0x8
add____$i8,%eax !0x-57
leave
ret
jmp32 %_hex_21_break
:_hex_21_else
# if (c >= 'A' && c <= 'F') ...else ...
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x41
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setge__%al
movzbl_%al,%eax
# jmp test LABEL
jl32 %_hex_41_else
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x46
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setle__%al
movzbl_%al,%eax
# jmp test LABEL
jg32 %_hex_41_else
mov____0x8(%ebp),%eax !0x8
add____$i8,%eax !0x-37
leave
ret
jmp32 %_hex_41_break
:_hex_41_else
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
leave
ret
:_hex_41_break
:_hex_21_break
:_hex_1_break
leave
ret
:decimal
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# if (c >= '0' && c <= '9') ...else ...
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x30
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setge__%al
movzbl_%al,%eax
# jmp test LABEL
jl32 %_decimal_1_else
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x39
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
setle__%al
movzbl_%al,%eax
# jmp test LABEL
jg32 %_decimal_1_else
mov____0x8(%ebp),%eax !0x8
add____$i8,%eax !0x-30
leave
ret
jmp32 %_decimal_1_break
:_decimal_1_else
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
leave
ret
:_decimal_1_break
leave
ret
:numerate_string
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# int count = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-4
# int index;
# int negative;
# if (0 == a[0]) ...else ...
mov____$i32,%eax %0x0
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_6_else
mov____$i32,%eax %0x0
leave
ret
jmp32 %_numerate_string_6_break
:_numerate_string_6_else
# if (a[0] == '0' && a[1] == 'x') ...else ...
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x30
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_24_else
mov____$i32,%eax %0x1
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x78
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_24_else
# if ('-' == a[2]) ...else ...
mov____$i32,%eax %0x2d
push___%eax
mov____$i32,%eax %0x2
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_51_else
# negative = 1
mov____$i32,%eax %0x1
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
# index = 3
mov____$i32,%eax %0x3
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
jmp32 %_numerate_string_51_break
:_numerate_string_51_else
# negative = 0
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
# index = 2
mov____$i32,%eax %0x2
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
:_numerate_string_51_break
# while (0 != a[index]) ...
jmp32 %_numerate_string_84_continue
:_numerate_string_84_loop
# if (-1 == hex(a[index])) ...
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
call32 %hex
add____$i8,%esp !0x4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_87_break
mov____$i32,%eax %0x0
leave
ret
jmp32 %_numerate_string_87_break
:_numerate_string_87_break
# count = 16*count + hex(a[index])
mov____$i32,%eax %0x10
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
mul____%edx
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
call32 %hex
add____$i8,%esp !0x4
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# index = index + 1
mov____0x8(%ebp),%eax !0x-8
add____$i8,%eax !0x1
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
:_numerate_string_84_continue
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_numerate_string_84_break
jmp32 %_numerate_string_84_loop
:_numerate_string_84_break
jmp32 %_numerate_string_24_break
:_numerate_string_24_else
# if ('-' == a[0]) ...else ...
mov____$i32,%eax %0x2d
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_154_else
# negative = 1
mov____$i32,%eax %0x1
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
# index = 1
mov____$i32,%eax %0x1
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
jmp32 %_numerate_string_154_break
:_numerate_string_154_else
# negative = 0
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-c
test___%eax,%eax
# index = 0
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
:_numerate_string_154_break
# while (0 != a[index]) ...
jmp32 %_numerate_string_187_continue
:_numerate_string_187_loop
# if (-1 == decimal(a[index])) ...
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
call32 %decimal
add____$i8,%esp !0x4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_numerate_string_190_break
mov____$i32,%eax %0x0
leave
ret
jmp32 %_numerate_string_190_break
:_numerate_string_190_break
# count = 10*count + decimal(a[index])
mov____$i32,%eax %0xa
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
mul____%edx
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
call32 %decimal
add____$i8,%esp !0x4
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# index = index + 1
mov____0x8(%ebp),%eax !0x-8
add____$i8,%eax !0x1
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
:_numerate_string_187_continue
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0x8
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_numerate_string_187_break
jmp32 %_numerate_string_187_loop
:_numerate_string_187_break
:_numerate_string_24_break
:_numerate_string_6_break
# if (negative) ...
mov____0x8(%ebp),%eax !0x-c
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_numerate_string_257_break
# count = count*-1
mov____0x8(%ebp),%eax !0x-4
push___%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
mov____%eax,%edx
pop____%eax
mul____%edx
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
jmp32 %_numerate_string_257_break
:_numerate_string_257_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:LittleEndian
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, };
mov____$i32,%eax %0x30
mov____%al,0x8(%ebp) !0x-10
mov____$i32,%eax %0x31
mov____%al,0x8(%ebp) !0x-f
mov____$i32,%eax %0x32
mov____%al,0x8(%ebp) !0x-e
mov____$i32,%eax %0x33
mov____%al,0x8(%ebp) !0x-d
mov____$i32,%eax %0x34
mov____%al,0x8(%ebp) !0x-c
mov____$i32,%eax %0x35
mov____%al,0x8(%ebp) !0x-b
mov____$i32,%eax %0x36
mov____%al,0x8(%ebp) !0x-a
mov____$i32,%eax %0x37
mov____%al,0x8(%ebp) !0x-9
mov____$i32,%eax %0x38
mov____%al,0x8(%ebp) !0x-8
mov____$i32,%eax %0x39
mov____%al,0x8(%ebp) !0x-7
mov____$i32,%eax %0x41
mov____%al,0x8(%ebp) !0x-6
mov____$i32,%eax %0x42
mov____%al,0x8(%ebp) !0x-5
mov____$i32,%eax %0x43
mov____%al,0x8(%ebp) !0x-4
mov____$i32,%eax %0x44
mov____%al,0x8(%ebp) !0x-3
mov____$i32,%eax %0x45
mov____%al,0x8(%ebp) !0x-2
mov____$i32,%eax %0x46
mov____%al,0x8(%ebp) !0x-1
# switch (Number_of_bytes) { ...}
mov____0x8(%ebp),%eax !0x10
:_LittleEndian_34_clause0
cmp____$i8,%eax !0x4
je32 %_LittleEndian_34_body0
jmp32 %_LittleEndian_34_clause1
:_LittleEndian_34_body0
# c[6] = table[value<<28]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x1c
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x6
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# c[7] = table[(value<<24)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x18
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x7
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
jmp32 %_LittleEndian_34_body1
:_LittleEndian_34_clause1
cmp____$i8,%eax !0x3
je32 %_LittleEndian_34_body1
jmp32 %_LittleEndian_34_clause2
:_LittleEndian_34_body1
# c[4] = table[(value<<20)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x14
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x4
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# c[5] = table[(value<<16)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x5
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
jmp32 %_LittleEndian_34_body2
:_LittleEndian_34_clause2
cmp____$i8,%eax !0x2
je32 %_LittleEndian_34_body2
jmp32 %_LittleEndian_34_clause3
:_LittleEndian_34_body2
# c[2] = table[(value<<12)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0xc
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x2
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# c[3] = table[(value<<8)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x8
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x3
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
jmp32 %_LittleEndian_34_body3
:_LittleEndian_34_clause3
cmp____$i8,%eax !0x1
je32 %_LittleEndian_34_body3
jmp32 %_LittleEndian_34_clause4
:_LittleEndian_34_body3
# c[0] = table[(value<<4)%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x4
mov____%eax,%edx
pop____%eax
xor____%ecx,%ecx
mov____%edx,%ecx
shr____%cl,%eax
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
# c[1] = table[value%16]
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0x10
mov____%eax,%edx
pop____%eax
mov____%edx,%ebx
xor____%edx,%edx
idiv___%ebx
mov____%edx,%eax
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-10
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____%eax,%edx
pop____%eax
mov____%al,(%edx)
test___%eax,%eax
jmp32 %_LittleEndian_34_break
jmp32 %_LittleEndian_34_body4
:_LittleEndian_34_clause4
:_LittleEndian_34_body4
# fprintf(2, "Received invalid number of bytes in LittleEndian %d\n", Number_of_bytes);
push___0x8(%ebp) !0x10
push___$i32 &string_open_8
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
:_LittleEndian_34_break
mov____0x8(%ebp),%eax !0xc
leave
ret
:express_number
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# char *ch;
# if ('!' == c) ...else ...
mov____$i32,%eax %0x21
push___%eax
movzbl_0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_express_number_2_else
# range_check(value, 1);
mov____$i32,%eax %0x1
push___%eax
push___0x8(%ebp) !0x8
call32 %range_check
add____$i8,%esp !0x8
test___%eax,%eax
# ch = calloc(3, sizeof(char))
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x3
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# if (BigEndian) ...else ...
mov____0x32,%eax &BigEndian
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_express_number_24_else
# sprintf(ch, "%02X", value & 0xFF);
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0xff
mov____%eax,%edx
pop____%eax
and____%edx,%eax
push___%eax
push___$i32 &string_open_9
push___0x8(%ebp) !0x-4
call32 %sprintf
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_express_number_24_break
:_express_number_24_else
# ch = LittleEndian(value, ch, 1)
mov____$i32,%eax %0x1
push___%eax
push___0x8(%ebp) !0x-4
push___0x8(%ebp) !0x8
call32 %LittleEndian
add____$i8,%esp !0xc
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
:_express_number_24_break
jmp32 %_express_number_2_break
:_express_number_2_else
# if ('@' == c) ...else ...
mov____$i32,%eax %0x40
push___%eax
movzbl_0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_express_number_54_else
# range_check(value, 2);
mov____$i32,%eax %0x2
push___%eax
push___0x8(%ebp) !0x8
call32 %range_check
add____$i8,%esp !0x8
test___%eax,%eax
# ch = calloc(5, sizeof(char))
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x5
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# if (BigEndian) ...else ...
mov____0x32,%eax &BigEndian
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_express_number_76_else
# sprintf(ch, "%04X", value & 0xFFFF);
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0xffff
mov____%eax,%edx
pop____%eax
and____%edx,%eax
push___%eax
push___$i32 &string_open_10
push___0x8(%ebp) !0x-4
call32 %sprintf
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_express_number_76_break
:_express_number_76_else
# ch = LittleEndian(value, ch, 2)
mov____$i32,%eax %0x2
push___%eax
push___0x8(%ebp) !0x-4
push___0x8(%ebp) !0x8
call32 %LittleEndian
add____$i8,%esp !0xc
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
:_express_number_76_break
jmp32 %_express_number_54_break
:_express_number_54_else
# if ('%' == c) ...else ...
mov____$i32,%eax %0x25
push___%eax
movzbl_0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_express_number_106_else
# range_check(value, 4);
mov____$i32,%eax %0x4
push___%eax
push___0x8(%ebp) !0x8
call32 %range_check
add____$i8,%esp !0x8
test___%eax,%eax
# ch = calloc(9, sizeof(char))
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x9
push___%eax
call32 %calloc
add____$i8,%esp !0x8
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# if (BigEndian) ...else ...
mov____0x32,%eax &BigEndian
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_express_number_128_else
# sprintf(ch, "%08X", value & 0xFFFFFFFF);
mov____0x8(%ebp),%eax !0x8
push___%eax
mov____$i32,%eax %0xffffffff
mov____%eax,%edx
pop____%eax
and____%edx,%eax
push___%eax
push___$i32 &string_open_11
push___0x8(%ebp) !0x-4
call32 %sprintf
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_express_number_128_break
:_express_number_128_else
# ch = LittleEndian(value, ch, 4)
mov____$i32,%eax %0x4
push___%eax
push___0x8(%ebp) !0x-4
push___0x8(%ebp) !0x8
call32 %LittleEndian
add____$i8,%esp !0xc
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
:_express_number_128_break
jmp32 %_express_number_106_break
:_express_number_106_else
# fprintf(2, "Given symbol %c to express immediate value %d\n", c, value);
push___0x8(%ebp) !0x8
push___0x8(%ebp) !0xc
push___$i32 &string_open_12
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x10
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
:_express_number_106_break
:_express_number_54_break
:_express_number_2_break
mov____0x8(%ebp),%eax !0x-4
leave
ret
:eval_immediates
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_eval_immediates_1_initial_skip
:_eval_immediates_1_loop
# if (0 == i->Expression && !(i->type & 1)) ...
mov____$i32,%eax %0x0
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
# i->Expression
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_eval_immediates_7_break
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
and____%edx,%eax
test___%eax,%eax
sete___%al
movzbl_%al,%eax
test___%eax,%eax
# jmp test LABEL
je32 %_eval_immediates_7_break
# int value;
# switch (Architecture) { ...}
mov____0x32,%eax &Architecture
:_eval_immediates_34_clause0
cmp____$i8,%eax !0x2
je32 %_eval_immediates_34_body0
cmp____$i8,%eax !0x1
je32 %_eval_immediates_34_body0
jmp32 %_eval_immediates_34_clause1
:_eval_immediates_34_body0
# value = numerate_string(i->Text + 1)
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
add____$i8,%eax !0x1
push___%eax
call32 %numerate_string
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# if ('0' == i->Text[1] || 0 != value) ...
mov____$i32,%eax %0x30
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_eval_immediates_54_break_b_55
jmp32 %_eval_immediates_54_break_skip_b_55
:_eval_immediates_54_break_b_55
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_eval_immediates_54_break
:_eval_immediates_54_break_skip_b_55
# i->Expression = express_number(value, i->Text[0])
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
push___%eax
push___0x8(%ebp) !0x-8
call32 %express_number
add____$i8,%esp !0x8
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
jmp32 %_eval_immediates_54_break
:_eval_immediates_54_break
jmp32 %_eval_immediates_34_break
jmp32 %_eval_immediates_34_body1
:_eval_immediates_34_clause1
cmp____$i8,%eax !0x0
je32 %_eval_immediates_34_body1
jmp32 %_eval_immediates_34_break
:_eval_immediates_34_body1
# value = numerate_string(i->Text)
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
push___%eax
call32 %numerate_string
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-8
test___%eax,%eax
# if ('0' == i->Text[0] || 0 != value) ...
mov____$i32,%eax %0x30
push___%eax
mov____$i32,%eax %0x0
mov____%eax,%edx
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x8
# i->Text
mov____(%eax),%eax
mov____%eax,%edx
pop____%eax
add____%edx,%eax
movzbl_(%eax),%eax
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_eval_immediates_124_break_b_125
jmp32 %_eval_immediates_124_break_skip_b_125
:_eval_immediates_124_break_b_125
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-8
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_eval_immediates_124_break
:_eval_immediates_124_break_skip_b_125
# range_check(value, 2);
mov____$i32,%eax %0x2
push___%eax
push___0x8(%ebp) !0x-8
call32 %range_check
add____$i8,%esp !0x8
test___%eax,%eax
# i->Expression = calloc(5, sizeof(char))
mov____$i32,%eax %0x1
push___%eax
mov____$i32,%eax %0x5
push___%eax
call32 %calloc
add____$i8,%esp !0x8
push___%eax
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
mov____%eax,%edx
pop____%eax
mov____%eax,(%edx)
test___%eax,%eax
# sprintf(i->Expression, "%04X", value);
push___0x8(%ebp) !0x-8
push___$i32 &string_open_10
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
# i->Expression
mov____(%eax),%eax
push___%eax
call32 %sprintf
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_eval_immediates_124_break
:_eval_immediates_124_break
jmp32 %_eval_immediates_34_break
:_eval_immediates_34_break
jmp32 %_eval_immediates_7_break
:_eval_immediates_7_break
:_eval_immediates_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_eval_immediates_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_eval_immediates_1_break
jmp32 %_eval_immediates_1_loop
:_eval_immediates_1_break
leave
ret
:print_hex
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# for (struct Token *i = p; 0 != i; i = i->next) ...
# struct Token *i = p;
mov____0x8(%ebp),%eax !0x8
mov____%eax,0x8(%ebp) !0x-4
jmp32 %_print_hex_1_initial_skip
:_print_hex_1_loop
# if (i->type ^ 1) ...
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x4
# i->type
mov____(%eax),%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
xor____%edx,%eax
test___%eax,%eax
# jmp test LABEL
test___%eax,%eax
je32 %_print_hex_7_break
# fprintf(destination_file, "\n%s", i->Expression);
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0xc
# i->Expression
mov____(%eax),%eax
push___%eax
push___$i32 &string_open_13
mov____0x32,%eax &destination_file
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
jmp32 %_print_hex_7_break
:_print_hex_7_break
:_print_hex_1_continue
# i = i->next
mov____%ebp,%eax
add____$i8,%eax !0x-4
mov____(%eax),%eax
add____$i8,%eax !0x0
# i->next
mov____(%eax),%eax
mov____%eax,0x8(%ebp) !0x-4
:_print_hex_1_initial_skip
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_print_hex_1_break
jmp32 %_print_hex_1_loop
:_print_hex_1_break
# fprintf(destination_file, "\n");
push___$i32 &string_open_14
mov____0x32,%eax &destination_file
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
leave
ret
:main
push___%ebp
mov____%esp,%ebp
sub____%esp,$i32 %0x1054
# BigEndian = 0
mov____$i32,%eax %0x0
mov____%eax,0x32 &BigEndian
test___%eax,%eax
# struct Token *head = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-4
# Architecture = 0
mov____$i32,%eax %0x0
mov____%eax,0x32 &Architecture
test___%eax,%eax
# destination_file = 1
mov____$i32,%eax %0x1
mov____%eax,0x32 &destination_file
test___%eax,%eax
# int c;
# int option_index = 0;
mov____$i32,%eax %0x0
mov____%eax,0x8(%ebp) !0x-c
# while ((c = getopt_long(argc, argv, "f:h:o:V", long_options, &option_index)) != -1) ...
jmp32 %_main_20_continue
:_main_20_loop
# switch (c) { ...}
mov____0x8(%ebp),%eax !0x-8
:_main_23_clause0
cmp____$i8,%eax !0x0
je32 %_main_23_body0
jmp32 %_main_23_clause1
:_main_23_body0
jmp32 %_main_23_break
jmp32 %_main_23_body1
:_main_23_clause1
cmp____$i8,%eax !0x41
je32 %_main_23_body1
jmp32 %_main_23_clause2
:_main_23_body1
# Architecture = atoi(optarg)
mov____0x32,%eax &optarg
push___%eax
call32 %atoi
add____$i8,%esp !0x4
mov____%eax,0x32 &Architecture
test___%eax,%eax
jmp32 %_main_23_break
jmp32 %_main_23_body2
:_main_23_clause2
cmp____$i8,%eax !0x68
je32 %_main_23_body2
jmp32 %_main_23_clause3
:_main_23_body2
# fprintf(2, "Usage: %s -f FILENAME1 {-f FILENAME2} (--BigEndian|--LittleEndian) [--BaseAddress 12345] [--Architecture 12345]\n" , argv[0]);
mov____$i32,%eax %0x0
shl____$i8,%eax !0x2
push___%eax
mov____0x8(%ebp),%eax !0xc
mov____%eax,%edx
pop____%eax
add____%edx,%eax
mov____(%eax),%eax
push___%eax
push___$i32 &string_open_22
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0xc
test___%eax,%eax
# fprintf(2, "Architecture 0: Knight; 1: x86; 2: AMD64");
push___$i32 &string_open_23
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(0);
mov____$i32,%eax %0x0
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_main_23_body3
:_main_23_clause3
cmp____$i8,%eax !0x66
je32 %_main_23_body3
jmp32 %_main_23_clause4
:_main_23_body3
# source_file = open(optarg, 0)
mov____$i32,%eax %0x0
push___%eax
mov____0x32,%eax &optarg
push___%eax
call32 %open
add____$i8,%esp !0x8
mov____%eax,0x32 &source_file
test___%eax,%eax
# Reached_EOF = 0
mov____$i32,%eax %0x0
mov____%eax,0x32 &Reached_EOF
test___%eax,%eax
# while (!Reached_EOF) ...
jmp32 %_main_91_continue
:_main_91_loop
# head = Tokenize_Line(head)
push___0x8(%ebp) !0x-4
call32 %Tokenize_Line
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
:_main_91_continue
mov____0x32,%eax &Reached_EOF
test___%eax,%eax
sete___%al
movzbl_%al,%eax
test___%eax,%eax
# jmp test LABEL
je32 %_main_91_break
jmp32 %_main_91_loop
:_main_91_break
jmp32 %_main_23_break
jmp32 %_main_23_body4
:_main_23_clause4
cmp____$i8,%eax !0x6f
je32 %_main_23_body4
jmp32 %_main_23_clause5
:_main_23_body4
# destination_file = open(optarg, (64 | 512) | 1, 00400 | 00200)
mov____$i32,%eax %0x100
push___%eax
mov____$i32,%eax %0x80
mov____%eax,%edx
pop____%eax
or_____%edx,%eax
push___%eax
mov____$i32,%eax %0x40
push___%eax
mov____$i32,%eax %0x200
mov____%eax,%edx
pop____%eax
or_____%edx,%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
or_____%edx,%eax
push___%eax
mov____0x32,%eax &optarg
push___%eax
call32 %open
add____$i8,%esp !0xc
mov____%eax,0x32 &destination_file
test___%eax,%eax
jmp32 %_main_23_break
jmp32 %_main_23_body5
:_main_23_clause5
cmp____$i8,%eax !0x56
je32 %_main_23_body5
jmp32 %_main_23_clause6
:_main_23_body5
# fprintf(1, "M1 0.3\n");
push___$i32 &string_open_24
mov____$i32,%eax %0x1
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(0);
mov____$i32,%eax %0x0
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_main_23_body6
:_main_23_clause6
:_main_23_body6
# fprintf(2, "Unknown option\n");
push___$i32 &string_open_25
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
:_main_23_break
:_main_20_continue
# c = getopt_long(argc, argv, "f:h:o:V", long_options, &option_index)
lea____0x8(%ebp),%eax !0x-c
push___%eax
push___$i32 &long_options
push___$i32 &string_open_26
push___0x8(%ebp) !0xc
push___0x8(%ebp) !0x8
call32 %getopt_long
add____$i8,%esp !0x14
mov____%eax,0x8(%ebp) !0x-8
push___%eax
push___%eax
mov____$i32,%eax %0x1
mov____%eax,%edx
pop____%eax
mov____$i32,%eax %0x0
sub____%edx,%eax
mov____%eax,%edx
pop____%eax
push___%eax
sub____%edx,%eax
setne__%al
movzbl_%al,%eax
xchg___%eax,(%esp)
sub____%edx,%eax
lahf
xor____$i8,%ah !0x40
sahf
pop____%eax
# jmp test LABEL
jne32 %_main_20_break
jmp32 %_main_20_loop
:_main_20_break
# if (0 == head) ...
mov____$i32,%eax %0x0
push___%eax
mov____0x8(%ebp),%eax !0x-4
mov____%eax,%edx
pop____%eax
sub____%edx,%eax
sete___%al
movzbl_%al,%eax
# jmp test LABEL
jne32 %_main_190_break
# fprintf(2, "Either no input files were given or they were empty\n");
push___$i32 &string_open_27
mov____$i32,%eax %0x2
push___%eax
call32 %fprintf
add____$i8,%esp !0x8
test___%eax,%eax
# exit(1);
mov____$i32,%eax %0x1
push___%eax
call32 %exit
add____$i8,%esp !0x4
test___%eax,%eax
jmp32 %_main_190_break
:_main_190_break
# head = reverse_list(head)
push___0x8(%ebp) !0x-4
call32 %reverse_list
add____$i8,%esp !0x4
mov____%eax,0x8(%ebp) !0x-4
test___%eax,%eax
# identify_macros(head);
push___0x8(%ebp) !0x-4
call32 %identify_macros
add____$i8,%esp !0x4
test___%eax,%eax
# line_macro(head);
push___0x8(%ebp) !0x-4
call32 %line_macro
add____$i8,%esp !0x4
test___%eax,%eax
# process_string(head);
push___0x8(%ebp) !0x-4
call32 %process_string
add____$i8,%esp !0x4
test___%eax,%eax
# eval_immediates(head);
push___0x8(%ebp) !0x-4
call32 %eval_immediates
add____$i8,%esp !0x4
test___%eax,%eax
# preserve_other(head);
push___0x8(%ebp) !0x-4
call32 %preserve_other
add____$i8,%esp !0x4
test___%eax,%eax
# print_hex(head);
push___0x8(%ebp) !0x-4
call32 %print_hex
add____$i8,%esp !0x4
test___%eax,%eax
mov____$i32,%eax %0x0
leave
ret
:ELF_data
:HEX2_data
:g_environment
!0x00 !0x00 !0x00 !0x00
:g_stdin
!0x00 !0x00 !0x00 !0x00
:g_stdout
!0x00 !0x00 !0x00 !0x00
:optarg
!0x00 !0x00 !0x00 !0x00
:optind
!0x00 !0x00 !0x00 !0x00
:opterr
!0x00 !0x00 !0x00 !0x00
:source_file
!0x00 !0x00 !0x00 !0x00
:destination_file
!0x00 !0x00 !0x00 !0x00
:Reached_EOF
!0x00 !0x00 !0x00 !0x00
:BigEndian
!0x00 !0x00 !0x00 !0x00
:Architecture
!0x00 !0x00 !0x00 !0x00
:string_open_0
"calloc failed.
"
:string_open_1
"Exhusted available memory
"
:string_open_2
!0x55 !0x6e !0x6d !0x61 !0x74 !0x63 !0x68 !0x65 !0x64 !0x20 !0x22 !0x21 !0x0a !0x00
:string_open_3
"String: %s exceeds max string size
"
:string_open_4
"DEFINE"
:string_open_5
"A displacement of %d does not fit in 3 bytes"
:string_open_6
"A displacement of %d does not fit in 2 bytes"
:string_open_7
"A displacement of %d does not fit in 1 byte"
:string_open_8
"Received invalid number of bytes in LittleEndian %d
"
:string_open_9
"%02X"
:string_open_10
"%04X"
:string_open_11
"%08X"
:string_open_12
"Given symbol %c to express immediate value %d
"
:string_open_13
"
%s"
:string_open_14
"
"
:string_open_15
"Architecture"
:string_open_16
"BigEndian"
:string_open_17
"LittleEndian"
:string_open_18
"file"
:string_open_19
"output"
:string_open_20
"help"
:string_open_21
"version"
:long_options
&string_open_15 !0x01 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x41 !0x00 !0x00 !0x00 &string_open_16 !0x00 !0x00 !0x00 !0x00 &BigEndian !0x01 !0x00 !0x00 !0x00 &string_open_17 !0x00 !0x00 !0x00 !0x00 &BigEndian !0x00 !0x00 !0x00 !0x00 &string_open_18 !0x01 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x66 !0x00 !0x00 !0x00 &string_open_19 !0x01 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x6f !0x00 !0x00 !0x00 &string_open_20 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x68 !0x00 !0x00 !0x00 &string_open_21 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x56 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00 !0x00
:string_open_22
!0x55 !0x73 !0x61 !0x67 !0x65 !0x3a !0x20 !0x25 !0x73 !0x20 !0x2d !0x66 !0x20 !0x46 !0x49 !0x4c !0x45 !0x4e !0x41 !0x4d !0x45 !0x31 !0x20 !0x7b !0x2d !0x66 !0x20 !0x46 !0x49 !0x4c !0x45 !0x4e !0x41 !0x4d !0x45 !0x32 !0x7d !0x20 !0x28 !0x2d !0x2d !0x42 !0x69 !0x67 !0x45 !0x6e !0x64 !0x69 !0x61 !0x6e !0x7c !0x2d !0x2d !0x4c !0x69 !0x74 !0x74 !0x6c !0x65 !0x45 !0x6e !0x64 !0x69 !0x61 !0x6e !0x29 !0x20 !0x5b !0x2d !0x2d !0x42 !0x61 !0x73 !0x65 !0x41 !0x64 !0x64 !0x72 !0x65 !0x73 !0x73 !0x20 !0x31 !0x32 !0x33 !0x34 !0x35 !0x5d !0x20 !0x5b !0x2d !0x2d !0x41 !0x72 !0x63 !0x68 !0x69 !0x74 !0x65 !0x63 !0x74 !0x75 !0x72 !0x65 !0x20 !0x31 !0x32 !0x33 !0x34 !0x35 !0x5d !0x0a !0x00
:string_open_23
"Architecture 0: Knight; 1: x86; 2: AMD64"
:string_open_24
"M1 0.3
"
:string_open_25
"Unknown option
"
:string_open_26
"f:h:o:V"
:string_open_27
"Either no input files were given or they were empty
"
mescc-tools-Release_1.3/test/test9/cleanup.sh 0000775 0000000 0000000 00000001430 14126326331 0021261 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
rm -f test/test9/M1.hex2
rm -f test/test9/footer.M1
exit 0
mescc-tools-Release_1.3/test/test9/crt1.hex2 0000664 0000000 0000000 00000001616 14126326331 0020742 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
:_start
55
89e5
81ec
54100000
89e8
83c0
04
0fb600
83c0
03
c1e0
02
01e8
a3
&g_environment
89e8
83c0
08
50
89e8
83c0
04
0fb600
50
e8
%main
83c4
00
85c0
89c3
b8
01000000
cd80
f4
c9
c3
:g_environment
00
00
00
00
mescc-tools-Release_1.3/test/test9/hello.sh 0000775 0000000 0000000 00000005341 14126326331 0020742 0 ustar 00root root 0000000 0000000 #! /bin/sh
## Copyright (C) 2017 Jeremiah Orians
## This file is part of mescc-tools.
##
## mescc-tools is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## mescc-tools is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with mescc-tools. If not, see .
set -ex
./bin/blood-elf -f test/test9/M1.M1 \
--entry exit \
--entry read \
--entry write \
--entry open \
--entry chmod \
--entry access \
--entry brk \
--entry fsync \
--entry strlen \
--entry eputc \
--entry eputs \
--entry fputs \
--entry puts \
--entry putchar \
--entry fputc \
--entry getchar \
--entry fgetc \
--entry free \
--entry ungetc \
--entry strcmp \
--entry strcpy \
--entry itoa \
--entry isdigit \
--entry isxdigit \
--entry isnumber \
--entry atoi \
--entry malloc \
--entry memcpy \
--entry realloc \
--entry strncmp \
--entry getenv \
--entry vprintf \
--entry printf \
--entry vsprintf \
--entry sprintf \
--entry getopt \
--entry close \
--entry unlink \
--entry lseek \
--entry getcwd \
--entry dlclose \
--entry dlopen \
--entry execvp \
--entry fclose \
--entry fdopen \
--entry ferror \
--entry fflush \
--entry fopen \
--entry fprintf \
--entry fread \
--entry fseek \
--entry ftell \
--entry fwrite \
--entry gettimeofday \
--entry localtime \
--entry longjmp \
--entry memmove \
--entry memset \
--entry memcmp \
--entry mprotect \
--entry qsort \
--entry remove \
--entry setjmp \
--entry sigaction \
--entry sigemptyset \
--entry snprintf \
--entry sscanf \
--entry strcat \
--entry strchr \
--entry strrchr \
--entry strstr \
--entry strtol \
--entry strtoll \
--entry strtoul \
--entry strtoull \
--entry time \
--entry vsnprintf \
--entry calloc \
--entry vfprintf \
--entry buf \
--entry optarg \
--entry optind \
--entry opterr \
--entry optarg \
--entry optind \
--entry nextchar \
--entry opterr \
--entry errno \
--entry _start \
--little-endian \
-o test/test9/footer.M1
./bin/M1 --little-endian --architecture x86 -f test/test9/x86.M1 -f test/test9/M1.M1 -f test/test9/footer.M1 -o test/test9/M1.hex2
./bin/hex2 --little-endian --architecture x86 --base-address 0x1000000 -f elf_headers/elf32-debug.hex2 -f test/test9/crt1.hex2 -f test/test9/libc-mes+tcc.hex2 -f test/test9/M1.hex2 -o test/results/test9-binary
exit 0
mescc-tools-Release_1.3/test/test9/libc-mes+tcc.hex2 0000664 0000000 0000000 00000112502 14126326331 0022326 0 ustar 00root root 0000000 0000000 ## Copyright (C) 2017 Jeremiah Orians
## This file is part of stage0.
##
## stage0 is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## stage0 is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with stage0. If not, see .
:exit
55
89e5
81ec
54100000
8b5d
08
b8
01000000
cd80
c9
c3
:read
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
8b55
10
b8
03000000
cd80
c9
c3
:write
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
8b55
10
b8
04000000
cd80
c9
c3
:open
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
8b55
10
b8
05000000
cd80
c9
c3
:chmod
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
b8
0f000000
cd80
c9
c3
:access
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
b8
21000000
cd80
c9
c3
:brk
55
89e5
81ec
54100000
8b5d
08
b8
2d000000
cd80
c9
c3
:fsync
55
89e5
81ec
54100000
8b5d
08
b8
76000000
cd80
c9
c3
:strlen
55
89e5
81ec
54100000
b8
00000000
8945
FC
e9
%strlen_4_continue
:strlen_4_loop
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
:strlen_4_continue
8b45
FC
89c2
50
8b45
08
89c2
58
01d0
0fb600
85c0
85c0
84c0
0f84
%strlen_4_break
e9
%strlen_4_loop
:strlen_4_break
8b45
FC
c9
c3
:eputc
55
89e5
81ec
54100000
b8
02000000
50
ff75
08
e8
%fputc
83c4
08
c9
c3
:eputs
55
89e5
81ec
54100000
ff75
08
e8
%strlen
83c4
04
8945
FC
ff75
FC
ff75
08
b8
02000000
50
e8
%write
83c4
0C
85c0
b8
00000000
c9
c3
:fputs
55
89e5
81ec
54100000
ff75
08
e8
%strlen
83c4
04
8945
FC
ff75
FC
ff75
08
ff75
0C
e8
%write
83c4
0C
85c0
b8
00000000
c9
c3
:puts
55
89e5
81ec
54100000
ff75
08
e8
%strlen
83c4
04
8945
FC
ff75
FC
ff75
08
b8
01000000
50
e8
%write
83c4
0C
85c0
b8
00000000
c9
c3
:putchar
55
89e5
81ec
54100000
b8
01000000
50
8d45
08
50
b8
01000000
50
e8
%write
83c4
0C
85c0
b8
00000000
c9
c3
:fputc
55
89e5
81ec
54100000
b8
01000000
50
8d45
08
50
ff75
0C
e8
%write
83c4
0C
85c0
b8
00000000
c9
c3
:assert_fail
55
89e5
81ec
54100000
68
&string_getopt_long_0
e8
%eputs
83c4
04
85c0
ff75
08
e8
%eputs
83c4
04
85c0
68
&string_getopt_long_1
e8
%eputs
83c4
04
85c0
8b45
08
8945
FC
b8
00000000
8945
FC
85c0
b8
00000000
50
8b45
FC
89c2
58
8802
85c0
c9
c3
:getchar
55
89e5
81ec
54100000
a1
&ungetc_char
50
50
b8
01000000
89c2
58
b8
00000000
29d0
89c2
58
29d0
0f94c0
0fb6c0
0f85
%getchar_3_else
b8
01000000
50
8d45
FC
50
a1
&g_stdin
50
e8
%read
83c4
0C
8945
F4
8b45
F4
50
b8
01000000
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%getchar_22_break
50
b8
01000000
89c2
58
b8
00000000
29d0
c9
c3
e9
%getchar_22_break
:getchar_22_break
0fb645
FC
8945
F8
85c0
e9
%getchar_3_break
:getchar_3_else
a1
&ungetc_char
89c2
50
b8
&ungetc_buf
89c2
58
01d0
0fb600
8945
F8
85c0
a1
&ungetc_char
83c0
FF
a3
&ungetc_char
85c0
:getchar_3_break
8b45
F8
50
b8
00000000
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%getchar_60_break
b8
00010000
50
8b45
F8
5a
01d0
8945
F8
85c0
e9
%getchar_60_break
:getchar_60_break
8b45
F8
c9
c3
:fgetc
55
89e5
81ec
54100000
b8
01000000
50
8d45
FC
50
ff75
08
e8
%read
83c4
0C
8945
F4
8b45
F4
50
b8
01000000
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%fgetc_10_break
50
b8
01000000
89c2
58
b8
00000000
29d0
c9
c3
e9
%fgetc_10_break
:fgetc_10_break
0fb645
FC
8945
F8
85c0
8b45
F8
c9
c3
:free
55
89e5
81ec
54100000
c9
c3
:ungetc
55
89e5
81ec
54100000
a1
&ungetc_char
50
b8
&ungetc_char
8300
01
58
85c0
8b45
08
50
a1
&ungetc_char
89c2
50
b8
&ungetc_buf
89c2
58
01d0
89c2
58
8802
85c0
8b45
08
c9
c3
:strcmp
55
89e5
81ec
54100000
e9
%strcmp_1_continue
:strcmp_1_loop
8b45
08
50
89e8
83c0
08
8300
01
58
85c0
8b45
0C
50
89e8
83c0
0C
8300
01
58
85c0
:strcmp_1_continue
8b45
08
0fb600
85c0
85c0
84c0
0f84
%strcmp_1_break
8b45
0C
0fb600
85c0
85c0
84c0
0f84
%strcmp_1_break
8b45
08
0fb600
50
8b45
0C
0fb600
89c2
58
29d0
0f94c0
0fb6c0
0f85
%strcmp_1_break
e9
%strcmp_1_loop
:strcmp_1_break
8b45
08
0fb600
50
8b45
0C
0fb600
89c2
58
29d0
c9
c3
:strcpy
55
89e5
81ec
54100000
8b45
08
8945
FC
e9
%strcpy_4_continue
:strcpy_4_loop
8b45
0C
50
89e8
83c0
0C
8300
01
58
0fb600
50
8b45
FC
89c2
58
8802
8345
FC
01
85c0
:strcpy_4_continue
8b45
0C
0fb600
85c0
85c0
84c0
0f84
%strcpy_4_break
e9
%strcpy_4_loop
:strcpy_4_break
b8
00000000
50
8b45
FC
89c2
58
8802
85c0
8b45
08
c9
c3
:itoa
55
89e5
81ec
54100000
b8
&itoa_buf
8945
FC
b8
09000000
50
8b45
FC
5a
01d0
8945
FC
85c0
b8
00000000
50
8b45
FC
89c2
58
8802
8345
FC
FF
85c0
b8
00000000
8945
F8
8b45
08
50
b8
00000000
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%itoa_24_break
b8
01000000
8945
F8
85c0
e9
%itoa_24_break
:itoa_24_break
8b45
F8
85c0
85c0
0f84
%itoa_38_break
50
8b45
08
89c2
58
b8
00000000
29d0
8945
08
85c0
e9
%itoa_38_break
:itoa_38_break
:itoa_54_loop
b8
30000000
50
8b45
08
50
b8
0A000000
89c2
58
89d3
31d2
f7fb
89d0
89c2
58
01d0
50
8b45
FC
89c2
58
8802
8345
FC
FF
85c0
8b45
08
50
b8
0A000000
89c2
58
89d3
31d2
f7fb
8945
08
85c0
:itoa_54_continue
8b45
08
85c0
85c0
0f84
%itoa_54_break
e9
%itoa_54_loop
:itoa_54_break
8b45
F8
85c0
85c0
0f84
%itoa_89_break
8b45
FC
83c0
01
0fb600
50
b8
30000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%itoa_89_break
b8
2D000000
50
8b45
FC
89c2
58
8802
8345
FC
FF
85c0
e9
%itoa_89_break
:itoa_89_break
8b45
FC
83c0
01
c9
c3
:isdigit
55
89e5
81ec
54100000
8b45
08
50
b8
30000000
89c2
58
29d0
0f9dc0
0fb6c0
85c0
0f84
%isdigit_6_and_skip_b
85c0
8b45
08
50
b8
39000000
89c2
58
29d0
0f9ec0
0fb6c0
85c0
:isdigit_6_and_skip_b
c9
c3
:isxdigit
55
89e5
81ec
54100000
ff75
08
e8
%isdigit
83c4
04
85c0
0f85
%isxdigit_3_or_skip_b
85c0
8b45
08
50
b8
61000000
89c2
58
29d0
0f9dc0
0fb6c0
85c0
0f84
%isxdigit_11_and_skip_b
85c0
8b45
08
50
b8
66000000
89c2
58
29d0
0f9ec0
0fb6c0
85c0
:isxdigit_11_and_skip_b
85c0
:isxdigit_3_or_skip_b
c9
c3
:isnumber
55
89e5
81ec
54100000
8b45
0C
50
b8
02000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%isnumber_1_break
8b45
08
50
b8
30000000
89c2
58
29d0
0f9dc0
0fb6c0
85c0
0f84
%isnumber_14_and_skip_b
85c0
8b45
08
50
b8
31000000
89c2
58
29d0
0f9ec0
0fb6c0
85c0
:isnumber_14_and_skip_b
c9
c3
e9
%isnumber_1_break
:isnumber_1_break
8b45
0C
50
b8
08000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%isnumber_27_break
8b45
08
50
b8
30000000
89c2
58
29d0
0f9dc0
0fb6c0
85c0
0f84
%isnumber_40_and_skip_b
85c0
8b45
08
50
b8
37000000
89c2
58
29d0
0f9ec0
0fb6c0
85c0
:isnumber_40_and_skip_b
c9
c3
e9
%isnumber_27_break
:isnumber_27_break
8b45
0C
50
b8
0A000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%isnumber_53_break
ff75
08
e8
%isdigit
83c4
04
c9
c3
e9
%isnumber_53_break
:isnumber_53_break
8b45
0C
50
b8
10000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%isnumber_66_break
ff75
08
e8
%isxdigit
83c4
04
c9
c3
e9
%isnumber_66_break
:isnumber_66_break
c9
c3
:_atoi
55
89e5
81ec
54100000
8b45
08
8b00
8945
FC
b8
00000000
8945
F8
b8
01000000
8945
F4
8b45
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%_atoi_11_break
b8
0A000000
8945
0C
85c0
e9
%_atoi_11_break
:_atoi_11_break
8b45
FC
0fb600
85c0
85c0
84c0
0f84
%_atoi_24_break
8b45
FC
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_atoi_24_break
50
b8
01000000
89c2
58
b8
00000000
29d0
8945
F4
85c0
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
e9
%_atoi_24_break
:_atoi_24_break
e9
%_atoi_55_continue
:_atoi_55_loop
8b45
0C
50
8b45
F8
5a
f7e2
8945
F8
85c0
8b45
FC
0fb600
50
b8
39000000
89c2
58
29d0
0f9fc0
0fb6c0
85c0
0f8e
%_atoi_67_else
b8
61000000
83c0
F6
85c0
e9
%_atoi_67_break
:_atoi_67_else
b8
30000000
85c0
:_atoi_67_break
8945
F0
8b45
FC
0fb600
50
8b45
F0
89c2
58
29d0
50
8b45
F8
5a
01d0
8945
F8
85c0
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
:_atoi_55_continue
ff75
0C
8b45
FC
0fb600
50
e8
%isnumber
83c4
08
85c0
85c0
0f84
%_atoi_55_break
e9
%_atoi_55_loop
:_atoi_55_break
8b45
FC
50
8b45
08
89c2
58
8902
85c0
8b45
F8
50
8b45
F4
89c2
58
f7e2
c9
c3
:atoi
55
89e5
81ec
54100000
8b45
08
8945
FC
b8
00000000
50
8d45
FC
50
e8
%_atoi
83c4
08
c9
c3
:malloc
55
89e5
81ec
54100000
a1
&g_brk
85c0
0f94c0
0fb6c0
85c0
0f84
%malloc_1_break
b8
00000000
50
e8
%brk
83c4
04
a3
&g_brk
85c0
e9
%malloc_1_break
:malloc_1_break
a1
&g_brk
50
8b45
08
89c2
58
01d0
50
e8
%brk
83c4
04
50
50
b8
01000000
89c2
58
b8
00000000
29d0
89c2
58
29d0
0f94c0
0fb6c0
0f85
%malloc_16_break
b8
00000000
c9
c3
e9
%malloc_16_break
:malloc_16_break
a1
&g_brk
8945
FC
8b45
08
50
a1
&g_brk
5a
01d0
a3
&g_brk
85c0
8b45
FC
c9
c3
:memcpy
55
89e5
81ec
54100000
8b45
08
8945
FC
8b45
0C
8945
F8
e9
%memcpy_7_continue
:memcpy_7_loop
8b45
F8
50
89e8
83c0
F8
8300
01
58
0fb600
50
8b45
FC
89c2
58
8802
8345
FC
01
85c0
:memcpy_7_continue
8b45
10
50
89e8
83c0
10
8300
FF
58
85c0
85c0
0f84
%memcpy_7_break
e9
%memcpy_7_loop
:memcpy_7_break
8b45
08
c9
c3
:realloc
55
89e5
81ec
54100000
ff75
0C
e8
%malloc
83c4
04
8945
FC
8b45
08
85c0
85c0
0f84
%realloc_5_break
8b45
FC
85c0
85c0
0f84
%realloc_5_break
ff75
0C
ff75
08
ff75
FC
e8
%memcpy
83c4
0C
85c0
ff75
08
e8
%free
83c4
04
85c0
e9
%realloc_5_break
:realloc_5_break
8b45
FC
c9
c3
:strncmp
55
89e5
81ec
54100000
e9
%strncmp_1_continue
:strncmp_1_loop
8b45
08
50
89e8
83c0
08
8300
01
58
85c0
8b45
0C
50
89e8
83c0
0C
8300
01
58
85c0
:strncmp_1_continue
8b45
08
0fb600
85c0
85c0
84c0
0f84
%strncmp_1_break
8b45
0C
0fb600
85c0
85c0
84c0
0f84
%strncmp_1_break
8b45
08
0fb600
50
8b45
0C
0fb600
89c2
58
29d0
0f94c0
0fb6c0
0f85
%strncmp_1_break
89e8
83c0
10
8300
FF
8b45
10
85c0
85c0
0f84
%strncmp_1_break
e9
%strncmp_1_loop
:strncmp_1_break
8b45
08
0fb600
50
8b45
0C
0fb600
89c2
58
29d0
c9
c3
:getenv
55
89e5
81ec
54100000
a1
&g_environment
8945
FC
ff75
08
e8
%strlen
83c4
04
8945
F8
e9
%getenv_8_continue
:getenv_8_loop
ff75
F8
8b45
FC
8b00
50
ff75
08
e8
%strncmp
83c4
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%getenv_11_break
8b45
FC
8b00
50
8b45
F8
89c2
58
01d0
0fb600
50
b8
3D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%getenv_11_break
8b45
FC
8b00
50
8b45
F8
89c2
58
01d0
83c0
01
c9
c3
e9
%getenv_11_break
:getenv_11_break
8b45
FC
50
89e8
83c0
FC
8300
04
58
85c0
:getenv_8_continue
8b45
FC
8b00
85c0
85c0
0f84
%getenv_8_break
e9
%getenv_8_loop
:getenv_8_break
b8
00000000
c9
c3
:vprintf
55
89e5
81ec
54100000
8b45
08
8945
FC
e9
%vprintf_4_continue
:vprintf_4_loop
8b45
FC
0fb600
50
b8
25000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%vprintf_7_else
8b45
FC
50
89e8
83c0
FC
8300
01
58
0fb600
50
e8
%putchar
83c4
04
85c0
e9
%vprintf_7_break
:vprintf_7_else
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
8b45
FC
0fb600
8945
F8
0fb645
F8
:vprintf_38_clause0
83f8
25
0f84
%vprintf_38_body0
e9
%vprintf_38_clause1
:vprintf_38_body0
8b45
FC
0fb600
50
e8
%putchar
83c4
04
85c0
e9
%vprintf_38_break
e9
%vprintf_38_body1
:vprintf_38_clause1
83f8
63
0f84
%vprintf_38_body1
e9
%vprintf_38_clause2
:vprintf_38_body1
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
0C
83c0
04
8945
0C
89c2
58
01d0
8b00
8945
F4
85c0
ff75
F4
e8
%putchar
83c4
04
85c0
e9
%vprintf_38_break
e9
%vprintf_38_body2
:vprintf_38_clause2
83f8
64
0f84
%vprintf_38_body2
e9
%vprintf_38_clause3
:vprintf_38_body2
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
0C
83c0
04
8945
0C
89c2
58
01d0
8b00
8945
F0
85c0
ff75
F0
e8
%itoa
83c4
04
50
e8
%puts
83c4
04
85c0
e9
%vprintf_38_break
e9
%vprintf_38_body3
:vprintf_38_clause3
83f8
73
0f84
%vprintf_38_body3
e9
%vprintf_38_clause4
:vprintf_38_body3
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
0C
83c0
04
8945
0C
89c2
58
01d0
8b00
8945
EC
85c0
ff75
EC
e8
%puts
83c4
04
85c0
e9
%vprintf_38_break
e9
%vprintf_38_body4
:vprintf_38_clause4
:vprintf_38_body4
8b45
FC
0fb600
50
e8
%putchar
83c4
04
85c0
e9
%vprintf_38_break
:vprintf_38_break
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
:vprintf_7_break
:vprintf_4_continue
8b45
FC
0fb600
85c0
85c0
84c0
0f84
%vprintf_4_break
e9
%vprintf_4_loop
:vprintf_4_break
b8
00000000
8945
0C
85c0
b8
00000000
c9
c3
:printf
55
89e5
81ec
54100000
89e8
83c0
08
83c0
04
8945
FC
85c0
ff75
FC
ff75
08
e8
%vprintf
83c4
08
8945
F8
b8
00000000
8945
FC
85c0
8b45
F8
c9
c3
:vsprintf
55
89e5
81ec
54100000
8b45
0C
8945
FC
e9
%vsprintf_4_continue
:vsprintf_4_loop
8b45
FC
0fb600
50
b8
25000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%vsprintf_7_else
8b45
FC
50
89e8
83c0
FC
8300
01
58
0fb600
50
8b45
08
89c2
58
8802
8345
08
01
85c0
e9
%vsprintf_7_break
:vsprintf_7_else
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
8b45
FC
0fb600
8945
F8
0fb645
F8
:vsprintf_42_clause0
83f8
25
0f84
%vsprintf_42_body0
e9
%vsprintf_42_clause1
:vsprintf_42_body0
8b45
FC
0fb600
50
8b45
08
89c2
58
8802
8345
08
01
85c0
e9
%vsprintf_42_break
e9
%vsprintf_42_body1
:vsprintf_42_clause1
83f8
63
0f84
%vsprintf_42_body1
e9
%vsprintf_42_clause2
:vsprintf_42_body1
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
F4
85c0
0fb645
F4
50
8b45
08
89c2
58
8802
8345
08
01
85c0
e9
%vsprintf_42_break
e9
%vsprintf_42_body2
:vsprintf_42_clause2
83f8
64
0f84
%vsprintf_42_body2
e9
%vsprintf_42_clause3
:vsprintf_42_body2
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
F0
85c0
ff75
F0
e8
%itoa
83c4
04
8945
EC
85c0
e9
%vsprintf_124_continue
:vsprintf_124_loop
8b45
EC
50
89e8
83c0
EC
8300
01
58
0fb600
50
8b45
08
89c2
58
8802
8345
08
01
85c0
:vsprintf_124_continue
8b45
EC
0fb600
85c0
85c0
84c0
0f84
%vsprintf_124_break
e9
%vsprintf_124_loop
:vsprintf_124_break
e9
%vsprintf_42_break
e9
%vsprintf_42_body3
:vsprintf_42_clause3
83f8
73
0f84
%vsprintf_42_body3
e9
%vsprintf_42_clause4
:vsprintf_42_body3
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
E8
85c0
e9
%vsprintf_175_continue
:vsprintf_175_loop
8b45
E8
50
89e8
83c0
E8
8300
01
58
0fb600
50
8b45
08
89c2
58
8802
8345
08
01
85c0
:vsprintf_175_continue
8b45
E8
0fb600
85c0
85c0
84c0
0f84
%vsprintf_175_break
e9
%vsprintf_175_loop
:vsprintf_175_break
e9
%vsprintf_42_break
e9
%vsprintf_42_body4
:vsprintf_42_clause4
:vsprintf_42_body4
8b45
FC
0fb600
50
8b45
08
89c2
58
8802
8345
08
01
85c0
e9
%vsprintf_42_break
:vsprintf_42_break
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
:vsprintf_7_break
:vsprintf_4_continue
8b45
FC
0fb600
85c0
85c0
84c0
0f84
%vsprintf_4_break
e9
%vsprintf_4_loop
:vsprintf_4_break
b8
00000000
8945
10
85c0
b8
00000000
50
8b45
08
89c2
58
8802
85c0
ff75
08
e8
%strlen
83c4
04
c9
c3
:sprintf
55
89e5
81ec
54100000
89e8
83c0
0C
83c0
04
8945
FC
85c0
ff75
FC
ff75
0C
ff75
08
e8
%vsprintf
83c4
0C
8945
F8
b8
00000000
8945
FC
85c0
8b45
F8
c9
c3
:_getopt_internal
55
89e5
81ec
54100000
b8
00000000
a3
&optarg
85c0
a1
&optind
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_6_break
b8
01000000
a3
&optind
a3
&last_nonopt
a3
&first_nonopt
85c0
b8
00000000
a3
&nextchar
85c0
e9
%_getopt_internal_6_break
:_getopt_internal_6_break
a1
&nextchar
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_28_break_b_29
e9
%_getopt_internal_28_break_skip_b_29
:_getopt_internal_28_break_b_29
a1
&nextchar
0fb600
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_28_break
:_getopt_internal_28_break_skip_b_29
a1
&optind
50
8b45
08
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_47_break
a1
&first_nonopt
50
a1
&last_nonopt
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_55_break
a1
&first_nonopt
a3
&optind
85c0
e9
%_getopt_internal_55_break
:_getopt_internal_55_break
50
b8
01000000
89c2
58
b8
00000000
29d0
c9
c3
e9
%_getopt_internal_47_break
:_getopt_internal_47_break
b8
00000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_77_break_b_78
e9
%_getopt_internal_77_break_skip_b_78
:_getopt_internal_77_break_b_78
b8
01000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_77_break
:_getopt_internal_77_break_skip_b_78
50
b8
01000000
89c2
58
b8
00000000
29d0
c9
c3
e9
%_getopt_internal_77_break
:_getopt_internal_77_break
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
83c0
01
50
8b45
14
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
85c0
0f84
%_getopt_internal_142_and_skip_b
85c0
b8
01000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
85c0
:_getopt_internal_142_and_skip_b
89c2
58
01d0
a3
&nextchar
85c0
e9
%_getopt_internal_28_break
:_getopt_internal_28_break
8b45
14
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_170_break
b8
00000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_170_break
b8
01000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_170_break_b_197
e9
%_getopt_internal_170_break_skip_b_197
:_getopt_internal_170_break_b_197
8b45
1C
85c0
85c0
0f84
%_getopt_internal_170_break
:_getopt_internal_170_break_skip_b_197
a1
&nextchar
8945
F4
b8
00000000
8945
F0
b8
00000000
8945
EC
b8
00000000
8945
E8
e9
%_getopt_internal_238_continue
:_getopt_internal_238_loop
8b45
F4
50
89e8
83c0
F4
8300
01
58
85c0
:_getopt_internal_238_continue
8b45
F4
0fb600
85c0
85c0
84c0
0f84
%_getopt_internal_238_break
8b45
F4
0fb600
50
b8
3D000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_238_break
e9
%_getopt_internal_238_loop
:_getopt_internal_238_break
8b45
14
8945
F8
b8
00000000
8945
FC
85c0
e9
%_getopt_internal_264_initial_skip
:_getopt_internal_264_loop
8b45
F4
50
a1
&nextchar
89c2
58
29d0
ba
01000000
89d3
31d2
f7fb
50
a1
&nextchar
50
89e8
83c0
F8
8b00
83c0
00
8b00
50
e8
%strncmp
83c4
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%_getopt_internal_274_break
8b45
F4
50
a1
&nextchar
89c2
58
29d0
ba
01000000
89d3
31d2
f7fb
50
89e8
83c0
F8
8b00
83c0
00
8b00
50
e8
%strlen
83c4
04
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_295_else
8b45
F8
8945
E8
85c0
8b45
FC
8945
E4
85c0
b8
01000000
8945
F0
85c0
e9
%_getopt_internal_264_break
e9
%_getopt_internal_295_break
:_getopt_internal_295_else
8b45
E8
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_329_else
8b45
F8
8945
E8
85c0
8b45
FC
8945
E4
85c0
e9
%_getopt_internal_329_break
:_getopt_internal_329_else
b8
01000000
8945
EC
85c0
:_getopt_internal_329_break
:_getopt_internal_295_break
e9
%_getopt_internal_274_break
:_getopt_internal_274_break
:_getopt_internal_264_continue
8b45
F8
50
89e8
83c0
F8
8300
10
58
8b45
FC
50
89e8
83c0
FC
8300
01
58
:_getopt_internal_264_initial_skip
89e8
83c0
F8
8b00
83c0
00
8b00
85c0
85c0
0f84
%_getopt_internal_264_break
e9
%_getopt_internal_264_loop
:_getopt_internal_264_break
8b45
EC
85c0
85c0
0f84
%_getopt_internal_378_break
8b45
F0
85c0
0f94c0
0fb6c0
85c0
0f84
%_getopt_internal_378_break
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_390_break
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_2
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_390_break
:_getopt_internal_390_break
a1
&nextchar
50
e8
%strlen
83c4
04
50
a1
&nextchar
5a
01d0
a3
&nextchar
85c0
a1
&optind
50
b8
&optind
8300
01
58
85c0
b8
3F000000
c9
c3
e9
%_getopt_internal_378_break
:_getopt_internal_378_break
8b45
E8
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_439_break
8b45
E4
8945
FC
85c0
a1
&optind
50
b8
&optind
8300
01
58
85c0
8b45
F4
0fb600
85c0
85c0
84c0
0f84
%_getopt_internal_457_else
89e8
83c0
E8
8b00
83c0
04
8b00
85c0
85c0
0f84
%_getopt_internal_464_else
8b45
F4
83c0
01
a3
&optarg
85c0
e9
%_getopt_internal_464_break
:_getopt_internal_464_else
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_481_break
b8
01000000
89c2
50
a1
&optind
83c0
FF
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_487_else
89e8
83c0
E8
8b00
83c0
00
8b00
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_3
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_487_break
:_getopt_internal_487_else
89e8
83c0
E8
8b00
83c0
00
8b00
50
b8
00000000
89c2
50
a1
&optind
83c0
FF
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_4
b8
02000000
50
e8
%fprintf
83c4
14
85c0
:_getopt_internal_487_break
e9
%_getopt_internal_481_break
:_getopt_internal_481_break
a1
&nextchar
50
e8
%strlen
83c4
04
50
a1
&nextchar
5a
01d0
a3
&nextchar
85c0
b8
3F000000
c9
c3
:_getopt_internal_464_break
e9
%_getopt_internal_457_break
:_getopt_internal_457_else
89e8
83c0
E8
8b00
83c0
04
8b00
50
b8
01000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_582_break
a1
&optind
50
8b45
08
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%_getopt_internal_594_else
a1
&optind
50
b8
&optind
8300
01
58
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
a3
&optarg
85c0
e9
%_getopt_internal_594_break
:_getopt_internal_594_else
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_618_break
a1
&optind
83c0
FF
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_5
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_618_break
:_getopt_internal_618_break
a1
&nextchar
50
e8
%strlen
83c4
04
50
a1
&nextchar
5a
01d0
a3
&nextchar
85c0
b8
3F000000
c9
c3
:_getopt_internal_594_break
e9
%_getopt_internal_582_break
:_getopt_internal_582_break
:_getopt_internal_457_break
a1
&nextchar
50
e8
%strlen
83c4
04
50
a1
&nextchar
5a
01d0
a3
&nextchar
85c0
8b45
18
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_673_break
8b45
FC
50
8b45
18
89c2
58
8902
85c0
e9
%_getopt_internal_673_break
:_getopt_internal_673_break
89e8
83c0
E8
8b00
83c0
08
8b00
85c0
85c0
0f84
%_getopt_internal_691_break
89e8
83c0
E8
8b00
83c0
0C
8b00
50
89e8
83c0
E8
8b00
83c0
08
8b00
89c2
58
8902
85c0
b8
00000000
c9
c3
e9
%_getopt_internal_691_break
:_getopt_internal_691_break
89e8
83c0
E8
8b00
83c0
0C
8b00
c9
c3
e9
%_getopt_internal_439_break
:_getopt_internal_439_break
8b45
1C
85c0
0f94c0
0fb6c0
85c0
0f84
%_getopt_internal_729_break_b_730_b_730
e9
%_getopt_internal_729_break_b_730_skip_b_730
:_getopt_internal_729_break_b_730_b_730
b8
01000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_729_break_b_730
:_getopt_internal_729_break_b_730_skip_b_730
e9
%_getopt_internal_729_break_skip_b_730
:_getopt_internal_729_break_b_730
a1
&nextchar
50
ff75
10
e8
%strchr
83c4
08
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_729_break
:_getopt_internal_729_break_skip_b_730
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_770_break
b8
01000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
2D000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_776_else
a1
&nextchar
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_6
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_776_break
:_getopt_internal_776_else
a1
&nextchar
50
b8
00000000
89c2
50
a1
&optind
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
89c2
58
01d0
0fb600
50
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_7
b8
02000000
50
e8
%fprintf
83c4
14
85c0
:_getopt_internal_776_break
e9
%_getopt_internal_770_break
:_getopt_internal_770_break
a1
&nextchar
50
e8
%strlen
83c4
04
50
a1
&nextchar
5a
01d0
a3
&nextchar
85c0
a1
&optind
50
b8
&optind
8300
01
58
85c0
b8
3F000000
c9
c3
e9
%_getopt_internal_729_break
:_getopt_internal_729_break
e9
%_getopt_internal_170_break
:_getopt_internal_170_break
a1
&nextchar
50
b8
&nextchar
8300
01
58
0fb600
8945
F8
ff75
F8
ff75
10
e8
%strchr
83c4
08
8945
F4
a1
&nextchar
0fb600
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_879_break
a1
&optind
50
b8
&optind
8300
01
58
85c0
e9
%_getopt_internal_879_break
:_getopt_internal_879_break
8b45
F4
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_896_break_b_897
e9
%_getopt_internal_896_break_skip_b_897
:_getopt_internal_896_break_b_897
0fb645
F8
50
b8
3A000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_896_break
:_getopt_internal_896_break_skip_b_897
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_914_break
0fb645
F8
50
b8
20000000
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%_getopt_internal_920_else_b_921
e9
%_getopt_internal_920_else_skip_b_921
:_getopt_internal_920_else_b_921
0fb645
F8
50
b8
7F000000
89c2
58
29d0
0f9dc0
0fb6c0
0f8c
%_getopt_internal_920_else
:_getopt_internal_920_else_skip_b_921
ff75
F8
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_8
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_920_break
:_getopt_internal_920_else
ff75
F8
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_9
b8
02000000
50
e8
%fprintf
83c4
10
85c0
:_getopt_internal_920_break
e9
%_getopt_internal_914_break
:_getopt_internal_914_break
b8
3F000000
c9
c3
e9
%_getopt_internal_896_break
:_getopt_internal_896_break
b8
01000000
89c2
50
8b45
F4
89c2
58
01d0
0fb600
50
b8
3A000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_977_break
b8
02000000
89c2
50
8b45
F4
89c2
58
01d0
0fb600
50
b8
3A000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_991_else
a1
&nextchar
0fb600
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_1005_else
a1
&nextchar
a3
&optarg
85c0
a1
&optind
50
b8
&optind
8300
01
58
85c0
e9
%_getopt_internal_1005_break
:_getopt_internal_1005_else
b8
00000000
a3
&optarg
85c0
:_getopt_internal_1005_break
b8
00000000
a3
&nextchar
85c0
e9
%_getopt_internal_991_break
:_getopt_internal_991_else
a1
&nextchar
0fb600
50
b8
00000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%_getopt_internal_1037_else
a1
&nextchar
a3
&optarg
85c0
a1
&optind
50
b8
&optind
8300
01
58
85c0
e9
%_getopt_internal_1037_break
:_getopt_internal_1037_else
a1
&optind
50
8b45
08
89c2
58
29d0
0f94c0
0fb6c0
0f85
%_getopt_internal_1058_else
a1
&opterr
85c0
85c0
0f84
%_getopt_internal_1066_break
ff75
F8
b8
00000000
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
50
68
&string_getopt_long_10
b8
02000000
50
e8
%fprintf
83c4
10
85c0
e9
%_getopt_internal_1066_break
:_getopt_internal_1066_break
b8
3F000000
8945
F8
85c0
e9
%_getopt_internal_1058_break
:_getopt_internal_1058_else
a1
&optind
50
b8
&optind
8300
01
58
c1e0
02
50
8b45
0C
89c2
58
01d0
8b00
a3
&optarg
85c0
:_getopt_internal_1058_break
:_getopt_internal_1037_break
b8
00000000
a3
&nextchar
85c0
:_getopt_internal_991_break
e9
%_getopt_internal_977_break
:_getopt_internal_977_break
0fb645
F8
c9
c3
:getopt
55
89e5
81ec
54100000
b8
00000000
50
b8
00000000
50
b8
00000000
50
ff75
10
ff75
0C
ff75
08
e8
%_getopt_internal
83c4
18
c9
c3
:getopt_long
55
89e5
81ec
54100000
b8
00000000
50
ff75
18
ff75
14
ff75
10
ff75
0C
ff75
08
e8
%_getopt_internal
83c4
18
c9
c3
:close
55
89e5
81ec
54100000
8b5d
08
b8
06000000
cd80
c9
c3
:unlink
55
89e5
81ec
54100000
8b5d
08
b8
0a000000
cd80
c9
c3
:lseek
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
8b55
10
b8
13000000
cd80
c9
c3
:getcwd
55
89e5
81ec
54100000
8b5d
08
8b4d
0C
b8
b7000000
cd80
c9
c3
:dlclose
55
89e5
81ec
54100000
b8
00000000
c9
c3
:dlopen
55
89e5
81ec
54100000
b8
00000000
c9
c3
:execvp
55
89e5
81ec
54100000
68
&string_getopt_long_11
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:fclose
55
89e5
81ec
54100000
8b45
08
8945
FC
ff75
FC
e8
%close
83c4
04
c9
c3
:fdopen
55
89e5
81ec
54100000
8b45
08
c9
c3
:ferror
55
89e5
81ec
54100000
8b45
08
8945
FC
8b45
FC
50
50
b8
01000000
89c2
58
b8
00000000
29d0
89c2
58
29d0
0f94c0
0fb6c0
0f85
%ferror_4_break
50
b8
01000000
89c2
58
b8
00000000
29d0
c9
c3
e9
%ferror_4_break
:ferror_4_break
b8
00000000
c9
c3
:fflush
55
89e5
81ec
54100000
68
&string_getopt_long_12
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:fopen
55
89e5
81ec
54100000
68
&string_getopt_long_13
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:fprintf
55
89e5
81ec
54100000
89e8
83c0
0C
83c0
04
8945
FC
85c0
ff75
FC
ff75
0C
ff75
08
e8
%vfprintf
83c4
0C
8945
F8
b8
00000000
8945
FC
85c0
8b45
F8
c9
c3
:fread
55
89e5
81ec
54100000
68
&string_getopt_long_14
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:fseek
55
89e5
81ec
54100000
68
&string_getopt_long_15
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:ftell
55
89e5
81ec
54100000
68
&string_getopt_long_16
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:fwrite
55
89e5
81ec
54100000
8b45
14
8945
FC
8b45
0C
50
8b45
10
89c2
58
f7e2
50
ff75
08
ff75
FC
e8
%write
83c4
0C
c9
c3
:gettimeofday
55
89e5
81ec
54100000
b8
00000000
c9
c3
:localtime
55
89e5
81ec
54100000
68
&string_getopt_long_17
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:longjmp
55
89e5
81ec
54100000
8b45
0C
50
b8
00000000
89c2
58
29d0
0f94c0
0fb6c0
0f85
%longjmp_2_else
b8
01000000
85c0
e9
%longjmp_2_break
:longjmp_2_else
8b45
0C
85c0
:longjmp_2_break
8945
0C
85c0
8b45
0C
8b6d
08
8b5d
04
8b65
08
8b6d
00
ffe3
b8
2A000000
50
e8
%exit
83c4
04
85c0
c9
c3
:memmove
55
89e5
81ec
54100000
8b45
08
50
8b45
0C
89c2
58
29d0
0f9cc0
0fb6c0
0f8d
%memmove_1_break
ff75
10
ff75
0C
ff75
08
e8
%memcpy
83c4
0C
c9
c3
e9
%memmove_1_break
:memmove_1_break
8b45
08
50
8b45
10
89c2
58
01d0
8945
FC
8b45
0C
50
8b45
10
89c2
58
01d0
8945
F8
e9
%memmove_30_continue
:memmove_30_loop
89e8
83c0
F8
8300
FF
8b45
F8
0fb600
50
89e8
83c0
FC
8300
FF
8b45
FC
89c2
58
8802
85c0
:memmove_30_continue
8b45
10
50
89e8
83c0
10
8300
FF
58
85c0
85c0
0f84
%memmove_30_break
e9
%memmove_30_loop
:memmove_30_break
8b45
08
c9
c3
:memset
55
89e5
81ec
54100000
8b45
08
8945
FC
e9
%memset_4_continue
:memset_4_loop
8b45
0C
50
8b45
FC
89c2
58
8802
8345
FC
01
85c0
:memset_4_continue
8b45
10
50
89e8
83c0
10
8300
FF
58
85c0
85c0
0f84
%memset_4_break
e9
%memset_4_loop
:memset_4_break
8b45
08
c9
c3
:memcmp
55
89e5
81ec
54100000
8b45
08
8945
FC
8b45
0C
8945
F8
e9
%memcmp_7_continue
:memcmp_7_loop
8b45
FC
50
89e8
83c0
FC
8300
01
58
85c0
8b45
F8
50
89e8
83c0
F8
8300
01
58
85c0
:memcmp_7_continue
8b45
FC
0fb600
50
8b45
F8
0fb600
89c2
58
29d0
0f94c0
0fb6c0
0f85
%memcmp_7_break
89e8
83c0
10
8300
FF
8b45
10
85c0
85c0
0f84
%memcmp_7_break
e9
%memcmp_7_loop
:memcmp_7_break
8b45
FC
0fb600
50
8b45
F8
0fb600
89c2
58
29d0
c9
c3
:mprotect
55
89e5
81ec
54100000
b8
00000000
c9
c3
:qsort
55
89e5
81ec
54100000
68
&string_getopt_long_18
e8
%eputs
83c4
04
85c0
c9
c3
:remove
55
89e5
81ec
54100000
68
&string_getopt_long_19
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:setjmp
55
89e5
81ec
54100000
89e8
83c0
08
8945
FC
50
b8
02000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
FC
89c2
58
01d0
8b00
50
b8
00000000
89c2
01c0
01d0
c1e0
02
50
8b45
08
89c2
58
01d0
83c0
00
89c2
58
8902
85c0
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
FC
89c2
58
01d0
8b00
50
b8
00000000
89c2
01c0
01d0
c1e0
02
50
8b45
08
89c2
58
01d0
83c0
04
89c2
58
8902
85c0
89e8
83c0
08
50
b8
00000000
89c2
01c0
01d0
c1e0
02
50
8b45
08
89c2
58
01d0
83c0
08
89c2
58
8902
85c0
b8
00000000
c9
c3
:sigaction
55
89e5
81ec
54100000
b8
00000000
c9
c3
:sigemptyset
55
89e5
81ec
54100000
b8
00000000
c9
c3
:snprintf
55
89e5
81ec
54100000
89e8
83c0
10
83c0
04
8945
FC
85c0
ff75
FC
ff75
10
ff75
08
e8
%vsprintf
83c4
0C
8945
F8
b8
00000000
8945
FC
85c0
8b45
F8
c9
c3
:sscanf
55
89e5
81ec
54100000
68
&string_getopt_long_20
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:strcat
55
89e5
81ec
54100000
b8
00000000
50
ff75
08
e8
%strchr
83c4
08
8945
FC
e9
%strcat_7_continue
:strcat_7_loop
8b45
0C
50
89e8
83c0
0C
8300
01
58
0fb600
50
8b45
FC
89c2
58
8802
8345
FC
01
85c0
:strcat_7_continue
8b45
0C
50
89e8
83c0
0C
8300
01
58
0fb600
85c0
85c0
84c0
0f84
%strcat_7_break
e9
%strcat_7_loop
:strcat_7_break
b8
00000000
50
8b45
FC
89c2
58
8802
85c0
8b45
08
c9
c3
:strchr
55
89e5
81ec
54100000
8b45
08
8945
FC
e9
%strchr_4_continue
:strchr_4_loop
8b45
0C
50
8b45
FC
0fb600
89c2
58
29d0
0f94c0
0fb6c0
0f85
%strchr_7_break
8b45
FC
c9
c3
e9
%strchr_7_break
:strchr_7_break
8b45
FC
50
89e8
83c0
FC
8300
01
58
0fb600
85c0
:strchr_4_continue
8b45
FC
0fb600
85c0
85c0
84c0
0f84
%strchr_4_break_b_28
e9
%strchr_4_break_skip_b_28
:strchr_4_break_b_28
8b45
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%strchr_4_break
:strchr_4_break_skip_b_28
e9
%strchr_4_loop
:strchr_4_break
b8
00000000
c9
c3
:strrchr
55
89e5
81ec
54100000
ff75
08
e8
%strlen
83c4
04
8945
FC
8b45
FC
85c0
0f94c0
0fb6c0
85c0
0f84
%strrchr_5_break
b8
00000000
c9
c3
e9
%strrchr_5_break
:strrchr_5_break
8b45
08
50
8b45
FC
89c2
58
01d0
83c0
FF
8945
F8
e9
%strrchr_24_continue
:strrchr_24_loop
8b45
0C
50
8b45
F8
0fb600
89c2
58
29d0
0f94c0
0fb6c0
0f85
%strrchr_27_break
8b45
F8
c9
c3
e9
%strrchr_27_break
:strrchr_27_break
8b45
F8
50
89e8
83c0
F8
8300
FF
58
0fb600
85c0
:strrchr_24_continue
8b45
F8
0fb600
85c0
85c0
84c0
0f84
%strrchr_24_break_b_48
e9
%strrchr_24_break_skip_b_48
:strrchr_24_break_b_48
8b45
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%strrchr_24_break
:strrchr_24_break_skip_b_48
e9
%strrchr_24_loop
:strrchr_24_break
b8
00000000
c9
c3
:strstr
55
89e5
81ec
54100000
68
&string_getopt_long_21
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:strtol
55
89e5
81ec
54100000
68
&string_getopt_long_22
e8
%eputs
83c4
04
85c0
b8
02000000
50
68
&string_getopt_long_23
ff75
08
e8
%strncmp
83c4
0C
85c0
0f94c0
0fb6c0
85c0
0f84
%strtol_5_break
8b45
08
83c0
02
8945
FC
b8
10000000
50
8d45
FC
50
e8
%_atoi
83c4
08
c9
c3
e9
%strtol_5_break
:strtol_5_break
ff75
10
8d45
08
50
e8
%_atoi
83c4
08
c9
c3
:strtoll
55
89e5
81ec
54100000
68
&string_getopt_long_24
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:strtoul
55
89e5
81ec
54100000
68
&string_getopt_long_25
e8
%eputs
83c4
04
85c0
b8
00000000
c9
c3
:strtoull
55
89e5
81ec
54100000
8b45
08
50
8b45
0C
89c2
58
8902
85c0
ff75
10
ff75
0C
e8
%_atoi
83c4
08
c9
c3
:time
55
89e5
81ec
54100000
b8
00000000
c9
c3
:vsnprintf
55
89e5
81ec
54100000
ff75
14
ff75
10
ff75
08
e8
%vsprintf
83c4
0C
c9
c3
:calloc
55
89e5
81ec
54100000
8b45
08
50
8b45
0C
89c2
58
f7e2
8945
FC
ff75
FC
e8
%malloc
83c4
04
8945
F8
ff75
FC
b8
00000000
50
ff75
F8
e8
%memset
83c4
0C
85c0
8b45
F8
c9
c3
:vfprintf
55
89e5
81ec
54100000
8b45
08
8945
FC
8b45
0C
8945
F8
e9
%vfprintf_7_continue
:vfprintf_7_loop
8b45
F8
0fb600
50
b8
25000000
89c2
58
50
29d0
0f95c0
0fb6c0
870424
29d0
9f
80f4
40
9e
58
0f85
%vfprintf_10_else
8b45
F8
50
89e8
83c0
F8
8300
01
58
0fb600
50
e8
%putchar
83c4
04
85c0
e9
%vfprintf_10_break
:vfprintf_10_else
8b45
F8
50
89e8
83c0
F8
8300
01
58
85c0
8b45
F8
0fb600
8945
F4
0fb645
F4
:vfprintf_41_clause0
83f8
25
0f84
%vfprintf_41_body0
e9
%vfprintf_41_clause1
:vfprintf_41_body0
ff75
FC
8b45
F8
0fb600
50
e8
%fputc
83c4
08
85c0
e9
%vfprintf_41_break
e9
%vfprintf_41_body1
:vfprintf_41_clause1
83f8
63
0f84
%vfprintf_41_body1
e9
%vfprintf_41_clause2
:vfprintf_41_body1
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
F0
85c0
ff75
FC
ff75
F0
e8
%fputc
83c4
08
85c0
e9
%vfprintf_41_break
e9
%vfprintf_41_body2
:vfprintf_41_clause2
83f8
64
0f84
%vfprintf_41_body2
e9
%vfprintf_41_clause3
:vfprintf_41_body2
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
EC
85c0
ff75
FC
ff75
EC
e8
%itoa
83c4
04
50
e8
%fputs
83c4
08
85c0
e9
%vfprintf_41_break
e9
%vfprintf_41_body3
:vfprintf_41_clause3
83f8
73
0f84
%vfprintf_41_body3
e9
%vfprintf_41_clause4
:vfprintf_41_body3
50
b8
01000000
89c2
58
b8
00000000
29d0
c1e0
02
50
8b45
10
83c0
04
8945
10
89c2
58
01d0
8b00
8945
E8
85c0
ff75
FC
ff75
E8
e8
%fputs
83c4
08
85c0
e9
%vfprintf_41_break
e9
%vfprintf_41_body4
:vfprintf_41_clause4
:vfprintf_41_body4
ff75
FC
8b45
F8
0fb600
50
e8
%fputc
83c4
08
85c0
e9
%vfprintf_41_break
:vfprintf_41_break
8b45
F8
50
89e8
83c0
F8
8300
01
58
85c0
:vfprintf_10_break
:vfprintf_7_continue
8b45
F8
0fb600
85c0
85c0
84c0
0f84
%vfprintf_7_break
e9
%vfprintf_7_loop
:vfprintf_7_break
b8
00000000
8945
10
85c0
b8
00000000
c9
c3
:buf
00
00
00
00
00
00
00
00
00
00
00
00
:g_environment
00
00
00
00
:g_stdin
00
00
00
00
:g_stdout
00
00
00
00
:g_environment
00
00
00
00
:g_stdin
00
00
00
00
:string_getopt_long_0
617373657274206661696C3A20000000
:string_getopt_long_1
0A000000
:ungetc_char
FF
FF
FF
FF
:ungetc_buf
00
00
:itoa_buf
00
00
00
00
00
00
00
00
00
00
:g_brk
00
00
00
00
:optarg
00
00
00
00
:optind
00
00
00
00
:opterr
00
00
00
00
:optarg
00
00
00
00
:optind
00
00
00
00
:nextchar
00
00
00
00
:opterr
01
00
00
00
:first_nonopt
00
00
00
00
:last_nonopt
00
00
00
00
:string_getopt_long_2
25
73
3A
20
6F
70
74
69
6F
6E
20
60
25
73
27
20
69
73
20
61
6D
62
69
67
75
6F
75
73
0A
00
:string_getopt_long_3
25
73
3A
20
6F
70
74
69
6F
6E
20
60
2D
2D
25
73
27
20
64
6F
65
73
6E
27
74
20
61
6C
6C
6F
77
20
61
6E
20
61
72
67
75
6D
65
6E
74
0A
00
:string_getopt_long_4
25
73
3A
20
6F
70
74
69
6F
6E
20
60
25
63
25
73
27
20
64
6F
65
73
6E
27
74
20
61
6C
6C
6F
77
20
61
6E
20
61
72
67
75
6D
65
6E
74
0A
00
:string_getopt_long_5
25
73
3A
20
6F
70
74
69
6F
6E
20
60
25
73
27
20
72
65
71
75
69
72
65
73
20
61
6E
20
61
72
67
75
6D
65
6E
74
0A
00
:string_getopt_long_6
25
73
3A
20
75
6E
72
65
63
6F
67
6E
69
7A
65
64
20
6F
70
74
69
6F
6E
20
60
2D
2D
25
73
27
0A
00
:string_getopt_long_7
25
73
3A
20
75
6E
72
65
63
6F
67
6E
69
7A
65
64
20
6F
70
74
69
6F
6E
20
60
25
63
25
73
27
0A
00
:string_getopt_long_8
25733A20756E7265636F676E697A6564206F7074696F6E2C2063686172616374657220636F64652030256F0A00000000
:string_getopt_long_9
25
73
3A
20
75
6E
72
65
63
6F
67
6E
69
7A
65
64
20
6F
70
74
69
6F
6E
20
60
2D
25
63
27
0A
00
:string_getopt_long_10
25
73
3A
20
6F
70
74
69
6F
6E
20
60
2D
25
63
27
20
72
65
71
75
69
72
65
73
20
61
6E
20
61
72
67
75
6D
65
6E
74
0A
00
:errno
00
00
00
00
:string_getopt_long_11
65786563767020737475620A00000000
:string_getopt_long_12
66666C75736820737475620A00000000
:string_getopt_long_13
666F70656E20737475620A00
:string_getopt_long_14
667265616420737475620A00
:string_getopt_long_15
667365656B20737475620A00
:string_getopt_long_16
6674656C6C20737475620A00
:string_getopt_long_17
6C6F63616C74696D6520737475620A00
:string_getopt_long_18
71736F727420737475620A00
:string_getopt_long_19
72656D6F766520737475620A00000000
:string_getopt_long_20
737363616E6620737475620A00000000
:string_getopt_long_21
73747273747220737475620A00000000
:string_getopt_long_22
737472746F6C20737475620A00000000
:string_getopt_long_23
30780000
:string_getopt_long_24
737472746F6C6C20737475620A000000
:string_getopt_long_25
737472746F756C20737475620A000000
mescc-tools-Release_1.3/test/test9/x86.M1 0000664 0000000 0000000 00000013651 14126326331 0020127 0 ustar 00root root 0000000 0000000 ### Mes --- Maxwell Equations of Software
### Copyright © 2017 Jan Nieuwenhuizen
###
### This file is part of Mes.
###
### Mes is free software# you can redistribute it and/or modify it
### under the terms of the GNU General Public License as published by
### the Free Software Foundation# either version 3 of the License, or (at
### your option) any later version.
###
### Mes is distributed in the hope that it will be useful, but
### WITHOUT ANY WARRANTY# without even the implied warranty of
### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
### GNU General Public License for more details.
###
### You should have received a copy of the GNU General Public License
### along with Mes. If not, see .
DEFINE add____$i32,%eax 05
DEFINE add____$i32,%ecx 81c1
DEFINE add____$i32,%edx 81c2
DEFINE add____$i32,(%eax) 8100
DEFINE add____$i32,0x32(%eax) 8180
DEFINE add____$i32,0x32(%ebp) 8185
DEFINE add____$i8,%eax 83c0
DEFINE add____$i8,%edx 83c2
DEFINE add____$i8,%esp 83c4
DEFINE add____$i8,(%eax) 8300
DEFINE add____$i8,0x32 8305
DEFINE add____$i8,0x32(%eax) 8380
DEFINE add____$i8,0x32(%ebp) 8385
DEFINE add____$i8,0x8(%eax) 8340
DEFINE add____$i8,0x8(%ebp) 8345
DEFINE add____%eax,%eax 01c0
DEFINE add____%ebp,%eax 01e8
DEFINE add____%edx,%eax 01d0
DEFINE and____%edx,%eax 21d0
DEFINE call32 e8
DEFINE call___*%eax ffd0
DEFINE cmp____$0x32,%eax 3d
DEFINE cmp____$i32,%eax 3d
DEFINE cmp____$i32,0x32(%ebp) 81bd
DEFINE cmp____$i32,0x8(%ebp) 817d
DEFINE cmp____$i8,%eax 83f8
DEFINE cmp____$i8,0x32(%ebp) 83bd
DEFINE cmp____$i8,0x8(%ebp) 837d
DEFINE cmp____%al,%dl 38c2
DEFINE cmp____%edx,%eax 39d0
DEFINE hlt f4
DEFINE idiv___%ebx f7fb
DEFINE int cd
DEFINE int____$0x80 cd80
DEFINE je32 0f84
DEFINE je8 74
DEFINE jg32 0f8f
DEFINE jge32 0f8d
DEFINE jl32 0f8c
DEFINE jle32 0f8e
DEFINE jmp32 e9
DEFINE jmp____*%ebx ffe3
DEFINE jne32 0f85
DEFINE lahf 9f
DEFINE lea____0x32(%ebp),%eax 8d85
DEFINE lea____0x32(%ebp),%edx 8d95
DEFINE lea____0x8(%ebp),%eax 8d45
DEFINE lea____0x8(%ebp),%edx 8d55
DEFINE leave c9
DEFINE mov____$i32,%eax b8
DEFINE mov____$i32,%ebx bb
DEFINE mov____$i32,%ecx b9
DEFINE mov____$i32,%edx ba
DEFINE mov____$i32,(%eax) c700
DEFINE mov____$i32,0x32 c705
DEFINE mov____$i32,0x8(%eax) c740
DEFINE mov____$i32,0x8(%ebp) c745
DEFINE mov____%al,(%edx) 8802
DEFINE mov____%al,0x32(%ebp) 8885
DEFINE mov____%al,0x8(%ebp) 8845
DEFINE mov____%al,0x8(%edx) 8842
DEFINE mov____%ax,(%edx) 668902
DEFINE mov____%ax,0x32(%ebp) 668985
DEFINE mov____%ax,0x32(%edx) 668982
DEFINE mov____%ax,0x8(%ebp) 668945
DEFINE mov____%ax,0x8(%edx) 668942
DEFINE mov____%dl,(%eax) 8810
DEFINE mov____%dl,0x8(%eax) 8850
DEFINE mov____%eax,%ebx 89c3
DEFINE mov____%eax,%edx 89c2
DEFINE mov____%eax,(%ecx) 8901
DEFINE mov____%eax,(%edx) 8902
DEFINE mov____%eax,0x32 a3
DEFINE mov____%eax,0x32(%ebp) 8985
DEFINE mov____%eax,0x32(%edx) 8982
DEFINE mov____%eax,0x8(%ebp) 8945
DEFINE mov____%eax,0x8(%edx) 8942
DEFINE mov____%ebp,%eax 89e8
DEFINE mov____%ebp,%ecx 89e9
DEFINE mov____%ebp,%edx 89ea
DEFINE mov____%ebx,0x32 891d
DEFINE mov____%ebx,0x32(%ebp) 899d
DEFINE mov____%ebx,0x8(%ebp) 895d
DEFINE mov____%ebx,0x8(%edx) 895a
DEFINE mov____%ecx,(%eax) 8908
DEFINE mov____%ecx,(%edx) 890a
DEFINE mov____%ecx,0x32(%ebp) 898d
DEFINE mov____%ecx,0x8(%ebp) 894d
DEFINE mov____%edx,%eax 89d0
DEFINE mov____%edx,%ebx 89d3
DEFINE mov____%edx,%ecx 89d1
DEFINE mov____%edx,(%eax) 8910
DEFINE mov____%edx,0x32(%ebp) 8995
DEFINE mov____%edx,0x8(%ebp) 8955
DEFINE mov____%esp,%ebp 89e5
DEFINE mov____(%eax),%eax 8b00
DEFINE mov____(%eax),%ecx 8b08
DEFINE mov____(%edx),%ecx 8b0a
DEFINE mov____(%edx),%edx 8b12
DEFINE mov____0x32(%eax),%eax 8b80
DEFINE mov____0x32(%eax),%ebx 8b98
DEFINE mov____0x32(%eax),%ecx 8b88
DEFINE mov____0x32(%ebp),%eax 8b85
DEFINE mov____0x32(%ebp),%ebx 8b9d
DEFINE mov____0x32(%ebp),%ecx 8b8d
DEFINE mov____0x32(%ebp),%edx 8b95
DEFINE mov____0x32,%eax a1
DEFINE mov____0x32,%edx 8b15
DEFINE mov____0x8(%eax),%eax 8b40
DEFINE mov____0x8(%eax),%ebx 8b58
DEFINE mov____0x8(%eax),%ecx 8b48
DEFINE mov____0x8(%ebp),%eax 8b45
DEFINE mov____0x8(%ebp),%ebp 8b6d
DEFINE mov____0x8(%ebp),%ebx 8b5d
DEFINE mov____0x8(%ebp),%ecx 8b4d
DEFINE mov____0x8(%ebp),%edx 8b55
DEFINE mov____0x8(%ebp),%esp 8b65
DEFINE movzbl_%al,%eax 0fb6c0
DEFINE movzbl_%dl,%edx 0fb6d2
DEFINE movzbl_(%eax),%eax 0fb600
DEFINE movzbl_(%eax),%edx 0fb610
DEFINE movzbl_(%edx),%edx 0fb612
DEFINE movzbl_0x32(%eax),%eax 0fb680
DEFINE movzbl_0x32(%ebp),%eax 0fb685
DEFINE movzbl_0x8(%eax),%eax 0fb640
DEFINE movzbl_0x8(%ebp),%eax 0fb645
DEFINE movzbl_0x8(%ebp),%edx 0fb655
DEFINE movzwl_(%eax),%eax 0fb700
DEFINE movzwl_0x32(%eax),%eax 0fb780
DEFINE movzwl_0x8(%eax),%eax 0fb740
DEFINE mul____%edx f7e2
DEFINE nop 90
DEFINE not____%eax f7d0
DEFINE or_____%edx,%eax 09d0
DEFINE pop____%eax 58
DEFINE pop____%edx 5a
DEFINE push___$i32 68
DEFINE push___%eax 50
DEFINE push___%ebp 55
DEFINE push___%edx 52
DEFINE push___(%eax) ff30
DEFINE push___0x32(%ebp) ffb5
DEFINE push___0x8(%ebp) ff75
DEFINE ret c3
DEFINE sahf 9e
DEFINE sete___%al 0f94c0
DEFINE setg___%al 0f9fc0
DEFINE setge__%al 0f9dc0
DEFINE setl___%al 0f9cc0
DEFINE setle__%al 0f9ec0
DEFINE setne__%al 0f95c0
DEFINE shl____$i8,%eax c1e0
DEFINE shl____%cl,%eax d3e0
DEFINE shr____%cl,%eax d3e8
DEFINE sub____%al,%dl 28d0
DEFINE sub____%dl,%al 28c2
DEFINE sub____%eax,%edx 29c2
DEFINE sub____%edx,%eax 29d0
DEFINE sub____%esp,$i32 81ec
DEFINE sub____%esp,$i8 83ec
DEFINE test___%al,%al 84c0
DEFINE test___%eax,%eax 85c0
DEFINE xchg___%eax,(%esp) 870424
DEFINE xor____$i32,%eax 35
DEFINE xor____$i8,%ah 80f4
DEFINE xor____%eax,%eax 31c0
DEFINE xor____%ebx,%ebx 31db
DEFINE xor____%ecx,%ecx 31c9
DEFINE xor____%edx,%eax 31d0
DEFINE xor____%edx,%edx 31d2
DEFINE SYS_exit 01000000
DEFINE SYS_read 03000000
DEFINE SYS_write 04000000
DEFINE SYS_open 05000000
DEFINE SYS_close 06000000
DEFINE SYS_unlink 0a000000
DEFINE SYS_chmod 0f000000
DEFINE SYS_lseek 13000000
DEFINE SYS_access 21000000
DEFINE SYS_brk 2d000000
DEFINE SYS_fsync 76000000
DEFINE SYS_getcwd b7000000