mescc-tools-1.5.2/.gitignore 0000644 0000000 0000000 00000002212 14522760670 012633 0 ustar ## 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-1.5.2/.gitmodules 0000644 0000000 0000000 00000000121 14522760670 013015 0 ustar [submodule "M2libc"]
path = M2libc
url = https://github.com/oriansj/M2libc.git
mescc-tools-1.5.2/CHANGELOG.org 0000644 0000000 0000000 00000036424 14522760670 012657 0 ustar ## 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
** Changed
** Fixed
** Removed
* 1.5 - 2023-07-20
** Added
Add UEFI support for spawning new processes.
** Changed
Kaem now sets the SHELL variable if it doesn't exist
Kaem now checks environment variable length before using strcpy.
** Fixed
Fixed makefile make call for kaem
Fixed kaem so it now handles cases when the alias name is longer than the command
Fixed M1 quoted DEFINES
Hex2 added support signed and unsigned range_check behavior
M1 added support for signed and unsigned range_check behavior
Fix bug where unset removes the first environment variable when a token value is NULL.
Fixed several kaem segfaults that could occur on UEFI systems
** Removed
Hex2 removed support for the flags: --BigEndian, --LittleEndian, --exec_enable and --BaseAddress
M1 removed support for the flags: --BigEndian and --LittleEndian
* 1.4 - 2022-05-01
** Added
Added exec support to kaem
Added if/else conditionals to kaem
Add support for aliases in kaem
Added --hex2 and --endian flags to get_machine
Kaem now returns more specific messages based on waitpid's status
Kaem added --show-exit-codes flag to enable seeing exit codes for subprocesses
** Changed
Kaem now places space between echo tokens
Kaem now also terminates commands with ;
Kaem now is strict by default and you need to pass --non-strict to revert to old behavior
** Fixed
Various typos
Fix extracting exit status of completed programs in kaem
Catch get_machine's --override segfault
** Removed
Remove unused getopt include from blood-elf
* 1.3 - 2021-10-03
** 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-1.5.2/COPYING 0000644 0000000 0000000 00000104513 14522760670 011705 0 ustar 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-1.5.2/Generating_M0_Definitions.org 0000644 0000000 0000000 00000025526 14522760670 016343 0 ustar * 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-1.5.2/HACKING 0000644 0000000 0000000 00000005310 14522760670 011634 0 ustar -*-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-1.5.2/INSTALL 0000644 0000000 0000000 00000002214 14522760670 011676 0 ustar ## 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-1.5.2/Kaem/.gitignore 0000644 0000000 0000000 00000000230 14522760670 013506 0 ustar # Ignore build directory
bin/
# Ignore Temp directory
temp/
# Ignore test result directory
test/results/
# Ignore temp and special files
*.tst
*.qst
mescc-tools-1.5.2/Kaem/README 0000644 0000000 0000000 00000000313 14522760670 012400 0 ustar 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-1.5.2/Kaem/kaem.c 0000644 0000000 0000000 00000075756 14522760670 012630 0 ustar /* Copyright (C) 2016-2020 Jeremiah Orians
* Copyright (C) 2020 fosslinux
* Copyright (C) 2021 Andrius Štikonas
* 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 token linked-list */
char* token_lookup(char* variable, struct Token* token)
{
/* Start at the head */
struct Token* n = token;
/* 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;
}
/* Search for a variable in the env linked-list */
char* env_lookup(char* variable)
{
return token_lookup(variable, env);
}
/* Search for a variable in the alias linked-list */
char* alias_lookup(char* variable)
{
return token_lookup(variable, alias);
}
/* 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)
{
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;
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);
c = 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;
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 separators */
token_done = TRUE;
}
else if(('\n' == c) || (';' == c))
{
/* Command terminates at the end of a line or at semicolon */
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;
}
/* Function to parse string and assign token->value */
int collect_alias_token(char* input, char* n, int index)
{
int c;
int cc;
int token_done = FALSE;
int output_index = 0;
do
{
/* Loop over each character in the token */
c = input[index];
index = index + 1;
if((' ' == c) || ('\t' == c))
{
/* Space and tab are token separators */
token_done = TRUE;
}
else if('\\' == c)
{
/* Support for escapes */
c = input[index];
index = index + 1;
cc = handle_escape(c);
/* We need to put it into the token */
n[output_index] = cc;
output_index = output_index + 1;
}
else if(0 == c)
{
/* We have come to the end of the token */
token_done = TRUE;
index = 0;
}
else
{
/* It's a character to assign */
n[output_index] = c;
output_index = output_index + 1;
}
} while(token_done == FALSE);
/* Terminate the output with a NULL */
n[output_index] = 0;
return index;
}
/*
* EXECUTION FUNCTIONS
* Note: All of the builtins return SUCCESS (0) when they exit successfully
* and FAILURE (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 FAILURE;
}
i = i + 1;
}
return SUCCESS;
}
/* 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 received 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;
}
/* Add an alias */
void add_alias()
{
token = token->next; /* Skip the actual alias */
if(token->next == NULL)
{
/* No arguments */
char** array = list_to_array(alias);
int index = 0;
while(array[index] != NULL) {
fputs(array[index], stdout);
fputc('\n', stdout);
index = index + 1;
}
fflush(stdout);
return;
}
if(!is_envar(token->value)) {
char** array = list_to_array(token);
int index = 0;
while(array[index] != NULL) {
fputs(array[index], stdout);
fputc(' ', stdout);
index = index + 1;
}
fputc('\n', stdout);
fflush(stdout);
return;
}
/* 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_alias received improper variable\n");
while(0 != value[i])
{
newvalue[i] = value[i];
i = i + 1;
}
/* If this is the first alias, rectify */
if(alias == NULL)
{
alias = calloc(1, sizeof(struct Token));
require(alias != NULL, "Memory initialization of alias failed\n");
alias->var = name; /* Add our first variable */
}
struct Token* n = alias;
/* 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 alias node in alias 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 FAILURE;
}
token = token->next;
if(NULL == token->value)
{
return FAILURE;
}
int ret = chdir(token->value);
if(0 > ret)
{
return FAILURE;
}
return SUCCESS;
}
/* 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 SUCCESS;
}
/* 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 SUCCESS;
cleanup_set:
return FAILURE;
}
/* 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 */
if(token->value == NULL)
{
break;
}
fputs(token->value, stdout);
if(NULL != token->next)
{
/* M2-Planet doesn't short circuit */
if(NULL != token->next->value) fputc(' ', 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;
for(t = token->next; t != NULL; t = t->next)
{
if(NULL == t->value)
{
continue;
}
e = env;
/* Look for the variable; we operate on ->next because we need to remove ->next */
while(e->next != NULL)
{
if(match(e->next->var, t->value))
{
break;
}
e = e->next;
}
if(e->next != NULL)
{
/* There is something to unset */
e->next = e->next->next;
}
}
}
void execute(FILE* script, char** argv);
int _execute(FILE* script, char** argv);
int collect_command(FILE* script, char** argv);
/* if builtin */
void if_cmd(FILE* script, char** argv)
{
int index;
int old_VERBOSE;
token = token->next; /* Skip the actual if */
/* Do not check for successful exit status */
int if_status = _execute(script, argv);
old_VERBOSE = VERBOSE;
VERBOSE = VERBOSE && !if_status;
do
{
index = collect_command(script, argv);
require(index != -1, "Unexpected EOF, improperly terminated if statement.\n");
if(0 == index)
{
continue;
}
if(0 == if_status)
{
/* Stuff to exec */
execute(script, argv);
}
if(match(token->value, "else"))
{
if_status = !if_status;
}
} while(!match(token->value, "fi"));
VERBOSE = old_VERBOSE;
}
int what_exit(char* program, int status)
{
/***********************************************************************************
* If the low-order 8 bits of w_status are equal to 0x7F or zero, the child *
* process has stopped. If the low-order 8 bits of w_status are non-zero and are *
* not equal to 0x7F, the child process terminated due to a signal otherwise, the *
* child process terminated due to an exit() call. *
* *
* In the event it was a signal that stopped the process the top 8 bits of *
* w_status contain the signal that caused the process to stop. *
* *
* In the event it was terminated the bottom 7 bits of w_status contain the *
* terminating error number for the process. *
* *
* If bit 0x80 of w_status is set, a core dump was produced. *
***********************************************************************************/
int WIFEXITED = !(status & 0x7F);
int WEXITSTATUS = (status & 0xFF00) >> 8;
int WTERMSIG = status & 0x7F;
int WCOREDUMP = status & 0x80;
int WIFSIGNALED = !((0x7F == WTERMSIG) || (0 == WTERMSIG));
int WIFSTOPPED = ((0x7F == WTERMSIG) && (0 == WCOREDUMP));
if(WIFEXITED)
{
if(VERBOSE_EXIT)
{
fputc('\n', stderr);
fputs(program, stderr);
fputs(" normal termination, exit status = ", stderr);
fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
fputs("\n\n\n", stderr);
}
return WEXITSTATUS;
}
else if (WIFSIGNALED)
{
fputc('\n', stderr);
fputs(program, stderr);
fputs(" abnormal termination, signal number = ", stderr);
fputs(int2str(WTERMSIG, 10, TRUE), stderr);
fputc('\n', stderr);
if(WCOREDUMP) fputs("core dumped\n", stderr);
return WTERMSIG;
}
else if(WIFSTOPPED)
{
fputc('\n', stderr);
fputs(program, stderr);
fputs(" child stopped, signal number = ", stderr);
fputs(int2str(WEXITSTATUS, 10, TRUE), stderr);
fputc('\n', stderr);
return WEXITSTATUS;
}
fputc('\n', stderr);
fputs(program, stderr);
fputs(" :: something crazy happened with execve\nI'm just gonna get the hell out of here\n", stderr);
exit(EXIT_FAILURE);
}
/* Execute program and check for error */
void execute(FILE* script, char** argv)
{
int status = _execute(script, argv);
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);
}
}
/* Execute program */
int _execute(FILE* script, char** argv)
{
/* Run the command */
/* rc = return code */
int rc;
/* exec without forking */
int exec = FALSE;
/* 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 == SUCCESS, "cd failed!\n");
}
return 0;
}
else if(match(token->value, "set"))
{
rc = set();
if(STRICT)
{
require(rc == SUCCESS, "set failed!\n");
}
return 0;
}
else if(match(token->value, "alias"))
{
add_alias();
return 0;
}
else if(match(token->value, "pwd"))
{
rc = pwd();
if(STRICT)
{
require(rc == SUCCESS, "pwd failed!\n");
}
return 0;
}
else if(match(token->value, "echo"))
{
echo();
return 0;
}
else if(match(token->value, "unset"))
{
unset();
return 0;
}
else if(match(token->value, "exec"))
{
token = token->next; /* Skip the actual exec */
exec = TRUE;
}
else if(match(token->value, "if"))
{
if_cmd(script, argv);
return 0;
}
else if(match(token->value, "then"))
{
/* ignore */
return 0;
}
else if(match(token->value, "else"))
{
/* ignore */
return 0;
}
else if(match(token->value, "fi"))
{
/* ignore */
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 = 0;
#ifdef __uefi__
array = list_to_array(token);
envp = list_to_array(env);
return spawn(program, array, envp);
#else
if(!exec)
{
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_FAILURE);
}
/* Otherwise we are the parent */
/* And we should wait for it to complete */
waitpid(f, &status, 0);
return what_exit(program, status);
#endif
}
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;
int alias_index;
char* alias_string;
/* 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;
}
alias_string = alias_lookup(s);
alias_index = 0;
do
{
if(alias_string != NULL)
{
alias_index = collect_alias_token(alias_string, s, alias_index);
}
/* 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;
}
while(alias_index != 0);
}
/* -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;
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 */
execute(script, argv);
}
}
/* 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");
require(strlen(envp[i]) < MAX_STRING, "Environment variable exceeds length restriction\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;
VERBOSE_EXIT = FALSE;
STRICT = TRUE;
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");
if(NULL != argv[0]) KAEM_BINARY = argv[0];
else KAEM_BINARY = "./bin/kaem";
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] [--non-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.5.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"))
{
/* it is a NOP */
STRICT = TRUE;
i = i + 1;
}
else if(match(argv[i], "--non-strict"))
{
/* Set strict */
STRICT = FALSE;
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], "--show-exit-codes"))
{
/* show exit codes */
VERBOSE_EXIT = 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);
}
/* make sure SHELL is set */
if(NULL == env_lookup("SHELL"))
{
struct Token* shell = calloc(1, sizeof(struct Token));
require(NULL != shell, "unable to create SHELL environment variable\n");
shell->next = env;
shell->var = "SHELL";
shell->value= KAEM_BINARY;
env = shell;
}
/* 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-1.5.2/Kaem/kaem.h 0000644 0000000 0000000 00000002771 14522760670 012620 0 ustar /* 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
// CONSTANT SUCCESS 0
#define SUCCESS 0
// CONSTANT FAILURE 1
#define FAILURE 1
#define MAX_STRING 4096
#define MAX_ARRAY 512
/*
* 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-1.5.2/Kaem/kaem_globals.c 0000644 0000000 0000000 00000002156 14522760670 014313 0 ustar /* 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 VERBOSE_EXIT;
int STRICT;
int INIT_MODE;
int FUZZING;
int WARNINGS;
char* KAEM_BINARY;
char* PATH;
/* Token linked-list; stores the tokens of each line */
struct Token* token;
/* Env linked-list; stores the environment variables */
struct Token* env;
/* Alias linked-list; stores the aliases */
struct Token* alias;
mescc-tools-1.5.2/Kaem/kaem_globals.h 0000644 0000000 0000000 00000002257 14522760670 014322 0 ustar /* 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 VERBOSE_EXIT;
extern int STRICT;
extern int INIT_MODE;
extern int FUZZING;
extern int WARNINGS;
extern char* KAEM_BINARY;
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;
/* Alias linked-list; stores the aliases */
extern struct Token* alias;
mescc-tools-1.5.2/Kaem/makefile 0000644 0000000 0000000 00000002714 14522760670 013227 0 ustar ## 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-1.5.2/Kaem/test.sh 0000755 0000000 0000000 00000004315 14522760670 013044 0 ustar #!/usr/bin/env 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 --non-strict -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"
LANG=C ../bin/kaem -f "test/test17/kaem.test" >| "test/results/test17-output"
. ../sha256.sh
sha256_check test/test.answers
echo "kaem tests complete"
mescc-tools-1.5.2/Kaem/test/.gitignore 0000644 0000000 0000000 00000000011 14522760670 014462 0 ustar results/
mescc-tools-1.5.2/Kaem/test/test.answers 0000644 0000000 0000000 00000003212 14522760670 015063 0 ustar 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
3cf0470e0bba3c7dd743a71f201903fcbd3aed2cf817966e2d127bf10fff66e9 test/results/test13-output
8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aa4 test/results/test14-output
3b22d4ec57697b461347a0c8d195c854172ae4b8c92b86497f2bbd8add4c4229 test/results/test15-output
472ed61017e76d36a6340ad495bd9e7be5f721d8df65fd4c2caa75e88a412601 test/results/test16-output
91eb27fb84000d1d18bc0aa5ec7cc1b85ec3951188f0e17c58161c6051c6a79b test/results/test17-output
mescc-tools-1.5.2/Kaem/test/test00/kaem.test 0000644 0000000 0000000 00000001374 14522760670 015444 0 ustar # 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-1.5.2/Kaem/test/test01/kaem.test 0000644 0000000 0000000 00000001367 14522760670 015447 0 ustar # 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-1.5.2/Kaem/test/test02/kaem.test 0000644 0000000 0000000 00000001322 14522760670 015437 0 ustar # 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-1.5.2/Kaem/test/test03/kaem.test 0000644 0000000 0000000 00000001344 14522760670 015444 0 ustar # 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-1.5.2/Kaem/test/test04/kaem.test 0000644 0000000 0000000 00000001374 14522760670 015450 0 ustar # 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-1.5.2/Kaem/test/test05/kaem.test 0000644 0000000 0000000 00000001414 14522760670 015444 0 ustar # 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-1.5.2/Kaem/test/test06/kaem.test 0000644 0000000 0000000 00000001422 14522760670 015444 0 ustar # 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-1.5.2/Kaem/test/test07/kaem.test 0000644 0000000 0000000 00000001420 14522760670 015443 0 ustar # 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-1.5.2/Kaem/test/test08/kaem.test 0000644 0000000 0000000 00000001341 14522760670 015446 0 ustar # 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-1.5.2/Kaem/test/test09/kaem.test 0000644 0000000 0000000 00000001343 14522760670 015451 0 ustar # 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-1.5.2/Kaem/test/test10/kaem.test 0000644 0000000 0000000 00000001501 14522760670 015435 0 ustar # 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-1.5.2/Kaem/test/test10/subkaem.test 0000644 0000000 0000000 00000001433 14522760670 016153 0 ustar # 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-1.5.2/Kaem/test/test11/kaem.test 0000644 0000000 0000000 00000001423 14522760670 015441 0 ustar # 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-1.5.2/Kaem/test/test12/kaem.test 0000644 0000000 0000000 00000001425 14522760670 015444 0 ustar # 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-1.5.2/Kaem/test/test13/kaem.test 0000644 0000000 0000000 00000001347 14522760670 015450 0 ustar # 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-1.5.2/Kaem/test/test14/kaem.test 0000644 0000000 0000000 00000001353 14522760670 015446 0 ustar # 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-1.5.2/Kaem/test/test15/kaem.test 0000644 0000000 0000000 00000000121 14522760670 015437 0 ustar VAR=test
ANOTHER=test2
echo ${VAR}
unset VAR ANOTHER
echo ${VAR}
echo ${ANOTHER}
mescc-tools-1.5.2/Kaem/test/test16/kaem.test 0000644 0000000 0000000 00000000035 14522760670 015444 0 ustar echo \"test\"
echo "\"test2"
mescc-tools-1.5.2/Kaem/test/test17/kaem.test 0000644 0000000 0000000 00000000163 14522760670 015447 0 ustar A=one
B=two
C=three
D=four
echo ${A}
echo ${B}
echo ${C}
echo ${D}
unset C
echo ${A}
echo ${B}
echo ${C}
echo ${D}
mescc-tools-1.5.2/Kaem/variable.c 0000644 0000000 0000000 00000017655 14522760670 013472 0 ustar /*
* 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-1.5.2/M1-macro.c 0000644 0000000 0000000 00000046374 14522760670 012404 0 ustar /* -*- 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 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");
i->contents = newline_blob;
if (STR == i->next->next->contents->type)
{
i->next->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)
{
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, int absolute)
{
if(4 == number_of_bytes) return;
else if(absolute && (3 == number_of_bytes))
{
bound_values(displacement, number_of_bytes, -8388609, 16777217);
return;
}
else if(3 == number_of_bytes)
{
bound_values(displacement, number_of_bytes, -8388609, 8388608);
return;
}
else if(absolute && (2 == number_of_bytes))
{
bound_values(displacement, number_of_bytes, -32769, 65536);
return;
}
else if(2 == number_of_bytes)
{
bound_values(displacement, number_of_bytes, -32769, 32768);
return;
}
else if(absolute && (1 == number_of_bytes))
{
bound_values(displacement, number_of_bytes, -1, 256);
return;
}
else if(1 == number_of_bytes)
{ /* work around current only signed bytes */
bound_values(displacement, number_of_bytes, -129, 256);
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;
int absolute = FALSE;
if('!' == c) number_of_bytes = 1;
else if('@' == c) number_of_bytes = 2;
else if('$' == c)
{
number_of_bytes = 2;
absolute = TRUE;
}
else if('~' == c) number_of_bytes = 3;
else if('%' == c) number_of_bytes = 4;
else if('&' == c)
{
number_of_bytes = 4;
absolute = TRUE;
}
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, absolute);
/* don't truncate prior to range check for -1 behavior */
if('!' == c) value = value & 0xFF;
else if(('@' == c) || ('$' == c)) value = value & 0xFFFF;
else if('~' == c) value = value & 0xFFFFFF;
else if(('%' == c) || ('&' == c)) value = value & 0xFFFFFFFF;
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(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))
{
if(value > 65536) continue;
else if(value > 32767) i->Expression = express_number(value, '$');
else 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*));
require(NULL != hash_table, "failed to allocate hash_table\n");
/* Create newline blob */
newline_blob = calloc(1, sizeof(struct blob));
require(NULL != newline_blob, "failed to allocate newline_blob\n");
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));
require(NULL != blob_list, "failed to allocate DEFINE blob\n");
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));
require(NULL != SCRATCH, "failed to allocate SCRATCH buffer");
int option_index = 1;
while(option_index <= argc)
{
if(NULL == argv[option_index])
{
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], "--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.5.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-1.5.2/M2libc/ 0000755 0000000 0000000 00000000000 14522760670 011756 5 ustar mescc-tools-1.5.2/M2libc/.git 0000644 0000000 0000000 00000000037 14522760670 012542 0 ustar gitdir: ../.git/modules/M2libc
mescc-tools-1.5.2/M2libc/LICENSE 0000644 0000000 0000000 00000104515 14522760670 012771 0 ustar 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-1.5.2/M2libc/README.md 0000644 0000000 0000000 00000000221 14522760670 013230 0 ustar Inside is a standard C library for those who need to bootstrap from nothing.
As all of the pieces inside will work with M2-Planet and mescc-tools mescc-tools-1.5.2/M2libc/aarch64/ 0000755 0000000 0000000 00000000000 14522760670 013206 5 ustar mescc-tools-1.5.2/M2libc/aarch64/ELF-aarch64-debug.hex2 0000644 0000000 0000000 00000006405 14522760670 016723 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### Copyright (C) 2020 deesix
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
B7 00 # e_machine Indicating AArch64
01 00 00 00 # e_version Indicating original elf
&_start 00 00 00 00 # e_entry Address of the entry point
%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
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # ph_offset
&ELF_base 00 00 00 00 # ph_vaddr
&ELF_base 00 00 00 00 # ph_physaddr
%ELF_end>ELF_base 00 00 00 00 # ph_filesz
%ELF_end>ELF_base 00 00 00 00 # ph_memsz
01 00 00 00 00 00 00 00 # ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/aarch64/ELF-aarch64.hex2 0000644 0000000 0000000 00000006405 14522760670 015637 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### Copyright (C) 2020 deesix
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
B7 00 # e_machine Indicating AArch64
01 00 00 00 # e_version Indicating original elf
&_start 00 00 00 00 # e_entry Address of the entry point
%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
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # ph_offset
&ELF_base 00 00 00 00 # ph_vaddr
&ELF_base 00 00 00 00 # ph_physaddr
%ELF_end>ELF_base 00 00 00 00 # ph_filesz
%ELF_end>ELF_base 00 00 00 00 # ph_memsz
01 00 00 00 00 00 00 00 # ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/aarch64/aarch64_defs.M1 0000644 0000000 0000000 00000010457 14522760670 015645 0 ustar ## Copyright (C) 2020 deesix
## Copyright (C) 2020 Sanne Wouda
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
DEFINE NULL 0000000000000000
# Stack (x18 as SP, 64 bits per element)
DEFINE PUSH_X0 408e1ff8
DEFINE PUSH_X1 418e1ff8
DEFINE PUSH_X16 508e1ff8
DEFINE PUSH_BP 518e1ff8
DEFINE PUSH_LR 5e8e1ff8
DEFINE POP_X0 408640f8
DEFINE POP_X1 418640f8
DEFINE POP_X16 508640f8
DEFINE POP_BP 518640f8
DEFINE POP_LR 5e8640f8
DEFINE INIT_SP f2030091 # mov x18, sp
# Jump/branch/call/return
DEFINE BR_X16 00021fd6
DEFINE BLR_X16 00023fd6
DEFINE RETURN c0035fd6
DEFINE CBZ_X0_PAST_BR a00000b4
DEFINE CBNZ_X0_PAST_BR a00000b5
DEFINE SKIP_INST_EQ 40000054
DEFINE SKIP_INST_NE 41000054
DEFINE SKIP_INST_LT 4b000054
DEFINE SKIP_INST_LE 4d000054
DEFINE SKIP_INST_GT 4c000054
DEFINE SKIP_INST_GE 4a000054
DEFINE SKIP_INST_LO 43000054
DEFINE SKIP_INST_LS 49000054
DEFINE SKIP_INST_HS 42000054
DEFINE SKIP_INST_HI 48000054
DEFINE SKIP_32_DATA 02000014
# Load literals (PC-relative)
DEFINE LOAD_W0_AHEAD 40000098
DEFINE LOAD_W1_AHEAD 41000018
DEFINE LOAD_W2_AHEAD 42000018
DEFINE LOAD_W16_AHEAD 50000018
# Load/store/dereference
DEFINE LDR_X0_[SP] 400240f9
DEFINE STR_X0_[X1] 200000f9
DEFINE STR_W0_[X1] 200000B9
DEFINE STRH_W0_[X1] 20000079
DEFINE STR_BYTE_W0_[X1] 20000039
DEFINE DEREF_X0 000040f9
DEFINE DEREF_X1 210040f9
DEFINE LDRH_W0_[X0] 00004079
DEFINE LDRSB_X0_[X0] 00008039
DEFINE LDRSH_X0_[X0] 00008079
DEFINE LDR_W0_[X0] 000040B9
DEFINE DEREF_X0_BYTE 00004039
DEFINE DEREF_X1_BYTE 21004039
# Move data between registers
DEFINE SET_X0_FROM_BP e00311aa
DEFINE SET_X1_FROM_X0 e10300aa
DEFINE SET_X1_FROM_SP e10312aa
DEFINE SET_X2_FROM_X0 e20300aa
DEFINE SET_X3_FROM_X0 e30300aa
DEFINE SET_X4_FROM_X0 e40300aa
DEFINE SET_X5_FROM_X0 e50300aa
DEFINE SET_X6_FROM_X0 e60300aa
DEFINE SET_X16_FROM_X0 f00300aa
DEFINE SET_X16_FROM_SP f00312aa
DEFINE SET_BP_FROM_X16 f10310aa
DEFINE SET_BP_FROM_SP f10312aa
# Move constant to register
DEFINE SET_X0_TO_0 000080d2
DEFINE SET_X0_TO_1 200080d2
DEFINE SET_X0_TO_17 200280d2
DEFINE SET_X0_TO_MINUS_1 00008092
DEFINE SET_W0_TO_MINUS_1 00008012
DEFINE SET_X1_TO_0 010080d2
DEFINE SET_X1_TO_2 410080d2
DEFINE SET_X1_TO_8 010180d2
DEFINE SET_X2_TO_1 220080d2
DEFINE SET_X0_TO_FCNTL_H_AT_FDCWD 600c8092
# Arith/logic/relational
DEFINE ADD_X0_X1_X0 2000008b
DEFINE ADD_X0_BP_X0 2002008b
DEFINE ADD_X1_SP_8 41220091
DEFINE SUB_X0_X1_X0 200000cb
DEFINE SUB_X0_X0_X1 000001cb
DEFINE SUB_X0_8 002000d1
DEFINE SUB_X0_16 004000d1
DEFINE SUB_X0_24 006000d1
DEFINE MSUB_X0_X0_X2_X1 0084029b
DEFINE MUL_X0_X1_X0 207c009b
DEFINE SDIV_X0_X1_X0 200cc09a
DEFINE SDIV_X2_X1_X0 220cc09a
DEFINE UDIV_X0_X1_X0 2008c09a
DEFINE UDIV_X2_X1_X0 2208c09a
DEFINE LSHIFT_X0_X0_X2 0020c29a
DEFINE LSHIFT_X0_X1_X0 2020c09a
DEFINE LOGICAL_RSHIFT_X0_X1_X0 2024c09a
DEFINE ARITH_RSHIFT_X0_X1_X0 2028c09a
DEFINE MVN_X0 e00320aa
DEFINE AND_X0_X1_X0 2000008a
DEFINE OR_X0_X1_X0 200000aa
DEFINE XOR_X0_X1_X0 000001ca
DEFINE CMP_X1_X0 3f0000eb
# Syscall
DEFINE SET_X8_TO_SYS_BRK c81a80d2
DEFINE SET_X8_TO_SYS_CHDIR 280680d2
DEFINE SET_X8_TO_SYS_CLONE 881b80d2
DEFINE SET_X8_TO_SYS_CLOSE 280780d2
DEFINE SET_X8_TO_SYS_EXECVE a81b80d2
DEFINE SET_X8_TO_SYS_EXIT a80b80d2
DEFINE SET_X8_TO_SYS_FACCESSAT 080680d2
DEFINE SET_X8_TO_SYS_FCHDIR 480680d2
DEFINE SET_X8_TO_SYS_FCHMOD 880680d2
DEFINE SET_X8_TO_SYS_FCHMODAT a80680d2
DEFINE SET_X8_TO_SYS_GETCWD 280280d2
DEFINE SET_X8_TO_SYS_LSEEK c80780d2
DEFINE SET_X8_TO_SYS_MKDIR c88080d2
DEFINE SET_X8_TO_SYS_MKNOD 688080d2
DEFINE SET_X8_TO_SYS_OPENAT 080780d2
DEFINE SET_X8_TO_SYS_READ e80780d2
DEFINE SET_X8_TO_SYS_UNAME 081480d2
DEFINE SET_X8_TO_SYS_WAIT4 882080d2
DEFINE SET_X8_TO_SYS_WRITE 080880d2
DEFINE SET_X8_TO_SYS_UNLINK 488080d2
DEFINE SET_X8_TO_SYS_UMASK c81480d2
DEFINE SYSCALL 010000d4
mescc-tools-1.5.2/M2libc/aarch64/libc-core.M1 0000644 0000000 0000000 00000002275 14522760670 015252 0 ustar ## Copyright (C) 2020 deesix
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
INIT_SP
LDR_X0_[SP]
ADD_X1_SP_8
SET_BP_FROM_SP
PUSH_X0
PUSH_X1
SET_X1_TO_2
ADD_X0_X1_X0
SET_X1_TO_8
MUL_X0_X1_X0
ADD_X0_BP_X0
PUSH_X0
LOAD_W16_AHEAD
SKIP_32_DATA
&FUNCTION_main
BLR_X16
POP_X1
POP_X1
POP_X1
PUSH_X0 ; Put return on the stack
PUSH_X0 ; So that _exit has it
PUSH_X0 ; So that _exit has it
:FUNCTION_exit
:FUNCTION__exit
SET_X0_FROM_BP
SUB_X0_8
DEREF_X0
SET_X8_TO_SYS_EXIT
SYSCALL
mescc-tools-1.5.2/M2libc/aarch64/libc-full.M1 0000644 0000000 0000000 00000003022 14522760670 015253 0 ustar ## Copyright (C) 2020 deesix
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
INIT_SP
LDR_X0_[SP]
ADD_X1_SP_8
SET_BP_FROM_SP
PUSH_X0
PUSH_X1
SET_X1_TO_2
ADD_X0_X1_X0
SET_X1_TO_8
MUL_X0_X1_X0
ADD_X0_BP_X0
PUSH_X0
;; Setup for _envp
LOAD_W1_AHEAD
SKIP_32_DATA
&GLOBAL__envp
STR_X0_[X1]
;; Setup for malloc
LOAD_W16_AHEAD
SKIP_32_DATA
&FUNCTION___init_malloc
BLR_X16
;; Setup for FILE*
LOAD_W16_AHEAD
SKIP_32_DATA
&FUNCTION___init_io
BLR_X16
;; Call main
LOAD_W16_AHEAD
SKIP_32_DATA
&FUNCTION_main
BLR_X16
POP_X1
POP_X1
POP_X1
PUSH_X0 ; Put return on the stack
PUSH_X0 ; So that _exit has it
PUSH_X0 ; So that _exit has it
:FUNCTION_exit
LOAD_W16_AHEAD
SKIP_32_DATA
&FUNCTION___kill_io
BLR_X16
:FUNCTION__exit
SET_X0_FROM_BP
SUB_X0_8
DEREF_X0
SET_X8_TO_SYS_EXIT
SYSCALL
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/aarch64/linux/ 0000755 0000000 0000000 00000000000 14522760670 014345 5 ustar mescc-tools-1.5.2/M2libc/aarch64/linux/bootstrap.c 0000644 0000000 0000000 00000006353 14522760670 016535 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2020 deesix
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"PUSH_X0"
"SET_X1_FROM_SP"
"SET_X2_TO_1"
"SET_X8_TO_SYS_READ"
"SYSCALL"
"SET_X1_TO_0"
"CMP_X1_X0"
"POP_X0"
"SKIP_INST_NE"
"SET_X0_TO_MINUS_1");
}
void fputc(char s, FILE* f)
{
asm("SET_X0_FROM_BP" "SUB_X0_8"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_TO_1"
"SET_X8_TO_SYS_WRITE"
"SYSCALL");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X3_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_OPENAT"
"SYSCALL");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_CLOSE"
"SYSCALL");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_BRK"
"SYSCALL");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_EXIT"
"SYSCALL");
}
mescc-tools-1.5.2/M2libc/aarch64/linux/fcntl.c 0000644 0000000 0000000 00000002642 14522760670 015623 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2020 deesix
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X3_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_OPENAT"
"SYSCALL");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/aarch64/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 015163 5 ustar mescc-tools-1.5.2/M2libc/aarch64/linux/sys/stat.c 0000644 0000000 0000000 00000004553 14522760670 016311 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_0"
"SET_X3_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_FCHMODAT"
"SYSCALL");
}
int fchmod(int a, mode_t b)
{
asm("SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_0"
"SET_X3_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_FCHMOD"
"SYSCALL");
}
int mkdir(char const* a, mode_t b)
{
asm("SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_0"
"SET_X3_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_MKDIR"
"SYSCALL");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("SET_X0_TO_MINUS_1"
"SET_X3_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_MKNOD"
"SYSCALL");
}
mode_t umask(mode_t m)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_UMASK"
"SYSCALL");
}
#endif
mescc-tools-1.5.2/M2libc/aarch64/linux/unistd.c 0000644 0000000 0000000 00000010447 14522760670 016025 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2020 deesix
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_TO_0"
"SET_X3_FROM_X0"
"SET_X0_TO_FCNTL_H_AT_FDCWD"
"SET_X8_TO_SYS_FACCESSAT"
"SYSCALL");
}
int chdir(char* path)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_CHDIR"
"SYSCALL");
}
int fchdir(int fd)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_FCHDIR"
"SYSCALL");
}
void _exit(int value);
int fork()
{
asm("SET_X0_TO_0"
"SET_X1_FROM_X0"
"SET_X2_FROM_X0"
"SET_X3_FROM_X0"
"SET_X4_FROM_X0"
"SET_X5_FROM_X0"
"SET_X6_FROM_X0"
"SET_X0_TO_17"
"SET_X8_TO_SYS_CLONE"
"SYSCALL");
}
int waitpid (int pid, int* status_ptr, int options)
{
asm("SET_X0_TO_MINUS_1"
"SET_X3_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_WAIT4"
"SYSCALL");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_EXECVE"
"SYSCALL");
}
int read(int fd, char* buf, unsigned count)
{
asm("SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_READ"
"SYSCALL");
}
int write(int fd, char* buf, unsigned count)
{
asm("SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_WRITE"
"SYSCALL");
}
int lseek(int fd, int offset, int whence)
{
asm("SET_X0_TO_MINUS_1"
"SET_X3_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_24" "DEREF_X0"
"SET_X2_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_LSEEK"
"SYSCALL");
}
int close(int fd)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_CLOSE"
"SYSCALL");
}
int unlink (char* filename)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_UNLINK"
"SYSCALL");
}
int _getcwd(char* buf, int size)
{
asm("SET_X0_FROM_BP" "SUB_X0_16" "DEREF_X0"
"SET_X1_FROM_X0"
"SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_GETCWD"
"SYSCALL");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_BRK"
"SYSCALL");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
"SET_X8_TO_SYS_UNAME"
"SYSCALL");
}
#endif
mescc-tools-1.5.2/M2libc/amd64/ 0000755 0000000 0000000 00000000000 14522760670 012671 5 ustar mescc-tools-1.5.2/M2libc/amd64/ELF-amd64-debug.hex2 0000644 0000000 0000000 00000006324 14522760670 016071 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
%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
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # ph_offset
&ELF_base 00 00 00 00 # ph_vaddr
&ELF_base 00 00 00 00 # ph_physaddr
%ELF_end>ELF_base 00 00 00 00 # ph_filesz
%ELF_end>ELF_base 00 00 00 00 # ph_memsz
01 00 00 00 00 00 00 00 # ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/amd64/ELF-amd64.hex2 0000644 0000000 0000000 00000006324 14522760670 015005 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
%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
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 # ph_type: PT-LOAD = 1
07 00 00 00 # ph_flags: PF-X|PF-W|PF-R = 7
00 00 00 00 00 00 00 00 # ph_offset
&ELF_base 00 00 00 00 # ph_vaddr
&ELF_base 00 00 00 00 # ph_physaddr
%ELF_end>ELF_base 00 00 00 00 # ph_filesz
%ELF_end>ELF_base 00 00 00 00 # ph_memsz
01 00 00 00 00 00 00 00 # ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/amd64/amd64_defs.M1 0000644 0000000 0000000 00000007033 14522760670 015007 0 ustar ## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
DEFINE add_rax, 4805
DEFINE add_rbp, 4881C5
DEFINE add_rsp, 4881C4
DEFINE add_rax,rbx 4801D8
DEFINE add_rax,rbp 4801E8
DEFINE add_rbx,rax 4801C3
DEFINE and_rax,rbx 4821D8
DEFINE call E8
DEFINE call_rax FFD0
DEFINE cmp_rbx,rax 4839C3
DEFINE cqo 4899
DEFINE div_rbx 48F7F3
DEFINE idiv_rbx 48F7FB
DEFINE jmp E9
DEFINE je 0F84
DEFINE jne 0F85
DEFINE lea_rax,[rbp+DWORD] 488D85
DEFINE lea_rax,[rip+DWORD] 488D05
DEFINE lea_rbx,[rip+DWORD] 488D1D
DEFINE lea_rcx,[rbp+DWORD] 488D8D
DEFINE lea_rdi,[rsp+DWORD] 488DBC24
DEFINE lea_rdx,[rip+DWORD] 488D15
DEFINE lea_rdx,[rsp+DWORD] 488D9424
DEFINE lea_rdx,[rbp+DWORD] 488D95
DEFINE lea_rsi,[rsp+DWORD] 488DB424
DEFINE lea_r8,[rbp+DWORD] 4C8D85
DEFINE lea_r9,[rbp+DWORD] 4C8D8D
DEFINE mov_rax, 48C7C0
DEFINE mov_rbx, 48C7C3
DEFINE mov_rdi, 48C7C7
DEFINE mov_rdx, 48C7C2
DEFINE mov_rsi, 48C7C6
DEFINE mov_r10, 49C7C2
DEFINE mov_rax,rdx 4889D0
DEFINE mov_rax,rbx 4889D8
DEFINE mov_rax,rbp 4889E8
DEFINE mov_rbp,rdi 4889FD
DEFINE mov_rbp,rsp 4889E5
DEFINE mov_rcx,rax 4889C1
DEFINE mov_rdi,rax 4889C7
DEFINE mov_rdi,rbx 4889DF
DEFINE mov_rdi,rsp 4889E7
DEFINE mov_rdx,rsp 4889E2
DEFINE mov_r8,rsp 4989E0
DEFINE mov_[rbx],al 8803
DEFINE mov_[rbx],ax 668903
DEFINE mov_[rbx],eax 8903
DEFINE mov_[rbx],rax 488903
DEFINE mov_[rip+DWORD],rax 488905
DEFINE mov_[rip+DWORD],rbp 48892D
DEFINE mov_[rip+DWORD],rcx 48890D
DEFINE mov_[rip+DWORD],rdx 488915
DEFINE mov_[rip+DWORD],rsp 488925
DEFINE mov_eax,[rax] 8B00
DEFINE mov_rax,[rax] 488B00
DEFINE mov_rbx,[rbx] 488B1B
DEFINE mov_rcx,[rcx] 488B09
DEFINE mov_rdi,[rdi] 488B3F
DEFINE mov_rdx,[rdx] 488B12
DEFINE mov_rsi,[rsi] 488B36
DEFINE mov_rax,[rsp+DWORD] 488B8424
DEFINE mov_rax,[rip+DWORD] 488B05
DEFINE mov_rbp,[rip+DWORD] 488B2D
DEFINE mov_rsp,[rip+DWORD] 488B25
DEFINE mov_r8,[r8] 4D8B00
DEFINE mov_r9,[r9] 4D8B09
DEFINE movzx_rax,al 480FB6C0
DEFINE movsxd_rax,eax 4863C0
DEFINE movsx_rax,BYTE_PTR_[rax] 480FBE00
DEFINE movsx_rbx,BYTE_PTR_[rbx] 480FBE1B
DEFINE movsx_rax,WORD_PTR_[rax] 480FBF00
DEFINE movsx_rax,DWORD_PTR_[rax] 486300
DEFINE movzx_rax,BYTE_PTR_[rax] 480FB600
DEFINE movzx_rax,WORD_PTR_[rax] 480FB700
DEFINE imul_rbx 48F7EB
DEFINE mul_rbx 48F7E3
DEFINE NULL 0000000000000000
DEFINE not_rax 48F7D0
DEFINE or_rax,rbx 4809D8
DEFINE pop_rax 58
DEFINE pop_rbp 5D
DEFINE pop_rbx 5B
DEFINE pop_rdi 5F
DEFINE push 6A
DEFINE push_rax 50
DEFINE push_rbp 55
DEFINE push_rbx 53
DEFINE push_rdi 57
DEFINE ret C3
DEFINE sal_rax, 48C1E0
DEFINE shl_rax,cl 48D3E0
DEFINE sal_rax,cl 48D3F0
DEFINE shr_rax,cl 48D3E8
DEFINE sar_rax,cl 48D3F8
DEFINE seta_al 0F97C0
DEFINE setae_al 0F93C0
DEFINE setb_al 0F92C0
DEFINE setbe_al 0F96C0
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 sub_rsp, 4881EC
DEFINE sub_rbx,rax 4829C3
DEFINE syscall 0F05
DEFINE test_rax,rax 4885C0
DEFINE xchg_rbx,rax 4893
DEFINE xor_rax,rbx 4831D8
mescc-tools-1.5.2/M2libc/amd64/libc-core.M1 0000644 0000000 0000000 00000002763 14522760670 014737 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_rbp,rsp ; Protect rsp
;; Prepare argv
lea_rax,[rbp+DWORD] %8 ; ARGV_address = RBP + 8
push_rax ; Put argv on the stack
;; Prepare envp
mov_rax,rbp ; Address we need to load from
mov_rax,[rax] ; Get ARGC
add_rax, %2 ; OFFSET = ARGC + 2
sal_rax, !3 ; OFFSET = OFFSET * WORDSIZE
add_rax,rbp ; ENVP_address = RSP + OFFSET
push_rax ; Put envp on the stack
;; Stack offset
add_rbp, %8 ; Fix rbp
;; Perform the main loop
call %FUNCTION_main
push_rax ; Put return value on the stack
push_rax ; So that _exit gets it
:FUNCTION_exit
:FUNCTION__exit
pop_rbx
pop_rdi
mov_rax, %0x3C
syscall
mescc-tools-1.5.2/M2libc/amd64/libc-full.M1 0000644 0000000 0000000 00000003364 14522760670 014747 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_rbp,rsp ; Protect rsp
;; Prepare argv
lea_rax,[rbp+DWORD] %8 ; ARGV_address = RBP + 8
push_rax ; Put argv on the stack
;; Prepare envp
mov_rax,rbp ; Address we need to load from
mov_rax,[rax] ; Get ARGC
add_rax, %2 ; OFFSET = ARGC + 2
sal_rax, !3 ; OFFSET = OFFSET * WORDSIZE
add_rax,rbp ; ENVP_address = RSP + OFFSET
push_rax ; Put envp on the stack
lea_rbx,[rip+DWORD] %GLOBAL__envp ; Get _envp global
mov_[rbx],rax ; Save environment to _envp
;; Stack offset
add_rbp, %8 ; Fix rbp
;; Setup for malloc
call %FUNCTION___init_malloc
;; Setup for FILE*
call %FUNCTION___init_io
;; Perform the main loop
call %FUNCTION_main
push_rax ; Put return value on the stack
push_rax ; So that _exit gets it
:FUNCTION_exit
call %FUNCTION___kill_io
:FUNCTION__exit
pop_rbx
pop_rdi
mov_rax, %0x3C
syscall
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/amd64/linux/ 0000755 0000000 0000000 00000000000 14522760670 014030 5 ustar mescc-tools-1.5.2/M2libc/amd64/linux/bootstrap.c 0000644 0000000 0000000 00000006206 14522760670 016215 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %0"
"push_rax"
"lea_rsi,[rsp+DWORD] %0"
"mov_rdx, %1"
"syscall"
"mov_rbx, %0"
"cmp_rbx,rax"
"pop_rax"
"jne %FUNCTION_fgetc_Done"
"mov_rax, %-1"
":FUNCTION_fgetc_Done");
}
void fputc(char s, FILE* f)
{
asm("mov_rax, %1"
"lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rdx, %1"
"syscall");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %2"
"syscall");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %3"
"syscall");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("mov_rax,[rsp+DWORD] %8"
"push_rax"
"mov_rax, %12"
"pop_rbx"
"mov_rdi,rbx"
"syscall");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("pop_rbx"
"pop_rdi"
"mov_rax, %0x3C"
"syscall");
}
mescc-tools-1.5.2/M2libc/amd64/linux/fcntl.c 0000644 0000000 0000000 00000002434 14522760670 015305 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %2"
"syscall");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/amd64/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 014646 5 ustar mescc-tools-1.5.2/M2libc/amd64/linux/sys/stat.c 0000644 0000000 0000000 00000003714 14522760670 015772 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("lea_rdi,[rsp+DWORD] %16"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %8"
"mov_rsi,[rsi]"
"mov_rax, %90"
"syscall");
}
int fchmod(int a, mode_t b)
{
asm("lea_rdi,[rsp+DWORD] %16"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %8"
"mov_rsi,[rsi]"
"mov_rax, %91"
"syscall");
}
int mkdir(char const* a, mode_t b)
{
asm("lea_rdi,[rsp+DWORD] %16"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %8"
"mov_rsi,[rsi]"
"mov_rax, %83"
"syscall");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %133"
"syscall");
}
mode_t umask(mode_t m)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %95"
"syscall");
}
#endif
mescc-tools-1.5.2/M2libc/amd64/linux/unistd.c 0000644 0000000 0000000 00000007527 14522760670 015515 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("lea_rdi,[rsp+DWORD] %16"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %8"
"mov_rsi,[rsi]"
"mov_rax, %21"
"syscall");
}
int chdir(char* path)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %80"
"syscall");
}
int fchdir(int fd)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %81"
"syscall");
}
void _exit(int value);
int fork()
{
asm("mov_rax, %57"
"mov_rdi, %0"
"syscall");
}
int waitpid (int pid, int* status_ptr, int options)
{
/* Uses wait4 with struct rusage *ru set to NULL */
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_r10, %0"
"mov_rax, %61"
"syscall");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %59"
"syscall");
}
int read(int fd, char* buf, unsigned count)
{ /*maybe*/
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %0"
"syscall");
}
int write(int fd, char* buf, unsigned count)
{/*maybe*/
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %1"
"syscall");
}
int lseek(int fd, int offset, int whence)
{
asm("lea_rdi,[rsp+DWORD] %24"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %16"
"mov_rsi,[rsi]"
"lea_rdx,[rsp+DWORD] %8"
"mov_rdx,[rdx]"
"mov_rax, %8"
"syscall");
}
int close(int fd)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %3"
"syscall");
}
int unlink (char* filename)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %87"
"syscall");
}
int _getcwd(char* buf, int size)
{
asm("lea_rdi,[rsp+DWORD] %16"
"mov_rdi,[rdi]"
"lea_rsi,[rsp+DWORD] %8"
"mov_rsi,[rsi]"
"mov_rax, %79"
"syscall");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("mov_rax,[rsp+DWORD] %8"
"push_rax"
"mov_rax, %12"
"pop_rbx"
"mov_rdi,rbx"
"syscall");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("lea_rdi,[rsp+DWORD] %8"
"mov_rdi,[rdi]"
"mov_rax, %63"
"syscall");
}
#endif
mescc-tools-1.5.2/M2libc/amd64/uefi/ 0000755 0000000 0000000 00000000000 14522760670 013621 5 ustar mescc-tools-1.5.2/M2libc/amd64/uefi/PE32-amd64.hex2 0000644 0000000 0000000 00000013074 14522760670 016000 0 ustar # SPDX-FileCopyrightText: 2022 Jeremiah Orians
#
# SPDX-License-Identifier: GPL-3.0-or-later
:PE32_base
# DOS MZ header
4D 5A # Signature
00 00 # Number of bytes in the last page.
00 00 # Number of whole/partial pages
00 00 # Number of entries in the relocation table.
00 00 # Header size
00 00 # Minimum allocation
00 00 # Maximum allocation
00 00 # Relocatable segment address for SS
00 00 # Initial value for SP
00 00 # Checksum (I don't think is looked at)
00 00 # Initial value for IP (Seems ignored)
00 00 # Relocatable segment address for CS (Seems ignored)
00 00 # The (absolute) offset to the relocation table.
00 00 # Value used for overlay management. If zero, this is the main executable
00 00 00 00 00 00 00 00 # Reserved in PE
00 00 # OEM identifier
00 00 # OEM info
00 00 00 00 00 00 00 00 00 00 # The required reserved 20 bytes of NULLS
00 00 00 00 00 00 00 00 00 00
40 00 00 00 # Starting address of the PE header
# [0x40]
:PE_header
50 45 00 00 # Signature "PE"
64 86 # Machine
01 00 # number of sections
00 00 00 00 # Timestamp supposedly
00 00 00 00 # PointerToSymbolTable
00 00 00 00 # number of symbols
@OptionalHeader_end>PE_header # SizeOfOptionalHeader
00 00 # 'Characteristics'
# [0x58]
# COFF header bits
0B 02 # Magic PE32+ (64 bit)
00 00 # Linker version
00 00 00 00 # size of code
00 00 00 00 # sizeOfInitializedData
00 00 00 00 # SizeOfUninitializedData
00 10 00 00 # AddressOfEntryPoint
00 00 00 00 # BaseOfCode
00 00 00 00 00 00 00 00 # ImageBase
01 00 00 00 # SectionAlignment
01 00 00 00 # FileAlignment
00 00 00 00 # OperatingSystemVersion
00 00 00 00 # ImageVersion
00 00 00 00 # SubsystemVersion
00 00 00 00 # Win32VersionValue
00 00 10 00 # SizeOfImage
%PE32_text>PE32_base # SizeOfHeaders
00 00 00 00 # CheckSum (isn't used at all)
0A 00 # Subsystem
00 00 # DllCharacteristics
00 00 00 00 # SizeOfStackReserve
00 00 00 00 # SizeOfStackCommit
00 00 00 00 # SizeOfHeapReserve
00 00 00 00 # SizeOfHeapCommit
00 00 00 00 # LoaderFlags
00 00 00 00 # NumberOfRvaAndSizes
# [0xB8]
# Data directories (has to be 16 entries always 16bytes per entry)
00 00 00 00 # Export Table
00 00 00 00 # Size of Export Table
00 00 00 00 # Import Table
10 00 00 00 # Size of Import Table
00 00 00 00 # Resource Table
00 00 00 00 # Size of Resource Table
00 00 00 00 # Exception Table
00 00 00 00 # Size of Exception Table
00 00 00 00 # Certificate Table
00 00 00 00 # Size of Certificate Table
00 00 00 00 # Base Relocation Table
00 00 00 00 # Size of Base Relocation Table
00 00 00 00 # Debug Table
00 00 00 00 # Size of Debug Table
00 00 00 00 # Architecture Data Table
00 00 00 00 # Size of Architecture Data Table
00 00 00 00 # Global Pointer
00 00 00 00 # NULL
00 00 00 00 # TLS Table
00 00 00 00 # Size of TLS Table
00 00 00 00 # Load Config Table
00 00 00 00 # Size of Load Config Table
00 00 00 00 # Bound Import Table
00 00 00 00 # Size of Bound Import Table
00 00 00 00 # Import Address Table
00 00 00 00 # Size of Import Address Table
00 00 00 00 # Delay Import Descriptor Table
00 00 00 00 # Size of Delay Import Descriptor Table
00 00 00 00 # CLR Runtime header table
00 00 00 00 # Size of CLR Runtime Header table
# [0x130]
:OptionalHeader_end
00 00 00 00 00 00 00 00 # MUST BE NULL
# no idea what it is yet
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
# [0x148]
# Start of section headers
2E 74 65 78 74 00 00 00 ; Name of the section: ".text"
%ELF_end>PE32_text ; VirtualSize
00 10 00 00 ; VirtualAddress
%ELF_end>PE32_text ; SizeOfRawData
70 01 00 00 ; PointerToRawData
00 00 00 00 ; PointerToRelocations
00 00 00 00 ; PointerToLinenumbers
00 00 ; NumberOfRelocations
00 00 ; NumberOfLinenumbers
00 00 00 00 ; 'Characteristics'
# [0x170]
:PE32_text
mescc-tools-1.5.2/M2libc/amd64/uefi/bootstrap.c 0000644 0000000 0000000 00000033535 14522760670 016013 0 ustar /* Copyright (C) 2022 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
/* UEFI */
// CONSTANT PAGE_SIZE 4096
// CONSTANT PAGE_NUM 16384
// CONSTANT USER_STACK_SIZE 8388608
// CONSTANT EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 1
// CONSTANT EFI_FILE_MODE_READ 1
// CONSTANT EFI_FILE_MODE_WRITE 2
// CONSTANT EFI_FILE_READ_ONLY 1
// CONSTANT EFI_ALLOCATE_ANY_PAGES 0
// CONSTANT EFI_LOADER_DATA 2
void exit(unsigned value);
void* _image_handle;
void* _root_device;
void* __user_stack;
void* _malloc_start;
long _malloc_ptr;
long _brk_ptr;
int _argc;
char** _argv;
struct efi_simple_text_output_protocol
{
void* reset;
void* output_string;
void* test_string;
void* query_mode;
void* set_mode;
void* set_attribute;
void* clear_screen;
void* set_cursor;
void* enable_cursor;
void* mode;
};
struct efi_table_header
{
unsigned signature;
unsigned revision_and_header_size;
unsigned crc32_and_reserved;
};
struct efi_boot_table
{
struct efi_table_header header;
/* Task Priority Services */
void* raise_tpl;
void* restore_tpl;
/* Memory Services */
void* allocate_pages;
void* free_pages;
void* get_memory_map;
void* allocate_pool;
void* free_pool;
/* Event & Timer Services */
void* create_event;
void* set_timer;
void* wait_for_event;
void* signal_event;
void* close_event;
void* check_event;
/* Protocol Handler Services */
void* install_protocol_interface;
void* reinstall_protocol_interface;
void* uninstall_protocol_interface;
void* handle_protocol;
void* reserved;
void* register_protocol_notify;
void* locate_handle;
void* locate_device_path;
void* install_configuration_table;
/* Image Services */
void* load_image;
void* start_image;
void* exit;
void* unload_image;
void* exit_boot_services;
/* Miscellaneous Services */
void* get_next_monotonic_count;
void* stall;
void* set_watchdog_timer;
/* DriverSupport Services */
void* connect_controller;
void* disconnect_controller;
/* Open and Close Protocol Services */
void* open_protocol;
void* close_protocol;
void* open_protocol_information;
/* Library Services */
void* protocols_per_handle;
void* locate_handle_buffer;
void* locate_protocol;
void* install_multiple_protocol_interfaces;
void* uninstall_multiple_protocol_interfaces;
/* 32-bit CRC Services */
void* copy_mem;
void* set_mem;
void* create_event_ex;
};
struct efi_system_table
{
struct efi_table_header header;
char* firmware_vendor;
unsigned firmware_revision;
void* console_in_handle;
void* con_in;
void* console_out_handle;
struct efi_simple_text_output_protocol* con_out;
void *standard_error_handle;
struct efi_simple_text_output_protocol* std_err;
void *runtime_services;
struct efi_boot_table* boot_services;
unsigned number_table_entries;
void *configuration_table;
};
struct efi_system_table* _system;
struct efi_guid
{
unsigned data1;
unsigned data2;
};
struct efi_guid* EFI_LOADED_IMAGE_PROTOCOL_GUID;
struct efi_guid* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
struct efi_loaded_image_protocol
{
unsigned revision;
void* parent;
void* system;
void* device;
void* filepath;
void* reserved;
/* Image's load options */
unsigned load_options_size;
void* load_options;
/* Location of the image in memory */
void* image_base;
unsigned image_size;
unsigned image_code_type;
unsigned image_data_type;
void* unload;
};
struct efi_simple_file_system_protocol
{
unsigned revision;
void* open_volume;
};
struct efi_file_protocol
{
unsigned revision;
void* open;
void* close;
void* delete;
void* read;
void* write;
void* get_position;
void* set_position;
void* get_info;
void* set_info;
void* flush;
void* open_ex;
void* read_ex;
void* write_ex;
void* flush_ex;
};
struct efi_file_protocol* _rootdir;
char _read(FILE* f, unsigned size, FUNCTION read)
{
/* f->read(f, &size, &c) */
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"push !0"
"mov_r8,rsp"
"lea_rax,[rbp+DWORD] %-24"
"mov_rax,[rax]"
"sub_rsp, %24"
"call_rax"
"add_rsp, %24"
"lea_rax,[rbp+DWORD] %-16"
"mov_rax,[rax]"
"test_rax,rax"
"pop_rax"
"jne %_read_end"
"mov_rax, %0xFFFFFFFF # EOF"
":_read_end");
}
long _write(FILE* f, unsigned size, char c, FUNCTION write)
{
/* fout->write(fout, &size, &c) */
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"lea_r8,[rbp+DWORD] %-24"
"lea_rax,[rbp+DWORD] %-32"
"mov_rax,[rax]"
"sub_rsp, %24"
"call_rax"
"add_rsp, %24");
}
void _write_stdout(void* con_out, int c, FUNCTION output_string)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"lea_rax,[rbp+DWORD] %-24"
"mov_rax,[rax]"
"sub_rsp, %16"
"call_rax"
"add_rsp, %16");
}
void* _open_protocol(void* handle, struct efi_guid* protocol, void* agent_handle, void* controller_handle, long attributes, FUNCTION open_protocol)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"push !0"
"mov_r8,rsp"
"lea_r9,[rbp+DWORD] %-24"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-32"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-48"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %48"
"pop_rax");
}
int _close_protocol(void *handle, struct efi_guid* protocol, void* agent_handle, void* controller_handle, FUNCTION close_protocol)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-32"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %32");
}
int _open_volume(struct efi_simple_file_system_protocol* rootfs, FUNCTION open_volume)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"push !0"
"mov_rdx,rsp"
"lea_rax,[rbp+DWORD] %-16"
"mov_rax,[rax]"
"sub_rsp, %16"
"call_rax"
"add_rsp, %16"
"pop_rax");
}
FILE* _open(void* _rootdir, char* name, long mode, long attributes, FUNCTION open)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"push !0"
"mov_rdx,rsp"
"lea_r8,[rbp+DWORD] %-16"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-24"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-32"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %40"
"pop_rax");
}
FILE* _close(FILE* f, FUNCTION close)
{
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rax,[rbp+DWORD] %-16"
"mov_rax,[rax]"
"sub_rsp, %8"
"call_rax"
"add_rsp, %8"
);
}
/* Returns _malloc_ptr and not exit value from AllocatePages call.*/
long _allocate_pages(unsigned type, unsigned memory_type, unsigned pages, long _malloc_ptr, FUNCTION allocate_pages)
{
/* boot->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, size, &_malloc_ptr) */
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-32"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %32"
"lea_rax,[rbp+DWORD] %-32"
"mov_rax,[rax]");
}
void _free_pages(void* memory, unsigned pages, FUNCTION free_pages)
{
/* boot->free_pages(memory, pages) */
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_rax,[rbp+DWORD] %-24"
"mov_rax,[rax]"
"sub_rsp, %16"
"call_rax"
"add_rsp, %16");
}
int fgetc(FILE* f)
{
struct efi_file_protocol* file = f;
unsigned size = 1;
char c = _read(file, size, file->read);
return c;
}
void fputc(char c, FILE* f)
{
unsigned size = 1;
/* In UEFI StdErr might not be printing stuff to console, so just use stdout */
if(f == stdout || f == stderr)
{
_write_stdout(_system->con_out, c, _system->con_out->output_string);
if('\n' == c)
{
_write_stdout(_system->con_out, '\r', _system->con_out->output_string);
}
return;
}
struct efi_file_protocol* file = f;
_write(file, size, c, file->write);
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
int strlen(char* str)
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
char* _posix_path_to_uefi(char *narrow_string);
FILE* fopen(char* filename, char* mode)
{
char* wide_filename = _posix_path_to_uefi(filename);
FILE* f;
long status;
if('w' == mode[0])
{
long mode = 1 << 63; /* EFI_FILE_MODE_CREATE = 0x8000000000000000 */
mode = mode | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ;
f = _open(_rootdir, wide_filename, mode, 0, _rootdir->open);
}
else
{ /* Everything else is a read */
f = _open(_rootdir, wide_filename, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY, _rootdir->open);
}
return f;
}
int fclose(FILE* stream)
{
struct efi_file_protocol* file = stream;
return _close(file, file->close);
}
/* A very primitive memory manager */
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
unsigned pages = PAGE_NUM; /* 64 MiB = 16384 * 4 KiB pages */
_malloc_ptr = _allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA, pages, _malloc_ptr, _system->boot_services->allocate_pages);
if(_malloc_ptr == 0)
{
return 0;
}
_brk_ptr = _malloc_ptr + pages * PAGE_SIZE;
}
/* We never allocate more memory in bootstrap mode */
if(_brk_ptr < _malloc_ptr + size)
{
return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(unsigned value)
{
goto FUNCTION__exit;
}
void _posix_path_to_uefi(char *narrow_string)
{
unsigned length = strlen(narrow_string) + 1;
char *wide_string = calloc(length, 2);
unsigned i;
for(i = 0; i < length; i = i + 1)
{
if(narrow_string[i] == '/')
{
wide_string[2 * i] = '\\';
}
else
{
wide_string[2 * i] = narrow_string[i];
}
}
return wide_string;
}
char* wide2string(char *wide_string, unsigned length)
{
unsigned i;
char *narrow_string = calloc(length, 1);
for(i = 0; i < length; i = i + 1)
{
narrow_string[i] = wide_string[2 * i];
}
return narrow_string;
}
int is_space(char c)
{
return (c == ' ') || (c == '\t');
}
void process_load_options(char* load_options)
{
/* Determine argc */
_argc = 1; /* command name */
char *i = load_options;
unsigned was_space = 0;
do
{
if(is_space(i[0]))
{
if(!was_space)
{
_argc = _argc + 1;
was_space = 1;
}
}
else
{
was_space = 0;
}
i = i + 1;
} while(i[0] != 0);
/* Collect argv */
_argv = calloc(_argc + 1, sizeof(char*));
i = load_options;
unsigned j;
for(j = 0; j < _argc; j = j + 1)
{
_argv[j] = i;
do
{
i = i + 1;
} while(!is_space(i[0]) && i[0] != 0);
i[0] = 0;
do
{
i = i + 1;
} while(is_space(i[0]));
}
}
void _init()
{
/* Allocate user stack, UEFI stack is not big enough for compilers */
__user_stack = malloc(USER_STACK_SIZE);
_malloc_start = __user_stack;
/* Go to the other end of allocated memory, as stack grows downwards)*/
__user_stack = __user_stack + USER_STACK_SIZE;
/* Process command line arguments */
EFI_LOADED_IMAGE_PROTOCOL_GUID = calloc(1, sizeof(struct efi_guid));
EFI_LOADED_IMAGE_PROTOCOL_GUID->data1 = (0x11D29562 << 32) + 0x5B1B31A1;
/* We want to add 0xA0003F8E but M2 treats 32-bit values as negatives, in order to
* have the same behaviour on 32-bit systems, so restrict to 31-bit constants */
EFI_LOADED_IMAGE_PROTOCOL_GUID->data2 = (0x3B7269C9 << 32) + 0x50003F8E + 0x50000000;
struct efi_loaded_image_protocol* image = _open_protocol(_image_handle, EFI_LOADED_IMAGE_PROTOCOL_GUID, _image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL, _system->boot_services->open_protocol);
char* load_options = wide2string(image->load_options, image->load_options_size);
process_load_options(load_options);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID = calloc(1, sizeof(struct efi_guid));
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID->data1 = (0x11D26459 << 32) + 0x564E5B22 + 0x40000000;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID->data2 = (0x3B7269C9 << 32) + 0x5000398E + 0x50000000;
_root_device = image->device;
struct efi_simple_file_system_protocol* rootfs = _open_protocol(_root_device, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, _image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL, _system->boot_services->open_protocol);
_rootdir = _open_volume(rootfs, rootfs->open_volume);
}
void _cleanup()
{
fclose(_rootdir);
_close_protocol(_root_device, EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, _image_handle, 0, _system->boot_services->close_protocol);
_close_protocol(_image_handle, EFI_LOADED_IMAGE_PROTOCOL_GUID, _image_handle, 0, _system->boot_services->close_protocol);
_free_pages(_malloc_start, PAGE_NUM, _system->boot_services->free_pages);
}
mescc-tools-1.5.2/M2libc/amd64/uefi/libc-core.M1 0000644 0000000 0000000 00000005777 14522760670 015677 0 ustar ## Copyright (C) 2022 Andrius Štikonas
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_rbp,rsp # save stack pointer
mov_[rip+DWORD],rsp %__return_address # save UEFI return address
mov_[rip+DWORD],rcx %GLOBAL__image_handle # save image_handle
mov_[rip+DWORD],rdx %GLOBAL__system # save system
;; Do UEFI initialization
call %FUNCTION__init
call %exit_uefi_stack # Switch to user stack
;; Perform the main loop
mov_rax,[rip+DWORD] %GLOBAL__argc # Get argc
push_rax # Push it onto stack
mov_rax,[rip+DWORD] %GLOBAL__argv # Get argv
push_rax # Push it onto stack
push !0 # envp = NULL
call %FUNCTION_main
:FUNCTION__exit
;; Do UEFI cleanup
call %enter_uefi_stack # Switch back to UEFI stack
push_rax # Save exit code
call %FUNCTION__cleanup
pop_rax # Restore exit code
:FUNCTION___exit
mov_rsp,[rip+DWORD] %__return_address # Get UEFI return address
ret
# Switch to uefi stack
# does not change any other registers except for rbp
:enter_uefi_stack
mov_[rip+DWORD],rax %__temp_rax # save RAX
pop_rax # Save return address
mov_[rip+DWORD],rsp %GLOBAL___user_stack # save user stack
mov_rsp,[rip+DWORD] %__uefi_stack # restore system stack
push_rax # Restore return address
mov_rax,[rip+DWORD] %__temp_rax # restore RAX
mov_rbp,rsp # Fix rbp
add_rbp, %8 # Fix rbp
ret
# Switch to user stack
# does not change any other registers except for rbp
:exit_uefi_stack
mov_[rip+DWORD],rax %__temp_rax # save RAX
pop_rax # Save return address
mov_[rip+DWORD],rsp %__uefi_stack # save system stack
mov_rsp,[rip+DWORD] %GLOBAL___user_stack # restore user stack
push_rax # Restore return address
mov_rax,[rip+DWORD] %__temp_rax # restore RAX
mov_rbp,rsp # Fix rbp
add_rbp, %8 # Fix rbp
ret
:__return_address
NULL
:__temp_rax
NULL
:__uefi_stack
NULL
mescc-tools-1.5.2/M2libc/amd64/uefi/libc-full.M1 0000644 0000000 0000000 00000006101 14522760670 015667 0 ustar ## Copyright (C) 2022 Andrius Štikonas
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_rbp,rsp # save stack pointer
mov_[rip+DWORD],rsp %__return_address # save UEFI return address
mov_[rip+DWORD],rcx %GLOBAL__image_handle # save image_handle
mov_[rip+DWORD],rdx %GLOBAL__system # save system
;; Do UEFI initialization
call %FUNCTION__init
call %exit_uefi_stack # Switch to user stack
;; Perform the main loop
mov_rax,[rip+DWORD] %GLOBAL__argc # Get argc
push_rax # Push it onto stack
mov_rax,[rip+DWORD] %GLOBAL__argv # Get argv
push_rax # Push it onto stack
mov_rax,[rip+DWORD] %GLOBAL__envp # Get envp
push_rax # Push it onto stack
call %FUNCTION_main
:FUNCTION__exit
;; Do UEFI cleanup
call %enter_uefi_stack # Switch back to UEFI stack
push_rax # Save exit code
call %FUNCTION__cleanup
pop_rax # Restore exit code
:FUNCTION___exit
mov_rsp,[rip+DWORD] %__return_address # Get UEFI return address
ret
# Switch to uefi stack
# does not change any other registers except for rbp
:enter_uefi_stack
mov_[rip+DWORD],rax %__temp_rax # save RAX
pop_rax # Save return address
mov_[rip+DWORD],rsp %GLOBAL___user_stack # save user stack
mov_rsp,[rip+DWORD] %__uefi_stack # restore system stack
push_rax # Restore return address
mov_rax,[rip+DWORD] %__temp_rax # restore RAX
mov_rbp,rsp # Fix rbp
add_rbp, %8 # Fix rbp
ret
# Switch to user stack
# does not change any other registers except for rbp
:exit_uefi_stack
mov_[rip+DWORD],rax %__temp_rax # save RAX
pop_rax # Save return address
mov_[rip+DWORD],rsp %__uefi_stack # save system stack
mov_rsp,[rip+DWORD] %GLOBAL___user_stack # restore user stack
push_rax # Restore return address
mov_rax,[rip+DWORD] %__temp_rax # restore RAX
mov_rbp,rsp # Fix rbp
add_rbp, %8 # Fix rbp
ret
:__return_address
NULL
:__temp_rax
NULL
:__uefi_stack
NULL
mescc-tools-1.5.2/M2libc/armv7l/ 0000755 0000000 0000000 00000000000 14522760670 013166 5 ustar mescc-tools-1.5.2/M2libc/armv7l/ELF-armv7l-debug.hex2 0000644 0000000 0000000 00000005650 14522760670 016664 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
: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 # ph_alignment
:ELF_text
mescc-tools-1.5.2/M2libc/armv7l/ELF-armv7l.hex2 0000644 0000000 0000000 00000005650 14522760670 015600 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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
: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 # ph_alignment
:ELF_text
mescc-tools-1.5.2/M2libc/armv7l/armv7l_defs.M1 0000644 0000000 0000000 00000004644 14522760670 015606 0 ustar ## 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 .
# M2-Planet standards
DEFINE NULL 00000000
# 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 BP C
DEFINE R13 D
DEFINE SP D
DEFINE R14 E
DEFINE LR E
DEFINE R15 F
DEFINE PC F
# Register masks for push/pop16
DEFINE {R0} 0100
DEFINE {R1} 0200
DEFINE {R2} 0400
DEFINE {R3} 0800
DEFINE {R4} 1000
DEFINE {R11} 0008
DEFINE {BP} 0010
DEFINE {LR} 0040
# Bitshift constants
DEFINE NO_SHIFT 0
DEFINE LEFT 1
DEFINE RIGHT 3
DEFINE ARITH_RIGHT 5
# LOAD/STORE
DEFINE HALF_MEMORY E1
DEFINE MEMORY E5
DEFINE NO_OFFSET B0
DEFINE STORE32 08
DEFINE STORE16 0C
DEFINE STORE8 0C
DEFINE LOAD32 09
DEFINE LOADU8 0
DEFINE LOADS8 D0
DEFINE LOADS16 F0
DEFINE LOAD 0D
DEFINE LOADI8_ALWAYS 0A0E3
DEFINE LOADI8_G 0A0C3
DEFINE LOADI8_GE 0A0A3
DEFINE LOADI8_EQUAL 0A003
DEFINE LOADI8_NE 0A013
DEFINE LOADI8_LE 0A0D3
DEFINE LOADI8_L 0A0B3
DEFINE LOADI8_HI 0A083
DEFINE LOADI8_HS 0A023
DEFINE LOADI8_LS 0A093
DEFINE LOADI8_LO 0A033
# JUMP/BRANCH
DEFINE JUMP_ALWAYS EA
DEFINE JUMP_EQUAL 0A
DEFINE JUMP_NE 1A
DEFINE CALL_ALWAYS EB
DEFINE CALL_REG_ALWAYS FF2FE1
DEFINE RETURN FF2FE1
# Data movement
DEFINE MOVE_ALWAYS A0E1
DEFINE MVN_ALWAYS 0E0E1
DEFINE MVN_LT 0E0B1
DEFINE MVNI8_EQUAL 0E003
DEFINE PUSH_ALWAYS 2DE9
DEFINE POP_ALWAYS BDE8
# Arithmetic/logic
DEFINE AUX_ALWAYS E1
DEFINE IMM_ALWAYS E3
DEFINE ARITH_ALWAYS E2
DEFINE ARITH_GE A2
DEFINE ARITH_LT B2
DEFINE ARITH_NE 12
DEFINE ARITH2_ALWAYS E0
DEFINE ARITH2_GE A0
DEFINE ADC 0A
DEFINE ADCS 0B
DEFINE ADD 08
DEFINE ADDS 09
DEFINE AND 00
DEFINE CMP 005
DEFINE CMPI8 005
DEFINE MUL 0
DEFINE MULS 1
DEFINE OR 08
DEFINE SHIFT A0
DEFINE SUB 04
DEFINE RSUB 06
DEFINE XOR 02
# SYSCALL
DEFINE SYSCALL_ALWAYS 000000EF
mescc-tools-1.5.2/M2libc/armv7l/libc-core.M1 0000644 0000000 0000000 00000011675 14522760670 015236 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
'0' SP BP NO_SHIFT MOVE_ALWAYS ; Setup Base Pointer
;; Prepare argv
!4 R0 ADD BP ARITH_ALWAYS ; ARGV_address = BP + 4
{R0} PUSH_ALWAYS ; Put argv on the stack
;; Prepare envp
'0' BP R0 NO_SHIFT MOVE_ALWAYS ; Address we need to load from
!0 R0 LOAD32 R0 MEMORY ; Get ARGC
!2 R0 ADD R0 ARITH_ALWAYS ; OFFSET = ARGC + 2
'0' R0 R0 '1' MOVE_ALWAYS ; OFFSET = OFFSET * WORDSIZE
'0' R0 R0 ADD BP ARITH2_ALWAYS ; ENVP_address = BP + OFFSET
{R0} PUSH_ALWAYS ; Put envp on the stack
;; Stack offset
!4 BP ADD BP ARITH_ALWAYS ; Fix BP
^~FUNCTION_main CALL_ALWAYS ; Jump right into main
{R1} POP_ALWAYS ; Fix stack
{R1} POP_ALWAYS ; Fix stack
{R1} POP_ALWAYS ; Fix stack
{R0} PUSH_ALWAYS ; put return on the stack
{R0} PUSH_ALWAYS ; So that _exit will have it
{R0} PUSH_ALWAYS ; So that _exit will have it
:FUNCTION_exit
:FUNCTION__exit
!4 R0 SUB R12 ARITH_ALWAYS
!0 R0 LOAD32 R0 MEMORY
!1 R7 LOADI8_ALWAYS
SYSCALL_ALWAYS ; exit
# Unsigned Divide
:divide
{R4} PUSH_ALWAYS ; Protect R4
{R3} PUSH_ALWAYS ; Protect R3
{R2} PUSH_ALWAYS ; Protect R2
'0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
'0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
!0 R0 LOADI8_ALWAYS ; MOV R0,#0
!0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
!1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
!0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
!0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
'0' R0 R0 MVN_LT ; MVNLT R0,R0
'0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
!32 R0 LOADI8_ALWAYS ; MOV R0,#32.
!0 R1 LOADI8_ALWAYS ; MOV R1,#0
:divide_loop
'0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
'0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
'0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
'0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
!1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
!1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
!0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
^~divide_loop JUMP_NE ; BNE loop
'0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
{R2} POP_ALWAYS ; Restore R2
{R3} POP_ALWAYS ; Restore R3
{R4} POP_ALWAYS ; Restore R4
'1' LR RETURN
# Signed Divide
:divides
{R4} PUSH_ALWAYS ; Protect R4
{R3} PUSH_ALWAYS ; Protect R3
{R2} PUSH_ALWAYS ; Protect R2
'0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
'0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
!0 R0 LOADI8_ALWAYS ; MOV R0,#0
!0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
!0 R2 RSUB R2 ARITH_LT ; RSBLT R2,R2,#0
!1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
!0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
!0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
'0' R0 R0 MVN_LT ; MVNLT R0,R0
'0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
!32 R0 LOADI8_ALWAYS ; MOV R0,#32.
!0 R1 LOADI8_ALWAYS ; MOV R1,#0
:divides_loop
'0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
'0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
'0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
'0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
!1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
!1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
!0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
^~divides_loop JUMP_NE ; BNE loop
!0 CMPI8 R4 IMM_ALWAYS ; CMP R4,#0
!0 R2 RSUB R2 ARITH_NE ; RSBNE R2,R2,#0
'0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
{R2} POP_ALWAYS ; Restore R2
{R3} POP_ALWAYS ; Restore R3
{R4} POP_ALWAYS ; Restore R4
'1' LR RETURN
# Unsigned Modulus
:modulus
{LR} PUSH_ALWAYS ; Prepare to leverage divide
^~divide CALL_ALWAYS ; Use divide
'0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
{LR} POP_ALWAYS ; Prepare for return
'1' LR RETURN
# Signed Modulus
:moduluss
{LR} PUSH_ALWAYS ; Prepare to leverage divide
^~divides CALL_ALWAYS ; Use divides
'0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
{LR} POP_ALWAYS ; Prepare for return
'1' LR RETURN
mescc-tools-1.5.2/M2libc/armv7l/libc-full.M1 0000644 0000000 0000000 00000012143 14522760670 015237 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
'0' SP BP NO_SHIFT MOVE_ALWAYS ; Setup Base Pointer
;; Prepare argv
!4 R0 ADD BP ARITH_ALWAYS ; ARGV_address = BP + 4
{R0} PUSH_ALWAYS ; Put argv on the stack
;; Prepare envp
'0' BP R0 NO_SHIFT MOVE_ALWAYS ; Address we need to load from
!0 R0 LOAD32 R0 MEMORY ; Get ARGC
!2 R0 ADD R0 ARITH_ALWAYS ; OFFSET = ARGC + 2
'0' R0 R0 '1' MOVE_ALWAYS ; OFFSET = OFFSET * WORDSIZE
'0' R0 R0 ADD BP ARITH2_ALWAYS ; ENVP_address = BP + OFFSET
{R0} PUSH_ALWAYS ; Put envp on the stack
;; Stack offset
!4 BP ADD BP ARITH_ALWAYS ; Fix BP
^~FUNCTION___init_malloc CALL_ALWAYS ; Setup for malloc
^~FUNCTION___init_io CALL_ALWAYS ; Setup for FILE*
^~FUNCTION_main CALL_ALWAYS ; Jump right into main
{R1} POP_ALWAYS ; Fix stack
{R1} POP_ALWAYS ; Fix stack
{R1} POP_ALWAYS ; Fix stack
{R0} PUSH_ALWAYS ; put return on the stack
{R0} PUSH_ALWAYS ; So that _exit will have it
{R0} PUSH_ALWAYS ; So that _exit will have it
:FUNCTION_exit
^~FUNCTION___kill_io CALL_ALWAYS
:FUNCTION__exit
!4 R0 SUB R12 ARITH_ALWAYS
!0 R0 LOAD32 R0 MEMORY
!1 R7 LOADI8_ALWAYS
SYSCALL_ALWAYS ; exit
# Unsigned Divide
:divide
{R4} PUSH_ALWAYS ; Protect R4
{R3} PUSH_ALWAYS ; Protect R3
{R2} PUSH_ALWAYS ; Protect R2
'0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
'0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
!0 R0 LOADI8_ALWAYS ; MOV R0,#0
!0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
!1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
!0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
!0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
'0' R0 R0 MVN_LT ; MVNLT R0,R0
'0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
!32 R0 LOADI8_ALWAYS ; MOV R0,#32.
!0 R1 LOADI8_ALWAYS ; MOV R1,#0
:divide_loop
'0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
'0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
'0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
'0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
!1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
!1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
!0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
^~divide_loop JUMP_NE ; BNE loop
'0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
{R2} POP_ALWAYS ; Restore R2
{R3} POP_ALWAYS ; Restore R3
{R4} POP_ALWAYS ; Restore R4
'1' LR RETURN
# Signed Divide
:divides
{R4} PUSH_ALWAYS ; Protect R4
{R3} PUSH_ALWAYS ; Protect R3
{R2} PUSH_ALWAYS ; Protect R2
'0' R0 R3 NO_SHIFT MOVE_ALWAYS ; MOV R3,R0
'0' R1 R2 NO_SHIFT MOVE_ALWAYS ; MOV R2,R1
!0 R0 LOADI8_ALWAYS ; MOV R0,#0
!0 CMPI8 R2 IMM_ALWAYS ; CMP R2,#0
!0 R2 RSUB R2 ARITH_LT ; RSBLT R2,R2,#0
!1 R0 SUB R0 ARITH_LT ; SUBLT R0,R0,#1
!0 CMPI8 R3 IMM_ALWAYS ; CMP R3,#0
!0 R3 RSUB R3 ARITH_LT ; RSBLT R3,R3,#0
'0' R0 R0 MVN_LT ; MVNLT R0,R0
'0' R0 R4 NO_SHIFT MOVE_ALWAYS ; MOV R4,R0
!32 R0 LOADI8_ALWAYS ; MOV R0,#32.
!0 R1 LOADI8_ALWAYS ; MOV R1,#0
:divides_loop
'0' R2 R2 ADDS R2 ARITH2_ALWAYS ; ADDS R2,R2,R2
'0' R1 R1 ADCS R1 ARITH2_ALWAYS ; ADCS R1,R1,R1
'0' R3 CMP R1 AUX_ALWAYS ; CMP R1,R3
'0' R3 R1 SUB R1 ARITH2_GE ; SUBGE R1,R1,R3
!1 R2 ADD R2 ARITH_GE ; ADDGE R2,R2,#1
!1 R0 SUB R0 ARITH_ALWAYS ; SUB R0,R0,#1
!0 CMPI8 R0 IMM_ALWAYS ; CMP R0,#0
^~divides_loop JUMP_NE ; BNE loop
!0 CMPI8 R4 IMM_ALWAYS ; CMP R4,#0
!0 R2 RSUB R2 ARITH_NE ; RSBNE R2,R2,#0
'0' R2 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R2
{R2} POP_ALWAYS ; Restore R2
{R3} POP_ALWAYS ; Restore R3
{R4} POP_ALWAYS ; Restore R4
'1' LR RETURN
# Unsigned Modulus
:modulus
{LR} PUSH_ALWAYS ; Prepare to leverage divide
^~divide CALL_ALWAYS ; Use divide
'0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
{LR} POP_ALWAYS ; Prepare for return
'1' LR RETURN
# Signed Modulus
:moduluss
{LR} PUSH_ALWAYS ; Prepare to leverage divide
^~divides CALL_ALWAYS ; Use divides
'0' R1 R0 NO_SHIFT MOVE_ALWAYS ; MOV R0,R1
{LR} POP_ALWAYS ; Prepare for return
'1' LR RETURN
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/armv7l/linux/ 0000755 0000000 0000000 00000000000 14522760670 014325 5 ustar mescc-tools-1.5.2/M2libc/armv7l/linux/bootstrap.c 0000644 0000000 0000000 00000006412 14522760670 016511 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"{R0} PUSH_ALWAYS"
"'0' SP R1 NO_SHIFT MOVE_ALWAYS"
"!1 R2 LOADI8_ALWAYS"
"!3 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS"
"!0 CMPI8 R0 IMM_ALWAYS"
"{R0} POP_ALWAYS"
"!0 R0 MVNI8_EQUAL");
}
void fputc(char s, FILE* f)
{
asm("!8 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!4 R1 SUB R12 ARITH_ALWAYS"
"!1 R2 LOADI8_ALWAYS"
"!4 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!5 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!6 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!45 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!1 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
mescc-tools-1.5.2/M2libc/armv7l/linux/fcntl.c 0000644 0000000 0000000 00000002521 14522760670 015577 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!5 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/armv7l/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 015143 5 ustar mescc-tools-1.5.2/M2libc/armv7l/linux/sys/stat.c 0000644 0000000 0000000 00000004224 14522760670 016264 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("!15 R7 LOADI8_ALWAYS"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int fchmod(int a, mode_t b)
{
asm("!94 R7 LOADI8_ALWAYS"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int mkdir(char const* a, mode_t b)
{
asm("!39 R7 LOADI8_ALWAYS"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("!14 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
mode_t umask(mode_t m)
{
asm("!60 R7 LOADI8_ALWAYS"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
#endif
mescc-tools-1.5.2/M2libc/armv7l/linux/unistd.c 0000644 0000000 0000000 00000010243 14522760670 015777 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!33 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int chdir(char* path)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!12 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int fchdir(int fd)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!133 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
void _exit(int value);
int fork()
{
asm("!2 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int waitpid (int pid, int* status_ptr, int options)
{
asm("!114 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("!11 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int read(int fd, char* buf, unsigned count)
{
asm("!3 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int write(int fd, char* buf, unsigned count)
{
asm("!4 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int lseek(int fd, int offset, int whence)
{
asm("!19 R7 LOADI8_ALWAYS"
"!12 R2 SUB R12 ARITH_ALWAYS"
"!0 R2 LOAD32 R2 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
int close(int fd)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!6 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int unlink (char* filename)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!10 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
int _getcwd(char* buf, int size)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!8 R1 SUB R12 ARITH_ALWAYS"
"!0 R1 LOAD32 R1 MEMORY"
"!183 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"!45 R7 LOADI8_ALWAYS"
"SYSCALL_ALWAYS");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("!122 R7 LOADI8_ALWAYS"
"!4 R0 SUB R12 ARITH_ALWAYS"
"!0 R0 LOAD32 R0 MEMORY"
"SYSCALL_ALWAYS");
}
#endif
mescc-tools-1.5.2/M2libc/bootstrappable.c 0000644 0000000 0000000 00000007145 14522760670 015152 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
#include
#define TRUE 1
#define FALSE 0
void require(int bool, char* error)
{
if(!bool)
{
fputs(error, stderr);
exit(EXIT_FAILURE);
}
}
int match(char* a, char* b)
{
if((NULL == a) && (NULL == b)) return TRUE;
if(NULL == a) return FALSE;
if(NULL == b) return FALSE;
int i = -1;
do
{
i = i + 1;
if(a[i] != b[i])
{
return FALSE;
}
} while((0 != a[i]) && (0 !=b[i]));
return TRUE;
}
int in_set(int c, char* s)
{
/* NULL set is always false */
if(NULL == s) return FALSE;
while(0 != s[0])
{
if(c == s[0]) return TRUE;
s = s + 1;
}
return FALSE;
}
/* INTERNAL ONLY */
int __index_number(char* s, char c)
{
int i = 0;
while(s[i] != c)
{
i = i + 1;
if(0 == s[i]) return -1;
}
return i;
}
/* INTERNAL ONLY */
int __toupper(int c)
{
if(in_set(c, "abcdefghijklmnopqrstuvwxyz")) return (c & 0xDF);
return c;
}
/* INTERNAL ONLY */
int __set_reader(char* set, int mult, char* input)
{
int n = 0;
int i = 0;
int hold;
int negative_p = FALSE;
if(input[0] == '-')
{
negative_p = TRUE;
i = i + 1;
}
while(in_set(input[i], set))
{
n = n * mult;
hold = __index_number(set, __toupper(input[i]));
/* Input managed to change between in_set and index_number */
if(-1 == hold) return 0;
n = n + hold;
i = i + 1;
}
/* loop exited before NULL and thus invalid input */
if(0 != input[i]) return 0;
if(negative_p)
{
n = 0 - n;
}
return n;
}
int strtoint(char *a)
{
int result = 0;
/* If NULL string */
if(0 == a[0])
{
result = 0;
}
/* Deal with binary */
else if ('0' == a[0] && 'b' == a[1])
{
result = __set_reader("01", 2, a+2);
}
/* Deal with hex */
else if ('0' == a[0] && 'x' == a[1])
{
result = __set_reader("0123456789ABCDEFabcdef", 16, a+2);
}
/* Deal with octal */
else if('0' == a[0])
{
result = __set_reader("01234567", 8, a+1);
}
/* Deal with decimal */
else
{
result = __set_reader("0123456789", 10, a);
}
/* Deal with sign extension for 64bit hosts */
if(0 != (0x80000000 & result)) result = (0xFFFFFFFF << 31) | result;
return result;
}
char* int2str(int x, int base, int signed_p)
{
require(1 < base, "int2str doesn't support a base less than 2\n");
require(37 > base, "int2str doesn't support a base more than 36\n");
/* Be overly conservative and save space for 32binary digits and padding null */
char* p = calloc(34, sizeof(char));
/* if calloc fails return null to let calling code deal with it */
if(NULL == p) return p;
p = p + 32;
unsigned i;
int sign_p = FALSE;
char* table = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(signed_p && (10 == base) && (0 != (x & 0x80000000)))
{
/* Truncate to 31bits */
i = -x & 0x7FFFFFFF;
if(0 == i) return "-2147483648";
sign_p = TRUE;
} /* Truncate to 32bits */
else i = x & (0x7FFFFFFF | (1 << 31));
do
{
p[0] = table[i % base];
p = p - 1;
i = i / base;
} while(0 < i);
if(sign_p)
{
p[0] = '-';
p = p - 1;
}
return p + 1;
}
mescc-tools-1.5.2/M2libc/bootstrappable.h 0000644 0000000 0000000 00000002110 14522760670 015142 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _BOOTSTRAPPABLE_H
#define _BOOTSTRAPPABLE_H
/* Essential common CONSTANTS*/
#define TRUE 1
#define FALSE 0
#ifdef __M2__
#include
#else
/* Universally useful functions */
void require(int bool, char* error);
int match(char* a, char* b);
int in_set(int c, char* s);
int strtoint(char *a);
char* int2str(int x, int base, int signed_p);
#endif
#endif
mescc-tools-1.5.2/M2libc/ctype.c 0000644 0000000 0000000 00000001415 14522760670 013247 0 ustar /* Copyright (C) 2022 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
int isspace(char _c)
{
return _c == ' ' || _c - '\t' < 5;
}
mescc-tools-1.5.2/M2libc/ctype.h 0000644 0000000 0000000 00000001452 14522760670 013255 0 ustar /* Copyright (C) 2022 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _CTYPE_H
#define _CTYPE_H
#ifdef __M2__
#include
#else
#endif
#endif
mescc-tools-1.5.2/M2libc/fcntl.c 0000644 0000000 0000000 00000002723 14522760670 013234 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _FCNTL_C
#define _FCNTL_C
#ifdef __M2__
#if __uefi__
#include
#elif __i386__
#include
#elif __x86_64__
#include
#elif __arm__
#include
#elif __aarch64__
#include
#elif __riscv && __riscv_xlen==32
#include
#elif __riscv && __riscv_xlen==64
#include
#elif __knight_posix__
#include
#elif __knight__
#include
#else
#error arch not supported
#endif
#else
extern int _open(char* name, int flag, int mode);
#endif
int errno;
int open(char* name, int flag, int mode)
{
int fd = _open(name, flag, mode);
if(0 > fd)
{
errno = -fd;
fd = -1;
}
return fd;
}
#endif
mescc-tools-1.5.2/M2libc/fcntl.h 0000644 0000000 0000000 00000002214 14522760670 013234 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _FCNTL_H
#define _FCNTL_H
#ifdef __M2__
#include
#else
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
extern int open(char* name, int flag, int mode);
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
#endif
mescc-tools-1.5.2/M2libc/gcc_req.h 0000644 0000000 0000000 00000001351 14522760670 013532 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
typedef unsigned long SCM;
mescc-tools-1.5.2/M2libc/knight/ 0000755 0000000 0000000 00000000000 14522760670 013242 5 ustar mescc-tools-1.5.2/M2libc/knight/ELF-knight.hex2 0000644 0000000 0000000 00000002137 14522760670 015725 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### if you wish to use this header, you need to add :ELF_end to the end of your
### M1 or hex2 files.
mescc-tools-1.5.2/M2libc/knight/knight-native_defs.M1 0000644 0000000 0000000 00000012514 14522760670 017215 0 ustar ## 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 SET.G E10000
DEFINE SET.GE E10001
DEFINE SET.E E10002
DEFINE SET.NE E10003
DEFINE SET.LE E10004
DEFINE SET.L E10005
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 NULL 00000000
DEFINE HALT FFFFFFFF
mescc-tools-1.5.2/M2libc/knight/knight_defs.M1 0000644 0000000 0000000 00000013301 14522760670 015724 0 ustar ## 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 SET.G E10000
DEFINE SET.GE E10001
DEFINE SET.E E10002
DEFINE SET.NE E10003
DEFINE SET.LE E10004
DEFINE SET.L E10005
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 SYS_READ 42000000
DEFINE SYS_WRITE 42000001
DEFINE SYS_OPEN 42000002
DEFINE SYS_CLOSE 42000003
DEFINE SYS_LSEEK 42000008
DEFINE SYS_ACCESS 42000015
DEFINE SYS_FORK 42000039
DEFINE SYS_EXECVE 4200003B
DEFINE SYS_EXIT 4200003C
DEFINE SYS_WAIT4 4200003D
DEFINE SYS_UNAME 4200003F
DEFINE SYS_GETCWD 4200004F
DEFINE SYS_CHDIR 42000050
DEFINE SYS_FCHDIR 42000051
DEFINE SYS_MKDIR 42000053
DEFINE SYS_UNLINK 42000057
DEFINE SYS_CHMOD 4200005A
DEFINE SYS_FCHMOD 4200005B
DEFINE SYS_UMASK 4200005F
DEFINE SYS_MKNOD 42000085
# 0OP Group
DEFINE NOP 00000000
DEFINE HALT FFFFFFFF
# M2-Planet Standard
DEFINE NULL 00000000
mescc-tools-1.5.2/M2libc/knight/libc-core.M1 0000644 0000000 0000000 00000002256 14522760670 015305 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
;; Kernel Setup R12 as HEAP pointer after end of the stack
;; Kernel Setup R15 as Stack pointer after the initial stack frame
;; Default stack frame is:
;; ARGC, ARGV, ENVP, NULL
SUBI R14 R15 16 ; Set our base pointer
;; Perform the main loop
LOADR R0 4
JUMP 4
&FUNCTION_main
CALL R0 R15
COPY R14 R15 ; Setup base pointer
PUSHR R0 R15 ; Put return on the stack
:FUNCTION_exit
:FUNCTION__exit
LOAD R0 R14 0
SYS_EXIT
mescc-tools-1.5.2/M2libc/knight/libc-full.M1 0000644 0000000 0000000 00000002625 14522760670 015317 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
;; Kernel Setup R12 as HEAP pointer after end of the stack
;; Kernel Setup R15 as Stack pointer after the initial stack frame
;; Default stack frame is:
;; ARGC, ARGV, ENVP, NULL
SUBI R14 R15 16 ; Set our base pointer
;; Setup for malloc
LOADR R0 4
JUMP 4
&FUNCTION___init_malloc
CALL R0 R15
;; Setup for FILE*
LOADR R0 4
JUMP 4
&FUNCTION___init_io
CALL R0 R15
;; Perform the main loop
LOADR R0 4
JUMP 4
&FUNCTION_main
CALL R0 R15
COPY R14 R15 ; Setup base pointer
PUSHR R0 R15 ; Put return on the stack
:FUNCTION_exit
LOADR R0 4
JUMP 4
&FUNCTION___kill_io
CALL R0 R15
:FUNCTION__exit
LOAD R0 R14 0
SYS_EXIT
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/knight/libc-native-file.M1 0000644 0000000 0000000 00000002552 14522760670 016557 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
;; Prep TAPE_02
LOADUI R0 0x1101
FOPEN_WRITE
;; Prep TAPE_01
LOADUI R0 0x1100
FOPEN_READ
LOADR R15 4
JUMP 4
&STACK ; Setup initial stack pointer
COPY R14 R15 ; Setup initial base pointer
LOADR32 R12 @HEAP ; Setup HEAP pointer
ADD R12 R12 R15 ; After Stack ends
;; Setup for FILE*
LOADR R0 4
JUMP 4
&FUNCTION___init_io
CALL R0 R15
LOADR R0 4
JUMP 4
&FUNCTION_main
CALL R0 R15
:FUNCTION_exit
LOADR R0 4
JUMP 4
&FUNCTION___kill_io
CALL R0 R15
:FUNCTION__exit
HALT ; Stop the machine
;; Our default heap offset (how big our stack ia)
:HEAP
'00100000'
mescc-tools-1.5.2/M2libc/knight/libc-native.M1 0000644 0000000 0000000 00000002201 14522760670 015631 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
; Setup initial stack pointer
LOADR R15 4
JUMP 4
&STACK
LOADR32 R12 @HEAP ; Setup HEAP pointer
ADD R12 R12 R15 ; After Stack
; Setup initial base pointer
COPY R14 R15
; Perform the main loop
LOADR R0 4
JUMP 4
&FUNCTION_main
CALL R0 R15
:FUNCTION_exit
:FUNCTION__exit
HALT ; Stop the machine
;; Our default heap pointer (offset from start of stack)
:HEAP
'00100000'
mescc-tools-1.5.2/M2libc/knight/linux/ 0000755 0000000 0000000 00000000000 14522760670 014401 5 ustar mescc-tools-1.5.2/M2libc/knight/linux/bootstrap.c 0000644 0000000 0000000 00000005631 14522760670 016567 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("LOAD R0 R14 0"
"LOADI R1 -1"
"COPY R2 R15"
"PUSHR R1 R15"
"MOVE R1 R2"
"LOADI R2 1"
"SYS_READ"
"POPR R1 R15"
"JUMP.Z R0 @FUNCTION_FGETC_DONE"
"SR0I R1 24"
":FUNCTION_FGETC_DONE"
"MOVE R0 R1");
}
void fputc(char s, FILE* f)
{
asm("LOAD R0 R14 0"
"SL0I R0 24"
"COPY R1 R15"
"PUSHR R0 R15"
"LOAD R0 R14 4"
"LOADI R2 1"
"SYS_WRITE"
"POPR R1 R15");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_OPEN"
"FALSE R2");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("LOAD R0 R14 0"
"SYS_CLOSE");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("LOAD R0 R14 0"
"ADDU R0 R12 R0"
"SWAP R0 R12");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("LOAD R0 R14 0"
"SYS_EXIT");
}
mescc-tools-1.5.2/M2libc/knight/linux/fcntl.c 0000644 0000000 0000000 00000002256 14522760670 015660 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_OPEN");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/knight/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 015217 5 ustar mescc-tools-1.5.2/M2libc/knight/linux/sys/stat.c 0000644 0000000 0000000 00000003102 14522760670 016332 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"SYS_CHMOD");
}
int fchmod(int a, mode_t b)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"SYS_FCHMOD");
}
int mkdir(char const* a, mode_t b)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"SYS_MKDIR");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_MKNOD");
}
mode_t umask(mode_t m)
{
asm("LOAD R0 R14 0"
"SYS_UMASK");
}
#endif
mescc-tools-1.5.2/M2libc/knight/linux/unistd.c 0000644 0000000 0000000 00000006201 14522760670 016052 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"SYS_ACCESS");
}
int chdir(char* path)
{
asm("LOAD R0 R14 0"
"SYS_CHDIR");
}
int fchdir(int fd)
{
asm("LOAD R0 R14 0"
"SYS_FCHDIR");
}
void _exit(int value);
int fork()
{
asm("SYS_FORK");
}
int waitpid (int pid, int* status_ptr, int options)
{
/* Uses wait4 with struct rusage *ru set to NULL */
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"FALSE R3"
"SYS_WAIT4");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_EXECVE");
}
int read(int fd, char* buf, unsigned count)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_READ");
}
int write(int fd, char* buf, unsigned count)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_WRITE");
}
int lseek(int fd, int offset, int whence)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"SYS_LSEEK");
}
int close(int fd)
{
asm("LOAD R0 R14 0"
"SYS_CLOSE");
}
int unlink (char* filename)
{
asm("LOAD R0 R14 0"
"SYS_UNLINK");
}
int _getcwd(char* buf, int size)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"SYS_GETCWD");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
/********************************************************************************
* All memory past the text segment and stack are always allocated to heap *
* purposes and thus no syscalls are needed for brk *
********************************************************************************/
int brk(void *addr)
{
asm("LOAD R0 R14 0"
"ADDU R0 R12 R0"
"SWAP R0 R12");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("LOAD R0 R14 0"
"SYS_UNAME");
}
#endif
mescc-tools-1.5.2/M2libc/knight/native/ 0000755 0000000 0000000 00000000000 14522760670 014530 5 ustar mescc-tools-1.5.2/M2libc/knight/native/bootstrap.c 0000644 0000000 0000000 00000005322 14522760670 016713 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0x1100
// CONSTANT stdout 0x1101
// CONSTANT stderr 0
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("LOAD R1 R14 0"
"FGETC");
}
void fputc(char s, FILE* f)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"FPUTC");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open_read(int filename)
{
asm("LOAD R0 R14 0"
"FOPEN_READ");
}
FILE* open_write(int filename)
{
asm("LOAD R0 R14 0"
"FOPEN_WRITE");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
int fd = 0;
if(match(filename, "STDIN") || match(filename, "tape_01"))
{
fd = 0x1100;
}
else if(match(filename, "STDOUT") || match(filename, "tape_02"))
{
fd = 0x1101;
}
if('w' == mode[0])
{
f = open_write(fd);
}
else
{ /* Everything else is a read */
f = open_read(fd);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("LOAD R0 R14 0"
"FCLOSE");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("LOAD R0 R14 0"
"ADDU R0 R12 R0"
"SWAP R0 R12");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("LOAD R0 R14 0"
"HALT");
}
mescc-tools-1.5.2/M2libc/knight/native/fcntl.c 0000644 0000000 0000000 00000002346 14522760670 016007 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
if((0 != flag) && (0 != mode))
{
asm("LOAD R0 R14 0"
"FOPEN_WRITE");
return 0x1101;
}
else
{
asm("LOAD R0 R14 0"
"FOPEN_READ");
return 0x1100;
}
}
#define STDIN_FILENO 0x1100
#define STDOUT_FILENO 0x1101
#define STDERR_FILENO 0
mescc-tools-1.5.2/M2libc/knight/native/sys/ 0000755 0000000 0000000 00000000000 14522760670 015346 5 ustar mescc-tools-1.5.2/M2libc/knight/native/sys/stat.c 0000644 0000000 0000000 00000002754 14522760670 016475 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 0400
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
/* Completely meaningless on bare metal*/
return 0;
}
int fchmod(int a, mode_t b)
{
/* Completely meaningless on bare metal*/
return 0;
}
int mkdir(char const* a, mode_t b)
{
/* Completely meaningless on bare metal*/
return 0;
}
int mknod(char const* a, mode_t b, dev_t c)
{
/* Completely meaningless on bare metal*/
return 0;
}
mode_t umask(mode_t m)
{
/* Completely meaningless on bare metal*/
return 0;
}
mescc-tools-1.5.2/M2libc/knight/native/unistd.c 0000644 0000000 0000000 00000006312 14522760670 016204 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#define NULL 0
#define __PATH_MAX 4096
#define EOF 0xFFFFFFFF
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
/* Completely meaningless in bare metal */
return 0;
}
int chdir(char* path)
{
/* Completely meaningless in bare metal */
return 0;
}
int fchdir(int fd)
{
/* Completely meaningless in bare metal */
return 0;
}
int fork()
{
/* Completely meaningless in bare metal */
return 0;
}
int waitpid (int pid, int* status_ptr, int options)
{
/* Completely meaningless in bare metal */
return 0;
}
int execve(char* file_name, char** argv, char** envp)
{
/* Completely meaningless in bare metal */
return 0;
}
int __read(int fd)
{
asm("LOAD R1 R14 0"
"FGETC");
}
int read(int fd, char* buf, unsigned count)
{
unsigned i = 0;
int c;
while(i < count)
{
c = __read(fd);
if(EOF == c) break;
buf[i] = c;
i = i + 1;
}
return i;
}
void __write(char s, int fd)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"FPUTC");
}
int write(int fd, char* buf, unsigned count)
{
unsigned i = 0;
while(i < count)
{
__write(buf[i], fd);
i = i + 1;
}
}
int lseek(int fd, int offset, int whence)
{
asm("LOAD R0 R14 0"
"LOAD R1 R14 4"
"LOAD R2 R14 8"
"FSEEK");
}
int close(int fd)
{
asm("LOAD R0 R14 0"
"FCLOSE");
}
int unlink (char* filename)
{
/* Completely meaningless in bare metal */
return 0;
}
int _getcwd(char* buf, int size)
{
/* Completely meaningless in bare metal */
return 0;
}
char* getcwd(char* buf, unsigned size)
{
/* Completely meaningless in bare metal */
return 0;
}
char* getwd(char* buf)
{
/* Completely meaningless in bare metal */
return 0;
}
char* get_current_dir_name()
{
/* Completely meaningless in bare metal */
return 0;
}
/********************************************************************************
* We are running on bare metal. Just don't go past the end of install RAM *
********************************************************************************/
int brk(void *addr)
{
asm("LOAD R0 R14 0"
"ADDU R0 R12 R0"
"SWAP R0 R12");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
/* Completely meaningless in bare metal */
return 0;
}
mescc-tools-1.5.2/M2libc/riscv32/ 0000755 0000000 0000000 00000000000 14522760670 013251 5 ustar mescc-tools-1.5.2/M2libc/riscv32/ELF-riscv32-debug.hex2 0000644 0000000 0000000 00000005017 14522760670 017027 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### 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] Set at 0 because none cares
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
F3 00 ## e_machine Indicating RISC-V
01 00 00 00 ## e_version Indicating original elf
&_start ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
%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
## Program Header
:ELF_program_headers
:ELF_program_header__text
01 00 00 00 ## ph_type: PT-LOAD = 1
00 00 00 00 ## p_offset
&ELF_base ## ph_vaddr
&ELF_base ## ph_physaddr
%ELF_end>ELF_base ## p_filesz
%ELF_end>ELF_base ## p_memsz
07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00 ## ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/riscv32/ELF-riscv32.hex2 0000644 0000000 0000000 00000004752 14522760670 015750 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### 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] Set at 0 because none cares
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
F3 00 ## e_machine Indicating RISC-V
01 00 00 00 ## e_version Indicating original elf
&_start ## e_entry Address of the entry point (Number of bytes this header is + Base Address)
%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
01 00 00 00 ## ph_type: PT-LOAD = 1
00 00 00 00 ## p_offset
&ELF_base ## ph_vaddr
&ELF_base ## ph_physaddr
%ELF_end>ELF_base ## p_filesz
%ELF_end>ELF_base ## p_memsz
07 00 00 00 ## ph_flags: PF-X|PF-W|PF-R = 7
01 00 00 00 ## ph_align
:ELF_text
mescc-tools-1.5.2/M2libc/riscv32/libc-core.M1 0000644 0000000 0000000 00000002754 14522760670 015317 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## 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
rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv
rd_a0 rs1_fp !4 addi ; ARGV_address = FP + 4
rd_sp rs1_sp !-4 addi
rs1_sp rs2_a0 sw ; Put argv on the stack
; Prepare envp
rd_a0 rs1_fp mv ; Address we need to load from
rd_a0 rs1_a0 lw ; Get ARGC
rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
rd_sp rs1_sp !-4 addi
rs1_sp rs2_a0 sw ; Put envp on the stack
; Stack offset
rd_fp rs1_fp !4 addi
; Call main function
rd_ra $FUNCTION_main jal
; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
rd_a7 !93 addi ; Syscall for exit
ecall ; Exit with code in a0
mescc-tools-1.5.2/M2libc/riscv32/libc-full.M1 0000644 0000000 0000000 00000003666 14522760670 015334 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## 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
rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv
rd_a0 rs1_fp !4 addi ; ARGV_address = FP + 4
rd_sp rs1_sp !-4 addi
rs1_sp rs2_a0 sw ; Put argv on the stack
; Prepare envp
rd_a0 rs1_fp mv ; Address we need to load from
rd_a0 rs1_a0 lw ; Get ARGC
rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
rd_a0 rs1_a0 rs2_x2 slli ; OFFSET = OFFSET * WORDSIZE
rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
rd_sp rs1_sp !-4 addi
rs1_sp rs2_a0 sw ; Put envp on the stack
rd_a1 ~GLOBAL__envp auipc ; Get _envp global
rd_a1 rs1_a1 !GLOBAL__envp addi
rs1_a1 rs2_a0 sw ; Save environment to _envp
; Stack offset
rd_fp rs1_fp !4 addi
; Setup for malloc
rd_ra $FUNCTION___init_malloc jal
; Setup for FILE*
rd_ra $FUNCTION___init_io jal
; Call main function
rd_ra $FUNCTION_main jal
; Put return value on the stack so that _exit gets it
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sw
; Exit to kernel
:FUNCTION_exit
rd_ra $FUNCTION___kill_io jal
:FUNCTION__exit
rd_a0 rs1_sp lw
rd_a7 !93 addi ; Syscall for exit
ecall ; Exit with code in a0
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/riscv32/linux/ 0000755 0000000 0000000 00000000000 14522760670 014410 5 ustar mescc-tools-1.5.2/M2libc/riscv32/linux/bootstrap.c 0000644 0000000 0000000 00000006112 14522760670 016571 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("rd_a0 rs1_fp !-4 lw"
"rs1_sp rs2_a0 sw"
"rd_a1 rs1_sp mv"
"rd_a2 !1 addi"
"rd_a7 !63 addi"
"ecall"
"rd_a1 mv"
"rd_t0 rs1_a0 mv"
"rd_a0 rs1_sp lw"
"rs1_t0 @8 bnez"
"rd_a0 !-1 addi");
}
void fputc(char s, FILE* f)
{
asm("rd_a0 rs1_fp !-8 lw"
"rd_a1 rs1_fp !-4 addi"
"rd_a2 !1 addi" /* 1 byte */
"rd_a7 !64 addi" /* write */
"ecall");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a3 rs1_fp !-12 lw"
"rd_a7 !56 addi" /* openat */
"ecall");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !57 addi" /* close */
"ecall");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !214 addi" /* brk */
"ecall");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !93 addi" /* exit */
"ecall");
}
mescc-tools-1.5.2/M2libc/riscv32/linux/fcntl.c 0000644 0000000 0000000 00000002443 14522760670 015665 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a3 rs1_fp !-12 lw"
"rd_a7 !56 addi"
"ecall");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/riscv32/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 015226 5 ustar mescc-tools-1.5.2/M2libc/riscv32/linux/sys/stat.c 0000644 0000000 0000000 00000003671 14522760670 016354 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a7 !53 addi"
"ecall");
}
int fchmod(int a, mode_t b)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a7 !52 addi"
"ecall");
}
int mkdir(char const* a, mode_t b)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a7 !34 addi"
"ecall");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a3 rs1_fp !-12 lw"
"rd_a7 !33 addi"
"ecall");
}
mode_t umask(mode_t m)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !166 addi"
"ecall");
}
#endif
mescc-tools-1.5.2/M2libc/riscv32/linux/unistd.c 0000644 0000000 0000000 00000011514 14522760670 016064 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#include
#define NULL 0
#define __PATH_MAX 4096
#define P_PID 1
#define WEXITED 4
#define __SI_SWAP_ERRNO_CODE
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 rs1_fp !-8 lw"
"rd_a3 addi" /* flags = 0 */
"rd_a7 !48 addi"
"ecall");
}
int chdir(char* path)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !49 addi"
"ecall");
}
int fchdir(int fd)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !50 addi"
"ecall");
}
void _exit(int value);
int fork()
{
asm("rd_a7 !220 addi"
"rd_a0 !17 addi" /* SIGCHLD */
"rd_a1 mv" /* Child uses duplicate of parent's stack */
"ecall");
}
int waitid(int idtype, int id, struct siginfo_t *infop, int options, void *rusage)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a2 rs1_fp !-12 lw"
"rd_a3 rs1_fp !-16 lw"
"rd_a4 rs1_fp !-20 lw"
"rd_a7 !95 addi"
"ecall");
}
void* calloc(int count, int size);
void free(void* l);
struct siginfo_t *__waitpid_info;
int waitpid(int pid, int* status_ptr, int options)
{
if(NULL == __waitpid_info) __waitpid_info = calloc(1, sizeof(struct siginfo_t));
int r = waitid(P_PID, pid, __waitpid_info, options|WEXITED, NULL);
if(__waitpid_info->si_pid != 0)
{
int sw = 0;
if(__waitpid_info->si_code == CLD_EXITED)
{
sw = (__waitpid_info->si_status & 0xff) << 8;
}
else if(__waitpid_info->si_code == CLD_KILLED)
{
sw = __waitpid_info->si_status & 0x7f;
}
else if(__waitpid_info->si_code == CLD_DUMPED)
{
sw = (__waitpid_info->si_status & 0x7f) | 0x80;
}
else if(__waitpid_info->si_code == CLD_CONTINUED)
{
sw = 0xffff;
}
else if(__waitpid_info->si_code == CLD_STOPPED || __waitpid_info->si_code == CLD_TRAPPED)
{
sw = ((__waitpid_info->si_status & 0xff) << 8) + 0x7f;
}
if(status_ptr != NULL) *status_ptr = sw;
}
int rval = __waitpid_info->si_pid;
if(r < 0)
{
return r;
}
return rval;
}
int execve(char* file_name, char** argv, char** envp)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a2 rs1_fp !-12 lw"
"rd_a7 !221 addi"
"ecall");
}
int read(int fd, char* buf, unsigned count)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a2 rs1_fp !-12 lw"
"rd_a7 !63 addi"
"ecall");
}
int write(int fd, char* buf, unsigned count)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a2 rs1_fp !-12 lw"
"rd_a7 !64 addi"
"ecall");
}
int llseek(int fd, int offset_high, int offset_low, int result, int whence)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a2 rs1_fp !-12 lw"
"rd_a3 rs1_fp !-16 lw"
"rd_a4 rs1_fp !-20 lw"
"rd_a7 !62 addi"
"ecall");
}
int lseek(int fd, int offset, int whence)
{
int result;
if(llseek(fd, offset >> 32, offset, &result, whence))
{
return -1;
}
return result;
}
int close(int fd)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !57 addi" /* close */
"ecall");
}
int unlink (char* filename)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-4 lw"
"rd_a2 !0 addi" /* No flags */
"rd_a7 !35 addi" /* unlinkat */
"ecall");
}
int _getcwd(char* buf, int size)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a1 rs1_fp !-8 lw"
"rd_a7 !17 addi"
"ecall");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !214 addi"
"ecall");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("rd_a0 rs1_fp !-4 lw"
"rd_a7 !160 addi"
"ecall");
}
#endif
mescc-tools-1.5.2/M2libc/riscv32/riscv32_defs.M1 0000644 0000000 0000000 00000012514 14522760670 015747 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
DEFINE NULL 00000000
;; Opcodes
;; RV32I Base Instruction Set
DEFINE lui 37000000
DEFINE auipc 17000000
DEFINE jal 6F000000
DEFINE jalr 67000000
DEFINE beq 63000000
DEFINE bne 63100000
DEFINE blt 63400000
DEFINE bge 63500000
DEFINE bltu 63600000
DEFINE bgeu 63700000
DEFINE lb 03000000
DEFINE lh 03100000
DEFINE lw 03200000
DEFINE lbu 03400000
DEFINE lhu 03500000
DEFINE sb 23000000
DEFINE sh 23100000
DEFINE sw 23200000
DEFINE addi 13000000
DEFINE slti 13200000
DEFINE sltiu 13300000
DEFINE xori 13400000
DEFINE ori 13600000
DEFINE andi 13700000
DEFINE slli 13100000
DEFINE srli 13500000
DEFINE srai 13500040
DEFINE add 33000000
DEFINE sub 33000040
DEFINE sll 33100000
DEFINE slt 33200000
DEFINE sltu 33300000
DEFINE xor 33400000
DEFINE srl 33500000
DEFINE sra 33500040
DEFINE or 33600000
DEFINE and 33700000
DEFINE ecall 73000000
DEFINE ebreak 73001000
;; RV32M Standard Extensions
DEFINE mul 33000002
DEFINE mulh 33100002
DEFINE mulhsu 33200002
DEFINE mulhu 33300002
DEFINE div 33400002
DEFINE divu 33500002
DEFINE rem 33600002
DEFINE remu 33700002
;; Pseudoinstructions
DEFINE nop 13000000 # addi
DEFINE mv 13000000 # addi
DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE beqz 63000000 # beq
DEFINE bnez 63100000 # bne
DEFINE bltz 63400000 # blt
DEFINE ret 67800000 # rs1_ra jalr
;; Destination registers
;; register_number << 7
DEFINE rd_ra .80000000
DEFINE rd_sp .00010000
DEFINE rd_gp .80010000
DEFINE rd_tp .00020000
DEFINE rd_t0 .80020000
DEFINE rd_t1 .00030000
DEFINE rd_t2 .80030000
DEFINE rd_s0 .00040000
DEFINE rd_fp .00040000
DEFINE rd_s1 .80040000
DEFINE rd_a0 .00050000
DEFINE rd_a1 .80050000
DEFINE rd_a2 .00060000
DEFINE rd_a3 .80060000
DEFINE rd_a4 .00070000
DEFINE rd_a5 .80070000
DEFINE rd_a6 .00080000
DEFINE rd_a7 .80080000
DEFINE rd_s2 .00090000
DEFINE rd_s3 .80090000
DEFINE rd_s4 .000A0000
DEFINE rd_s5 .800A0000
DEFINE rd_s6 .000B0000
DEFINE rd_s7 .800B0000
DEFINE rd_s8 .000C0000
DEFINE rd_s9 .800C0000
DEFINE rd_s10 .000D0000
DEFINE rd_s11 .800D0000
DEFINE rd_t3 .000E0000
DEFINE rd_t4 .800E0000
DEFINE rd_t5 .000F0000
DEFINE rd_t6 .800F0000
;; First source registers
;; register_number << 15
DEFINE rs1_ra .00800000
DEFINE rs1_sp .00000100
DEFINE rs1_gp .00800100
DEFINE rs1_tp .00000200
DEFINE rs1_t0 .00800200
DEFINE rs1_t1 .00000300
DEFINE rs1_t2 .00800300
DEFINE rs1_s0 .00000400
DEFINE rs1_fp .00000400
DEFINE rs1_s1 .00800400
DEFINE rs1_a0 .00000500
DEFINE rs1_a1 .00800500
DEFINE rs1_a2 .00000600
DEFINE rs1_a3 .00800600
DEFINE rs1_a4 .00000700
DEFINE rs1_a5 .00800700
DEFINE rs1_a6 .00000800
DEFINE rs1_a7 .00800800
DEFINE rs1_s2 .00000900
DEFINE rs1_s3 .00800900
DEFINE rs1_s4 .00000A00
DEFINE rs1_s5 .00800A00
DEFINE rs1_s6 .00000B00
DEFINE rs1_s7 .00800B00
DEFINE rs1_s8 .00000C00
DEFINE rs1_s9 .00800C00
DEFINE rs1_s10 .00000D00
DEFINE rs1_s11 .00800D00
DEFINE rs1_t3 .00000E00
DEFINE rs1_t4 .00800E00
DEFINE rs1_t5 .00000F00
DEFINE rs1_t6 .00800F00
;; Second source registers
;; register_number << 20
DEFINE rs2_ra .00001000
DEFINE rs2_sp .00002000
DEFINE rs2_gp .00003000
DEFINE rs2_tp .00004000
DEFINE rs2_t0 .00005000
DEFINE rs2_t1 .00006000
DEFINE rs2_t2 .00007000
DEFINE rs2_s0 .00008000
DEFINE rs2_fp .00008000
DEFINE rs2_s1 .00009000
DEFINE rs2_a0 .0000A000
DEFINE rs2_a1 .0000B000
DEFINE rs2_a2 .0000C000
DEFINE rs2_a3 .0000D000
DEFINE rs2_a4 .0000E000
DEFINE rs2_a5 .0000F000
DEFINE rs2_a6 .00000001
DEFINE rs2_a7 .00001001
DEFINE rs2_s2 .00002001
DEFINE rs2_s3 .00003001
DEFINE rs2_s4 .00004001
DEFINE rs2_s5 .00005001
DEFINE rs2_s6 .00006001
DEFINE rs2_s7 .00007001
DEFINE rs2_s8 .00008001
DEFINE rs2_s9 .00009001
DEFINE rs2_s10 .0000A001
DEFINE rs2_s11 .0000B001
DEFINE rs2_t3 .0000C001
DEFINE rs2_t4 .0000D001
DEFINE rs2_t5 .0000E001
DEFINE rs2_t6 .0000F001
DEFINE rs1_x0 .00000000
DEFINE rs2_x0 .00000000
DEFINE rs2_x1 .00001000
DEFINE rs2_x2 .00002000
DEFINE rs2_x3 .00003000
DEFINE rs2_x4 .00004000
DEFINE rs2_x5 .00005000
DEFINE rs2_x6 .00006000
DEFINE rs2_x7 .00007000
DEFINE rs2_x8 .00008000
DEFINE rs2_x9 .00009000
DEFINE rs2_x10 .0000A000
DEFINE rs2_x11 .0000B000
DEFINE rs2_x12 .0000C000
DEFINE rs2_x13 .0000D000
DEFINE rs2_x14 .0000E000
DEFINE rs2_x15 .0000F000
DEFINE rs2_x16 .00000001
DEFINE rs2_x17 .00001001
DEFINE rs2_x18 .00002001
DEFINE rs2_x19 .00003001
DEFINE rs2_x20 .00004001
DEFINE rs2_x21 .00005001
DEFINE rs2_x22 .00006001
DEFINE rs2_x23 .00007001
DEFINE rs2_x24 .00008001
DEFINE rs2_x25 .00009001
DEFINE rs2_x26 .0000A001
DEFINE rs2_x27 .0000B001
DEFINE rs2_x28 .0000C001
DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001
mescc-tools-1.5.2/M2libc/riscv64/ 0000755 0000000 0000000 00000000000 14522760670 013256 5 ustar mescc-tools-1.5.2/M2libc/riscv64/ELF-riscv64-debug.hex2 0000644 0000000 0000000 00000005122 14522760670 017036 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### 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] Set at 0 because none cares
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
F3 00 ## e_machine Indicating RISC-V
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
%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
:ELF_program_header__text
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-1.5.2/M2libc/riscv64/ELF-riscv64.hex2 0000644 0000000 0000000 00000005046 14522760670 015757 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### 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] Set at 0 because none cares
00 00 00 00 00 00 00 ## e_ident[EI_PAD]
02 00 ## e_type Indicating Executable
F3 00 ## e_machine Indicating RISC-V
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-1.5.2/M2libc/riscv64/libc-core.M1 0000644 0000000 0000000 00000002754 14522760670 015324 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## 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
rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv
rd_a0 rs1_fp !8 addi ; ARGV_address = FP + 8
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put argv on the stack
; Prepare envp
rd_a0 rs1_fp mv ; Address we need to load from
rd_a0 rs1_a0 ld ; Get ARGC
rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put envp on the stack
; Stack offset
rd_fp rs1_fp !8 addi
; Call main function
rd_ra $FUNCTION_main jal
; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
rd_a7 !93 addi ; Syscall for exit
ecall ; Exit with code in a0
mescc-tools-1.5.2/M2libc/riscv64/libc-full.M1 0000644 0000000 0000000 00000003667 14522760670 015342 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## 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
rd_fp rs1_sp mv ; Protect stack pointer
; Prepare argv
rd_a0 rs1_fp !8 addi ; ARGV_address = FP + 8
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put argv on the stack
; Prepare envp
rd_a0 rs1_fp mv ; Address we need to load from
rd_a0 rs1_a0 ld ; Get ARGC
rd_a0 rs1_a0 !2 addi ; OFFSET = ARGC + 2
rd_a0 rs1_a0 rs2_x3 slli ; OFFSET = OFFSET * WORDSIZE
rd_a0 rs1_fp rs2_a0 add ; ENVP_address = RSP + OFFSET
rd_sp rs1_sp !-8 addi
rs1_sp rs2_a0 sd ; Put envp on the stack
rd_a1 ~GLOBAL__envp auipc ; Get _envp global
rd_a1 rs1_a1 !GLOBAL__envp addi
rs1_a1 rs2_a0 sd ; Save environment to _envp
; Stack offset
rd_fp rs1_fp !8 addi
; Setup for malloc
rd_ra $FUNCTION___init_malloc jal
; Setup for FILE*
rd_ra $FUNCTION___init_io jal
; Call main function
rd_ra $FUNCTION_main jal
; Put return value on the stack so that _exit gets it
rd_sp rs1_sp !-16 addi
rs1_sp rs2_a0 sd
; Exit to kernel
:FUNCTION_exit
rd_ra $FUNCTION___kill_io jal
:FUNCTION__exit
rd_a0 rs1_sp ld
rd_a7 !93 addi ; Syscall for exit
ecall ; Exit with code in a0
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/riscv64/linux/ 0000755 0000000 0000000 00000000000 14522760670 014415 5 ustar mescc-tools-1.5.2/M2libc/riscv64/linux/bootstrap.c 0000644 0000000 0000000 00000006114 14522760670 016600 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("rd_a0 rs1_fp !-8 ld"
"rs1_sp rs2_a0 sd"
"rd_a1 rs1_sp mv"
"rd_a2 !1 addi"
"rd_a7 !63 addi"
"ecall"
"rd_a1 mv"
"rd_t0 rs1_a0 mv"
"rd_a0 rs1_sp ld"
"rs1_t0 @8 bnez"
"rd_a0 !-1 addi");
}
void fputc(char s, FILE* f)
{
asm("rd_a0 rs1_fp !-16 ld"
"rd_a1 rs1_fp !-8 addi"
"rd_a2 !1 addi" /* 1 byte */
"rd_a7 !64 addi" /* write */
"ecall");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a3 rs1_fp !-24 ld"
"rd_a7 !56 addi" /* openat */
"ecall");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !57 addi" /* close */
"ecall");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !214 addi" /* brk */
"ecall");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !93 addi" /* exit */
"ecall");
}
mescc-tools-1.5.2/M2libc/riscv64/linux/fcntl.c 0000644 0000000 0000000 00000002444 14522760670 015673 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a3 rs1_fp !-24 ld"
"rd_a7 !56 addi"
"ecall");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/riscv64/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 015233 5 ustar mescc-tools-1.5.2/M2libc/riscv64/linux/sys/stat.c 0000644 0000000 0000000 00000003675 14522760670 016365 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a7 !53 addi"
"ecall");
}
int fchmod(int a, mode_t b)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a7 !52 addi"
"ecall");
}
int mkdir(char const* a, mode_t b)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a7 !34 addi"
"ecall");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a3 rs1_fp !-24 ld"
"rd_a7 !33 addi"
"ecall");
}
mode_t umask(mode_t m)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !166 addi"
"ecall");
}
#endif
mescc-tools-1.5.2/M2libc/riscv64/linux/unistd.c 0000644 0000000 0000000 00000007051 14522760670 016072 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
#define __SI_SWAP_ERRNO_CODE
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 rs1_fp !-16 ld"
"rd_a3 addi" /* flags = 0 */
"rd_a7 !48 addi"
"ecall");
}
int chdir(char* path)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !49 addi"
"ecall");
}
int fchdir(int fd)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !50 addi"
"ecall");
}
void _exit(int value);
int fork()
{
asm("rd_a7 !220 addi"
"rd_a0 !17 addi" /* SIGCHld */
"rd_a1 mv" /* Child uses duplicate of parent's stack */
"ecall");
}
int waitpid (int pid, int* status_ptr, int options)
{
/* Uses wait4 with struct rusage *ru set to NULL */
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a2 rs1_fp !-24 ld"
"rd_a3 addi"
"rd_a7 !260 addi"
"ecall");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a2 rs1_fp !-24 ld"
"rd_a7 !221 addi"
"ecall");
}
int read(int fd, char* buf, unsigned count)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a2 rs1_fp !-24 ld"
"rd_a7 !63 addi"
"ecall");
}
int write(int fd, char* buf, unsigned count)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a2 rs1_fp !-24 ld"
"rd_a7 !64 addi"
"ecall");
}
int lseek(int fd, int offset, int whence)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a2 rs1_fp !-24 ld"
"rd_a7 !62 addi"
"ecall");
}
int close(int fd)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !57 addi" /* close */
"ecall");
}
int unlink (char* filename)
{
asm("rd_a0 !-100 addi" /* AT_FDCWD */
"rd_a1 rs1_fp !-8 ld"
"rd_a2 !0 addi" /* No flags */
"rd_a7 !35 addi" /* unlinkat */
"ecall");
}
int _getcwd(char* buf, int size)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a1 rs1_fp !-16 ld"
"rd_a7 !17 addi"
"ecall");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !214 addi"
"ecall");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("rd_a0 rs1_fp !-8 ld"
"rd_a7 !160 addi"
"ecall");
}
#endif
mescc-tools-1.5.2/M2libc/riscv64/riscv64_defs.M1 0000644 0000000 0000000 00000013414 14522760670 015761 0 ustar ## Copyright (C) 2021 Andrius Štikonas
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
DEFINE NULL 0000000000000000
;; Opcodes
;; RV32I Base Instruction Set
DEFINE lui 37000000
DEFINE auipc 17000000
DEFINE jal 6F000000
DEFINE jalr 67000000
DEFINE beq 63000000
DEFINE bne 63100000
DEFINE blt 63400000
DEFINE bge 63500000
DEFINE bltu 63600000
DEFINE bgeu 63700000
DEFINE lb 03000000
DEFINE lh 03100000
DEFINE lw 03200000
DEFINE lbu 03400000
DEFINE lhu 03500000
DEFINE sb 23000000
DEFINE sh 23100000
DEFINE sw 23200000
DEFINE addi 13000000
DEFINE slti 13200000
DEFINE sltiu 13300000
DEFINE xori 13400000
DEFINE ori 13600000
DEFINE andi 13700000
DEFINE slli 13100000
DEFINE srli 13500000
DEFINE srai 13500040
DEFINE add 33000000
DEFINE sub 33000040
DEFINE sll 33100000
DEFINE slt 33200000
DEFINE sltu 33300000
DEFINE xor 33400000
DEFINE srl 33500000
DEFINE sra 33500040
DEFINE or 33600000
DEFINE and 33700000
DEFINE ecall 73000000
DEFINE ebreak 73001000
;; RV64I Base Instruction set
DEFINE lwu 03600000
DEFINE ld 03300000
DEFINE sd 23300000
DEFINE addiw 1B000000
DEFINE slliw 1B100000
DEFINE srliw 1B500000
DEFINE sraiw 1B500040
DEFINE addw 3B000000
DEFINE subw 3B000040
DEFINE sllw 3B100000
DEFINE srlw 3B500000
DEFINE sraw 3B500040
;; RV32M Standard Extensions
DEFINE mul 33000002
DEFINE mulh 33100002
DEFINE mulhsu 33200002
DEFINE mulhu 33300002
DEFINE div 33400002
DEFINE divu 33500002
DEFINE rem 33600002
DEFINE remu 33700002
;; RV64M Standard Extensions
DEFINE mulw 3B000002
DEFINE divw 3B400002
DEFINE divuw 3B500002
DEFINE remw 3B600002
DEFINE remuw 3B700002
;; Pseudoinstructions
DEFINE nop 13000000 # addi
DEFINE mv 13000000 # addi
DEFINE not 1340F0FF # xori, RD, RS, -1
DEFINE beqz 63000000 # beq
DEFINE bnez 63100000 # bne
DEFINE bltz 63400000 # blt
DEFINE ret 67800000 # rs1_ra jalr
;; Destination registers
;; register_number << 7
DEFINE rd_ra .80000000
DEFINE rd_sp .00010000
DEFINE rd_gp .80010000
DEFINE rd_tp .00020000
DEFINE rd_t0 .80020000
DEFINE rd_t1 .00030000
DEFINE rd_t2 .80030000
DEFINE rd_s0 .00040000
DEFINE rd_fp .00040000
DEFINE rd_s1 .80040000
DEFINE rd_a0 .00050000
DEFINE rd_a1 .80050000
DEFINE rd_a2 .00060000
DEFINE rd_a3 .80060000
DEFINE rd_a4 .00070000
DEFINE rd_a5 .80070000
DEFINE rd_a6 .00080000
DEFINE rd_a7 .80080000
DEFINE rd_s2 .00090000
DEFINE rd_s3 .80090000
DEFINE rd_s4 .000A0000
DEFINE rd_s5 .800A0000
DEFINE rd_s6 .000B0000
DEFINE rd_s7 .800B0000
DEFINE rd_s8 .000C0000
DEFINE rd_s9 .800C0000
DEFINE rd_s10 .000D0000
DEFINE rd_s11 .800D0000
DEFINE rd_t3 .000E0000
DEFINE rd_t4 .800E0000
DEFINE rd_t5 .000F0000
DEFINE rd_t6 .800F0000
;; First source registers
;; register_number << 15
DEFINE rs1_ra .00800000
DEFINE rs1_sp .00000100
DEFINE rs1_gp .00800100
DEFINE rs1_tp .00000200
DEFINE rs1_t0 .00800200
DEFINE rs1_t1 .00000300
DEFINE rs1_t2 .00800300
DEFINE rs1_s0 .00000400
DEFINE rs1_fp .00000400
DEFINE rs1_s1 .00800400
DEFINE rs1_a0 .00000500
DEFINE rs1_a1 .00800500
DEFINE rs1_a2 .00000600
DEFINE rs1_a3 .00800600
DEFINE rs1_a4 .00000700
DEFINE rs1_a5 .00800700
DEFINE rs1_a6 .00000800
DEFINE rs1_a7 .00800800
DEFINE rs1_s2 .00000900
DEFINE rs1_s3 .00800900
DEFINE rs1_s4 .00000A00
DEFINE rs1_s5 .00800A00
DEFINE rs1_s6 .00000B00
DEFINE rs1_s7 .00800B00
DEFINE rs1_s8 .00000C00
DEFINE rs1_s9 .00800C00
DEFINE rs1_s10 .00000D00
DEFINE rs1_s11 .00800D00
DEFINE rs1_t3 .00000E00
DEFINE rs1_t4 .00800E00
DEFINE rs1_t5 .00000F00
DEFINE rs1_t6 .00800F00
;; Second source registers
;; register_number << 20
DEFINE rs2_ra .00001000
DEFINE rs2_sp .00002000
DEFINE rs2_gp .00003000
DEFINE rs2_tp .00004000
DEFINE rs2_t0 .00005000
DEFINE rs2_t1 .00006000
DEFINE rs2_t2 .00007000
DEFINE rs2_s0 .00008000
DEFINE rs2_fp .00008000
DEFINE rs2_s1 .00009000
DEFINE rs2_a0 .0000A000
DEFINE rs2_a1 .0000B000
DEFINE rs2_a2 .0000C000
DEFINE rs2_a3 .0000D000
DEFINE rs2_a4 .0000E000
DEFINE rs2_a5 .0000F000
DEFINE rs2_a6 .00000001
DEFINE rs2_a7 .00001001
DEFINE rs2_s2 .00002001
DEFINE rs2_s3 .00003001
DEFINE rs2_s4 .00004001
DEFINE rs2_s5 .00005001
DEFINE rs2_s6 .00006001
DEFINE rs2_s7 .00007001
DEFINE rs2_s8 .00008001
DEFINE rs2_s9 .00009001
DEFINE rs2_s10 .0000A001
DEFINE rs2_s11 .0000B001
DEFINE rs2_t3 .0000C001
DEFINE rs2_t4 .0000D001
DEFINE rs2_t5 .0000E001
DEFINE rs2_t6 .0000F001
DEFINE rs1_x0 .00000000
DEFINE rs2_x0 .00000000
DEFINE rs2_x1 .00001000
DEFINE rs2_x2 .00002000
DEFINE rs2_x3 .00003000
DEFINE rs2_x4 .00004000
DEFINE rs2_x5 .00005000
DEFINE rs2_x6 .00006000
DEFINE rs2_x7 .00007000
DEFINE rs2_x8 .00008000
DEFINE rs2_x9 .00009000
DEFINE rs2_x10 .0000A000
DEFINE rs2_x11 .0000B000
DEFINE rs2_x12 .0000C000
DEFINE rs2_x13 .0000D000
DEFINE rs2_x14 .0000E000
DEFINE rs2_x15 .0000F000
DEFINE rs2_x16 .00000001
DEFINE rs2_x17 .00001001
DEFINE rs2_x18 .00002001
DEFINE rs2_x19 .00003001
DEFINE rs2_x20 .00004001
DEFINE rs2_x21 .00005001
DEFINE rs2_x22 .00006001
DEFINE rs2_x23 .00007001
DEFINE rs2_x24 .00008001
DEFINE rs2_x25 .00009001
DEFINE rs2_x26 .0000A001
DEFINE rs2_x27 .0000B001
DEFINE rs2_x28 .0000C001
DEFINE rs2_x29 .0000D001
DEFINE rs2_x30 .0000E001
DEFINE rs2_x31 .0000F001
mescc-tools-1.5.2/M2libc/signal.h 0000644 0000000 0000000 00000002467 14522760670 013415 0 ustar /* Copyright (C) 2021 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SIGNAL_H
#define _SIGNAL_H
#define CLD_EXITED 1 /* child has exited */
#define CLD_KILLED 2 /* child was killed */
#define CLD_DUMPED 3 /* child terminated abnormally */
#define CLD_TRAPPED 4 /* traced child has trapped */
#define CLD_STOPPED 5 /* child has stopped */
#define CLD_CONTINUED 6 /* stopped child has continued */
struct siginfo_t {
int si_signo;
#ifdef __SI_SWAP_ERRNO_CODE
int si_code;
int si_errno;
#else
int si_errno;
int si_code;
#endif
int si_pid;
int si_uid;
int si_status;
int si_utime;
int si_stime;
};
#endif
mescc-tools-1.5.2/M2libc/stddef.h 0000644 0000000 0000000 00000001517 14522760670 013404 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _STDDEF_H
#define _STDDEF_H
#include
#define NULL 0
typedef long ptrdiff_t;
typedef ulong size_t;
#endif
mescc-tools-1.5.2/M2libc/stdio.c 0000644 0000000 0000000 00000017347 14522760670 013260 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
#include
#include
#include
#include
#include
/* Required constants */
/* For file I/O*/
#define EOF 0xFFFFFFFF
#define BUFSIZ 0x1000
/* For lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/* Required variables */
FILE* stdin;
FILE* stdout;
FILE* stderr;
FILE* __list;
void __init_io()
{
__list = NULL;
stdin = calloc(1, sizeof(FILE));
stdin->fd = STDIN_FILENO;
stdin->bufmode = O_RDONLY;
stdin->buflen = 1;
stdin->buffer = calloc(2, sizeof(char));
stdout = calloc(1, sizeof(FILE));
stdout->fd = STDOUT_FILENO;
stdout->bufmode = O_WRONLY;
stdout->buflen = 512;
stdout->buffer = calloc(514, sizeof(char));
stderr = calloc(1, sizeof(FILE));
stderr->fd = STDERR_FILENO;
stderr->bufmode = O_WRONLY;
stderr->buflen = 512;
stderr->buffer = calloc(514, sizeof(char));
}
/* Flush all IO on exit */
int fflush(FILE* stream);
void __kill_io()
{
fflush(stdout);
fflush(stderr);
while(NULL != __list)
{
fflush(__list);
__list = __list->next;
}
}
/* Standard C functions */
/* Getting */
int read(int fd, char* buf, unsigned count);
int fgetc(FILE* f)
{
/* Only read on read buffers */
if(O_WRONLY == f->bufmode) return EOF;
/* Deal with stdin */
if(STDIN_FILENO == f->fd)
{
f->bufpos = 0;
int r = read(f->fd, f->buffer, 1);
/* Catch special case of STDIN gets nothing (AN EOF) */
if(0 == r) return EOF;
}
/* Catch EOF */
if(f->buflen <= f->bufpos) return EOF;
/* Deal with standard case */
int ret = f->buffer[f->bufpos];
f->bufpos = f->bufpos + 1;
/* Ensure 0xFF doesn't return EOF */
return (ret & 0xFF);
}
size_t fread( void* buffer, size_t size, size_t count, FILE* stream )
{
if(0 == size) return 0;
if(0 == count) return 0;
long n = size + count - 1;
char* p = buffer;
long i;
unsigned c;
for(i = 0; i < n; i = i + 1)
{
c = fgetc(stream);
if(EOF == c) return (i/size);
p[i] = c;
}
return (i/size);
}
int getchar()
{
return fgetc(stdin);
}
char* fgets(char* str, int count, FILE* stream)
{
int i = 0;
int ch;
while(i < count)
{
ch = fgetc(stream);
if(EOF == ch) break;
str[i] = ch;
i = i + 1;
if('\n' == ch) break;
}
return str;
}
/* Putting */
void fputc(char s, FILE* f)
{
/* Only write on write buffers */
if(O_RDONLY == f->bufmode) return;
/* Add to buffer */
f->buffer[f->bufpos] = s;
f->bufpos = f->bufpos + 1;
/* Flush if full or '\n' */
if(f->bufpos == f->buflen) fflush(f);
else if(('\n' == s) && (2 >= f->fd)) fflush(f);
}
size_t fwrite(void const* buffer, size_t size, size_t count, FILE* stream )
{
long n = size * count;
if(0 == n) return 0;
char* p = buffer;
int c;
long i;
for(i=0; i < n; i = i + 1)
{
c = p[i];
fputc(c, stream);
}
return (i/size);
}
void putchar(char s)
{
fputc(s, stdout);
}
int fputs(char const* str, FILE* stream)
{
while(0 != str[0])
{
fputc(str[0], stream);
str = str + 1;
}
return 0;
}
int puts(char const* str)
{
fputs(str, stdout);
fputc('\n', stdout);
return 0;
}
int lseek(int fd, int offset, int whence);
/* File management */
FILE* fopen(char const* filename, char const* mode)
{
int f;
FILE* fi = calloc(1, sizeof(FILE));
fi->next = __list;
if(NULL != __list) __list->prev = fi;
__list = fi;
int size;
if('w' == mode[0]) f = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 00600);
else f = open(filename, 0, 0); /* Everything else is a read */
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
if('w' == mode[0])
{
/* Buffer as much as possible */
fi->buffer = malloc(BUFSIZ * sizeof(char));
fi->buflen = BUFSIZ;
fi->bufmode = O_WRONLY;
}
else
{
/* Get enough buffer to read it all */
size = lseek(f, 0, SEEK_END);
fi->buffer = malloc((size + 1) * sizeof(char));
fi->buflen = size;
fi->bufmode = O_RDONLY;
/* Now read it all */
lseek(f, 0, SEEK_SET);
read(f, fi->buffer, size);
}
fi->fd = f;
return fi;
}
FILE* fdopen(int fd, char* mode)
{
FILE* fi = calloc(1, sizeof(FILE));
fi->next = __list;
if(NULL != __list) __list->prev = fi;
__list = fi;
int size;
if('w' == mode[0])
{
/* Buffer as much as possible */
fi->buffer = malloc(BUFSIZ * sizeof(char));
fi->buflen = BUFSIZ;
fi->bufmode = O_WRONLY;
}
else
{
/* Get enough buffer to read it all */
size = lseek(fd, 0, SEEK_END);
fi->buffer = malloc((size + 1) * sizeof(char));
fi->buflen = size;
fi->bufmode = O_RDONLY;
/* Now read it all */
lseek(fd, 0, SEEK_SET);
read(fd, fi->buffer, size);
}
fi->fd = fd;
return fi;
}
int write(int fd, char* buf, unsigned count);
int fflush(FILE* stream)
{
/* We only need to flush on writes */
if(O_RDONLY == stream->bufmode) return 0;
/* If nothing to flush */
if(0 ==stream->bufpos) return 0;
/* The actual flushing */
int error = write(stream->fd, stream->buffer, stream->bufpos);
/* Keep track of position */
stream->file_pos = stream->file_pos + stream->bufpos;
stream->bufpos = 0;
return error;
}
int close(int fd);
int fclose(FILE* stream)
{
/* Deal with STDIN, STDOUT and STDERR */
/* No close for you */
if(2 >= stream->fd) return 0;
/* We only need to flush on writes */
if(O_WRONLY == stream->bufmode)
{
fflush(stream);
}
/* Need to keep the File Descriptor for a moment */
int fd = stream->fd;
/* Remove from __list */
if(NULL != stream->prev) stream->prev->next = stream->next;
if(NULL != stream->next) stream->next->prev = stream->prev;
/* Deal with special case of first node in __list */
if (__list == stream) __list = __list->next;
/* Free up the buffer and struct used for FILE */
free(stream->buffer);
free(stream);
/* Do the actual closing */
return close(fd);
}
int unlink(char* filename);
/* File Removal */
int remove(char *pathname)
{
return unlink(pathname);
}
/* File Positioning */
int ungetc(int ch, FILE* stream)
{
/* Deal with STDIN, STDOUT and STDERR */
/* No ungetc for you */
if(2 >= stream->fd) return EOF;
/* You can't unget on a write stream! */
if(O_WRONLY == stream->bufmode) return EOF;
/* Don't underflow */
if(0 == stream->bufpos) return EOF;
/* Don't let crap be shoved into read stream */
if(stream->buffer[stream->bufpos - 1] != ch) return EOF;
stream->bufpos = stream->bufpos - 1;
return ch;
}
long ftell(FILE* stream)
{
/* Deal with STDIN, STDOUT and STDERR */
/* No ftell for you */
if(2 >= stream->fd) return 0;
/* Deal with buffered output */
if(O_WRONLY == stream->bufmode) return stream->file_pos + stream->bufpos;
/* Deal with read */
return stream->bufpos;
}
int fseek(FILE* f, long offset, int whence)
{
/* Deal with STDIN, STDOUT and STDERR */
/* No seek and destroy missions */
if(2 >= f->fd) return 0;
/* Deal with ugly case */
if(O_WRONLY == f->bufmode)
{
fflush(f);
return lseek(f->fd, offset, whence);
}
/* Deal with read mode */
int pos;
if(SEEK_SET == whence)
{
pos = offset;
}
else if(SEEK_CUR == whence)
{
pos = f->bufpos + offset;
}
else if(SEEK_END == whence)
{
pos = f->buflen + offset;
}
else return -1;
if(pos < 0) return -1;
if(pos > f->buflen) return -1;
f->bufpos = pos;
return pos;
}
void rewind(FILE* f)
{
fseek(f, 0, SEEK_SET);
}
mescc-tools-1.5.2/M2libc/stdio.h 0000644 0000000 0000000 00000004640 14522760670 013255 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _STDIO_H
#define _STDIO_H
#ifdef __M2__
/* Actual format of FILE */
struct __IO_FILE
{
int fd;
int bufmode; /* O_RDONLY = 0, O_WRONLY = 1 */
int bufpos;
int file_pos;
int buflen;
char* buffer;
struct __IO_FILE* next;
struct __IO_FILE* prev;
};
/* Now give us the FILE we all love */
typedef struct __IO_FILE FILE;
#include
#else
#include
#include
#include
#include
#include
/* Required constants */
/* For file I/O*/
#define EOF -1
#define BUFSIZ 4096
/* For lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
/* Actual format of FILE */
struct __IO_FILE
{
int fd;
int bufmode; /* 0 = no buffer, 1 = read, 2 = write */
int bufpos;
int buflen;
char* buffer;
};
/* Now give us the FILE we all love */
typedef struct __IO_FILE FILE;
/* Required variables */
extern FILE* stdin;
extern FILE* stdout;
extern FILE* stderr;
/* Standard C functions */
/* Getting */
extern int fgetc(FILE* f);
extern int getchar();
extern char* fgets(char* str, int count, FILE* stream);
extern size_t fread( void* buffer, size_t size, size_t count, FILE* stream );
/* Putting */
extern void fputc(char s, FILE* f);
extern void putchar(char s);
extern int fputs(char const* str, FILE* stream);
extern int puts(char const* str);
extern size_t fwrite(void const* buffer, size_t size, size_t count, FILE* stream );
/* File management */
extern FILE* fopen(char const* filename, char const* mode);
extern int fclose(FILE* stream);
extern int fflush(FILE* stream);
/* File Positioning */
extern int ungetc(int ch, FILE* stream);
extern long ftell(FILE* stream);
extern int fseek(FILE* f, long offset, int whence);
extern void rewind(FILE* f);
#endif
#endif
mescc-tools-1.5.2/M2libc/stdlib.c 0000644 0000000 0000000 00000030416 14522760670 013407 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
#include
#include
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#define _IN_USE 1
#define _NOT_IN_USE 0
typedef char wchar_t;
void exit(int value);
struct _malloc_node
{
struct _malloc_node *next;
void* block;
size_t size;
int used;
};
struct _malloc_node* _allocated_list;
struct _malloc_node* _free_list;
/********************************
* The core POSIX malloc *
********************************/
long _malloc_ptr;
long _brk_ptr;
void* _malloc_brk(unsigned size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
void __init_malloc()
{
_free_list = NULL;
_allocated_list = NULL;
return;
}
/************************************************************************
* Handle with the tricky insert behaviors for our nodes *
* As free lists must be sorted from smallest to biggest to enable *
* cheap first fit logic *
* The free function however is rarely called, so it can kick sand and *
* do things the hard way *
************************************************************************/
void _malloc_insert_block(struct _malloc_node* n, int used)
{
/* Allocated block doesn't care about order */
if(_IN_USE == used)
{
/* Literally just be done as fast as possible */
n->next = _allocated_list;
_allocated_list = n;
return;
}
/* sanity check garbage */
if(_NOT_IN_USE != used) exit(EXIT_FAILURE);
if(_NOT_IN_USE != n->used) exit(EXIT_FAILURE);
if(NULL != n->next) exit(EXIT_FAILURE);
/* Free block really does care about order */
struct _malloc_node* i = _free_list;
struct _malloc_node* last = NULL;
while(NULL != i)
{
/* sort smallest to largest */
if(n->size <= i->size)
{
/* Connect */
n->next = i;
/* If smallest yet */
if(NULL == last) _free_list = n;
/* or just another average block */
else last->next = n;
return;
}
/* iterate */
last = i;
i = i->next;
}
/* looks like we are the only one */
if(NULL == last) _free_list = n;
/* or we are the biggest yet */
else last->next = n;
}
/************************************************************************
* We only mark a block as unused, we don't actually deallocate it here *
* But rather shove it into our _free_list *
************************************************************************/
void free(void* ptr)
{
/* just in case someone needs to quickly turn it off */
#ifndef _MALLOC_DISABLE_FREE
struct _malloc_node* i = _allocated_list;
struct _malloc_node* last = NULL;
/* walk the whole freaking list if needed to do so */
while(NULL != i)
{
/* did we find it? */
if(i->block == ptr)
{
/* detach the block */
if(NULL == last) _allocated_list = i->next;
/* in a way that doesn't break the allocated list */
else last->next = i->next;
/* insert into free'd list */
i->used = _NOT_IN_USE;
i->next = NULL;
_malloc_insert_block(i, _NOT_IN_USE);
return;
}
/* iterate */
last = i;
i = i->next;
}
/* we received a pointer to a block that wasn't allocated */
/* Bail *HARD* because I don't want to cover this edge case */
exit(EXIT_FAILURE);
#endif
/* if free is disabled, there is nothing to do */
return;
}
/************************************************************************
* find if there is any "FREED" blocks big enough to sit on our memory *
* budget's face and ruin its life. Respectfully of course *
************************************************************************/
void* _malloc_find_free(unsigned size)
{
struct _malloc_node* i = _free_list;
struct _malloc_node* last = NULL;
/* Walk the whole list if need be */
while(NULL != i)
{
/* see if anything in it is equal or bigger than what I need */
if((_NOT_IN_USE == i->used) && (i->size > size))
{
/* disconnect from list ensuring we don't break free doing so */
if(NULL == last) _free_list = i->next;
else last->next = i->next;
/* insert into allocated list */
i->used = _IN_USE;
i->next = NULL;
_malloc_insert_block(i, _IN_USE);
return i->block;
}
/* iterate (will loop forever if you get this wrong) */
last = i;
i = i->next;
}
/* Couldn't find anything big enough */
return NULL;
}
/************************************************************************
* Well we couldn't find any memory good enough to satisfy our needs so *
* we are going to have to go beg for some memory on the street corner *
************************************************************************/
void* _malloc_add_new(unsigned size)
{
struct _malloc_node* n;
#ifdef __uefi__
n = _malloc_uefi(sizeof(struct _malloc_node));
/* Check if we were beaten */
if(NULL == n) return NULL;
n->block = _malloc_uefi(size);
#else
n = _malloc_brk(sizeof(struct _malloc_node));
/* Check if we were beaten */
if(NULL == n) return NULL;
n->block = _malloc_brk(size);
#endif
/* check if we were robbed */
if(NULL == n->block) return NULL;
/* Looks like we made it home safely */
n->size = size;
n->next = NULL;
n->used = _IN_USE;
/* lets pop the cork and party */
_malloc_insert_block(n, _IN_USE);
return n->block;
}
/************************************************************************
* Safely iterates over all malloc nodes and frees them *
************************************************************************/
void __malloc_node_iter(struct _malloc_node* node, FUNCTION _free)
{
struct _malloc_node* current;
while(node != NULL)
{
current = node;
node = node->next;
_free(current->block);
_free(current);
}
}
/************************************************************************
* Runs a callback with all previously allocated nodes. *
* This can be useful if operating system does not do any clean up. *
************************************************************************/
void* _malloc_release_all(FUNCTION _free)
{
__malloc_node_iter(_allocated_list, _free);
__malloc_node_iter(_free_list, _free);
}
/************************************************************************
* Provide a POSIX standardish malloc function to keep things working *
************************************************************************/
void* malloc(unsigned size)
{
/* skip allocating nothing */
if(0 == size) return NULL;
/* use one of the standard block sizes */
size_t max = 1 << 30;
size_t used = 256;
while(used < size)
{
used = used << 1;
/* fail big allocations */
if(used > max) return NULL;
}
/* try the cabinets around the house */
void* ptr = _malloc_find_free(used);
/* looks like we need to get some more from the street corner */
if(NULL == ptr)
{
ptr = _malloc_add_new(used);
}
/* hopefully you can handle NULL pointers, good luck */
return ptr;
}
/************************************************************************
* Provide a POSIX standardish memset function to keep things working *
************************************************************************/
void* memset(void* ptr, int value, int num)
{
char* s;
/* basically walk the block 1 byte at a time and set it to any value you want */
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
return ptr;
}
/************************************************************************
* Provide a POSIX standardish calloc function to keep things working *
************************************************************************/
void* calloc(int count, int size)
{
/* if things get allocated, we are good*/
void* ret = malloc(count * size);
/* otherwise good luck */
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
/* USED EXCLUSIVELY BY MKSTEMP */
void __set_name(char* s, int i)
{
s[5] = '0' + (i % 10);
i = i / 10;
s[4] = '0' + (i % 10);
i = i / 10;
s[3] = '0' + (i % 10);
i = i / 10;
s[2] = '0' + (i % 10);
i = i / 10;
s[1] = '0' + (i % 10);
i = i / 10;
s[0] = '0' + i;
}
/************************************************************************
* Provide a POSIX standardish mkstemp function to keep things working *
************************************************************************/
int mkstemp(char *template)
{
/* get length of template */
int i = 0;
while(0 != template[i]) i = i + 1;
i = i - 1;
/* String MUST be more than 6 characters in length */
if(i < 6) return -1;
/* Sanity check the string matches the template requirements */
int count = 6;
int c;
while(count > 0)
{
c = template[i];
/* last 6 chars must be X */
if('X' != c) return -1;
template[i] = '0';
i = i - 1;
count = count - 1;
}
int fd = -1;
count = -1;
/* open will return -17 or other values */
while(0 > fd)
{
/* Just give up after the planet has blown up */
if(9000 < count) return -1;
/* Try up to 9000 unique filenames before stopping */
count = count + 1;
__set_name(template+i+1, count);
/* Pray we can */
fd = open(template, O_RDWR | O_CREAT | O_EXCL, 00600);
}
/* well that only took count many tries */
return fd;
}
/************************************************************************
* wcstombs - convert a wide-character string to a multibyte string *
* because seriously UEFI??? UTF-16 is a bad design choice but I guess *
* they were drinking pretty hard when they designed UEFI; it is DOS *
* but somehow they magically found ways of making it worse *
************************************************************************/
size_t wcstombs(char* dest, char* src, size_t n)
{
int i = 0;
do
{
/* UTF-16 is 2bytes per char and that first byte maps good enough to ASCII */
dest[i] = src[2 * i];
if(dest[i] == 0)
{
break;
}
i = i + 1;
n = n - 1;
} while (n != 0);
return i;
}
/************************************************************************
* getenv - get an environmental variable *
************************************************************************/
size_t _strlen(char const* str)
{
size_t i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
int _strncmp(char const* lhs, char const* rhs, size_t count)
{
size_t i = 0;
while(count > i)
{
if(0 == lhs[i]) break;
if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
i = i + 1;
}
return 0;
}
char** _envp;
char* getenv (char const* name)
{
char** p = _envp;
char* q;
int length = _strlen(name);
while (p[0] != 0)
{
if(_strncmp(name, p[0], length) == 0)
{
q = p[0] + length;
if(q[0] == '=')
return q + 1;
}
p += sizeof(char**); /* M2 pointer arithemtic */
}
return 0;
}
/************************************************************************
* setenv - set an environmental variable *
************************************************************************/
char* _strcpy(char* dest, char const* src)
{
int i = 0;
while (0 != src[i])
{
dest[i] = src[i];
i = i + 1;
}
dest[i] = 0;
return dest;
}
int setenv(char const *s, char const *v, int overwrite_p)
{
char** p = _envp;
int length = _strlen(s);
char* q;
while (p[0] != 0)
{
if (_strncmp (s, p[0], length) == 0)
{
q = p[0] + length;
if (q[0] == '=')
break;
}
p += sizeof(char**); /* M2 pointer arithemtic */
}
char *entry = malloc (length + _strlen(v) + 2);
int end_p = p[0] == 0;
p[0] = entry;
_strcpy(entry, s);
_strcpy(entry + length, "=");
_strcpy(entry + length + 1, v);
entry[length + _strlen(v) + 2] = 0;
if (end_p != 0)
p[1] = 0;
return 0;
}
mescc-tools-1.5.2/M2libc/stdlib.h 0000644 0000000 0000000 00000002275 14522760670 013416 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _STDLIB_H
#define _STDLIB_H
#include
#ifdef __M2__
#include
#else
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
extern void exit(int value);
extern long _malloc_ptr;
extern long _brk_ptr;
extern void free(void* l);
extern void* malloc(unsigned size);
extern void* memset(void* ptr, int value, int num);
extern void* calloc(int count, int size);
extern char *getenv(const char *name);
size_t wcstombs(char* dest, const wchar_t* src, size_t n);
#endif
#endif
mescc-tools-1.5.2/M2libc/string.c 0000644 0000000 0000000 00000007710 14522760670 013435 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
char* strcpy(char* dest, char const* src)
{
int i = 0;
while (0 != src[i])
{
dest[i] = src[i];
i = i + 1;
}
dest[i] = 0;
return dest;
}
char* strncpy(char* dest, char const* src, size_t count)
{
if(0 == count) return dest;
size_t i = 0;
while(0 != src[i])
{
dest[i] = src[i];
i = i + 1;
if(count == i) return dest;
}
while(i <= count)
{
dest[i] = 0;
i = i + 1;
}
return dest;
}
char* strcat(char* dest, char const* src)
{
int i = 0;
int j = 0;
while(0 != dest[i]) i = i + 1;
while(0 != src[j])
{
dest[i] = src[j];
i = i + 1;
j = j + 1;
}
dest[i] = 0;
return dest;
}
char* strncat(char* dest, char const* src, size_t count)
{
size_t i = 0;
size_t j = 0;
while(0 != dest[i]) i = i + 1;
while(0 != src[j])
{
if(count == j)
{
dest[i] = 0;
return dest;
}
dest[i] = src[j];
i = i + 1;
j = j + 1;
}
dest[i] = 0;
return dest;
}
size_t strlen(char const* str )
{
size_t i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
size_t strnlen_s(char const* str, size_t strsz )
{
size_t i = 0;
while(0 != str[i])
{
if(strsz == i) return i;
i = i + 1;
}
return i;
}
int strcmp(char const* lhs, char const* rhs )
{
int i = 0;
while(0 != lhs[i])
{
if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
i = i + 1;
}
return lhs[i] - rhs[i];
}
int strncmp(char const* lhs, char const* rhs, size_t count)
{
size_t i = 0;
while(count > i)
{
if(0 == lhs[i]) break;
if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
i = i + 1;
}
return 0;
}
char* strchr(char const* str, int ch)
{
char* p = str;
while(ch != p[0])
{
if(0 == p[0]) return NULL;
p = p + 1;
}
if(0 == p[0]) return NULL;
return p;
}
char* strrchr(char const* str, int ch)
{
char* p = str;
int i = 0;
while(0 != p[i]) i = i + 1;
while(ch != p[i])
{
if(0 == i) return NULL;
i = i - 1;
}
return (p + i);
}
size_t strspn(char const* dest, char const* src)
{
if(0 == dest[0]) return 0;
int i = 0;
while(NULL != strchr(src, dest[i])) i = i + 1;
return i;
}
size_t strcspn(char const* dest, char const* src)
{
int i = 0;
while(NULL == strchr(src, dest[i])) i = i + 1;
return i;
}
char* strpbrk(char const* dest, char const* breakset)
{
char* p = dest;
char* s;
while(0 != p[0])
{
s = strchr(breakset, p[0]);
if(NULL != s) return strchr(p, s[0]);
p = p + 1;
}
return p;
}
void* memset(void* dest, int ch, size_t count)
{
if(NULL == dest) return dest;
size_t i = 0;
char* s = dest;
while(i < count)
{
s[i] = ch;
i = i + 1;
}
return dest;
}
void* memcpy(void* dest, void const* src, size_t count)
{
if(NULL == dest) return dest;
if(NULL == src) return NULL;
char* s1 = dest;
char const* s2 = src;
size_t i = 0;
while(i < count)
{
s1[i] = s2[i];
i = i + 1;
}
return dest;
}
void* memmove(void* dest, void const* src, size_t count)
{
if (dest < src) return memcpy (dest, src, count);
char *p = dest;
char const *q = src;
count = count - 1;
while (count >= 0)
{
p[count] = q[count];
count = count - 1;
}
return dest;
}
int memcmp(void const* lhs, void const* rhs, size_t count)
{
if(0 == count) return 0;
size_t i = 0;
count = count - 1;
char const* s1 = lhs;
char const* s2 = rhs;
while(i < count)
{
if(s1[i] != s2[i]) break;
i = i + 1;
}
return (s1[i] - s2[i]);
}
mescc-tools-1.5.2/M2libc/string.h 0000644 0000000 0000000 00000003425 14522760670 013441 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _STRING_H
#define _STRING_H
#ifdef __M2__
#include
#else
#include
/* String manipulation */
char* strcpy(char* dest, char const* src);
char* strncpy(char* dest, char const* src, size_t count);
char* strcat(char* dest, char const* src);
char* strncat(char* dest, char const* src, size_t count);
/* String examination */
size_t strlen(char const* str );
size_t strnlen_s(char const* str, size_t strsz );
int strcmp(char const* lhs, char const* rhs );
int strncmp(char const* lhs, char const* rhs, size_t count);
char* strchr(char const* str, int ch);
char* strrchr(char const* str, int ch);
size_t strspn(char const* dest, char const* src);
size_t strcspn(char const* dest, char const* src);
char* strpbrk(char const* dest, char const* breakset);
/* Memory manipulation */
void* memset(void* dest, int ch, size_t count);
void* memcpy(void* dest, void const* src, size_t count);
void* memmove(void* dest, void const* src, size_t count);
int memcmp(void const* lhs, void const* rhs, size_t count);
void* memchr(void const* ptr, int ch, size_t count);
#endif
#endif
mescc-tools-1.5.2/M2libc/sys/ 0000755 0000000 0000000 00000000000 14522760670 012574 5 ustar mescc-tools-1.5.2/M2libc/sys/stat.h 0000644 0000000 0000000 00000003271 14522760670 013723 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_H
#define _SYS_STAT_H
#ifdef __M2__
#if __uefi__
#include
#elif __i386__
#include
#elif __x86_64__
#include
#elif __arm__
#include
#elif __aarch64__
#include
#elif __riscv && __riscv_xlen==32
#include
#elif __riscv && __riscv_xlen==64
#include
#else
#error arch not supported
#endif
#else
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode);
int fchmod(int a, mode_t b);
int mkdir(char const* a, mode_t b);
int mknod(char const* a, mode_t b, dev_t c);
mode_t umask(mode_t m);
#endif
#endif
mescc-tools-1.5.2/M2libc/sys/types.h 0000644 0000000 0000000 00000001731 14522760670 014113 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#ifndef __M2__
#include "../gcc_req.h"
#endif
typedef SCM ulong;
typedef long ssize_t;
typedef int pid_t;
typedef long intptr_t;
typedef ulong uintptr_t;
typedef long clock_t;
typedef int mode_t;
typedef long dev_t;
#endif
mescc-tools-1.5.2/M2libc/uefi/ 0000755 0000000 0000000 00000000000 14522760670 012706 5 ustar mescc-tools-1.5.2/M2libc/uefi/fcntl.c 0000644 0000000 0000000 00000003453 14522760670 014165 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
#include
void free(void* l);
int __open(struct efi_file_protocol* _rootdir, char* name, long mode, long attributes)
{
struct efi_file_protocol* new_handle;
char* wide_name = _posix_path_to_uefi(name);
unsigned rval = __uefi_5(_rootdir, &new_handle, wide_name, mode, attributes, _rootdir->open);
free(wide_name);
if(rval != EFI_SUCCESS)
{
return -1;
}
return new_handle;
}
int _open(char* name, int flag, int mode)
{
long mode = 0;
long attributes = 0;
if(flag == O_WRONLY|O_CREAT|O_TRUNC)
{
mode = EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ;
}
else
{ /* Everything else is a read */
mode = EFI_FILE_MODE_READ;
attributes = EFI_FILE_READ_ONLY;
}
return __open(_rootdir, name, mode, attributes);
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/uefi/string_p.h 0000644 0000000 0000000 00000007710 14522760670 014711 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#include
char* strcpy(char* dest, char const* src)
{
int i = 0;
while (0 != src[i])
{
dest[i] = src[i];
i = i + 1;
}
dest[i] = 0;
return dest;
}
char* strncpy(char* dest, char const* src, size_t count)
{
if(0 == count) return dest;
size_t i = 0;
while(0 != src[i])
{
dest[i] = src[i];
i = i + 1;
if(count == i) return dest;
}
while(i <= count)
{
dest[i] = 0;
i = i + 1;
}
return dest;
}
char* strcat(char* dest, char const* src)
{
int i = 0;
int j = 0;
while(0 != dest[i]) i = i + 1;
while(0 != src[j])
{
dest[i] = src[j];
i = i + 1;
j = j + 1;
}
dest[i] = 0;
return dest;
}
char* strncat(char* dest, char const* src, size_t count)
{
size_t i = 0;
size_t j = 0;
while(0 != dest[i]) i = i + 1;
while(0 != src[j])
{
if(count == j)
{
dest[i] = 0;
return dest;
}
dest[i] = src[j];
i = i + 1;
j = j + 1;
}
dest[i] = 0;
return dest;
}
size_t strlen(char const* str )
{
size_t i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
size_t strnlen_s(char const* str, size_t strsz )
{
size_t i = 0;
while(0 != str[i])
{
if(strsz == i) return i;
i = i + 1;
}
return i;
}
int strcmp(char const* lhs, char const* rhs )
{
int i = 0;
while(0 != lhs[i])
{
if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
i = i + 1;
}
return lhs[i] - rhs[i];
}
int strncmp(char const* lhs, char const* rhs, size_t count)
{
size_t i = 0;
while(count > i)
{
if(0 == lhs[i]) break;
if(lhs[i] != rhs[i]) return lhs[i] - rhs[i];
i = i + 1;
}
return 0;
}
char* strchr(char const* str, int ch)
{
char* p = str;
while(ch != p[0])
{
if(0 == p[0]) return NULL;
p = p + 1;
}
if(0 == p[0]) return NULL;
return p;
}
char* strrchr(char const* str, int ch)
{
char* p = str;
int i = 0;
while(0 != p[i]) i = i + 1;
while(ch != p[i])
{
if(0 == i) return NULL;
i = i - 1;
}
return (p + i);
}
size_t strspn(char const* dest, char const* src)
{
if(0 == dest[0]) return 0;
int i = 0;
while(NULL != strchr(src, dest[i])) i = i + 1;
return i;
}
size_t strcspn(char const* dest, char const* src)
{
int i = 0;
while(NULL == strchr(src, dest[i])) i = i + 1;
return i;
}
char* strpbrk(char const* dest, char const* breakset)
{
char* p = dest;
char* s;
while(0 != p[0])
{
s = strchr(breakset, p[0]);
if(NULL != s) return strchr(p, s[0]);
p = p + 1;
}
return p;
}
void* memset(void* dest, int ch, size_t count)
{
if(NULL == dest) return dest;
size_t i = 0;
char* s = dest;
while(i < count)
{
s[i] = ch;
i = i + 1;
}
return dest;
}
void* memcpy(void* dest, void const* src, size_t count)
{
if(NULL == dest) return dest;
if(NULL == src) return NULL;
char* s1 = dest;
char const* s2 = src;
size_t i = 0;
while(i < count)
{
s1[i] = s2[i];
i = i + 1;
}
return dest;
}
void* memmove(void* dest, void const* src, size_t count)
{
if (dest < src) return memcpy (dest, src, count);
char *p = dest;
char const *q = src;
count = count - 1;
while (count >= 0)
{
p[count] = q[count];
count = count - 1;
}
return dest;
}
int memcmp(void const* lhs, void const* rhs, size_t count)
{
if(0 == count) return 0;
size_t i = 0;
count = count - 1;
char const* s1 = lhs;
char const* s2 = rhs;
while(i < count)
{
if(s1[i] != s2[i]) break;
i = i + 1;
}
return (s1[i] - s2[i]);
}
mescc-tools-1.5.2/M2libc/uefi/sys/ 0000755 0000000 0000000 00000000000 14522760670 013524 5 ustar mescc-tools-1.5.2/M2libc/uefi/sys/stat.c 0000644 0000000 0000000 00000003341 14522760670 014644 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
return 0;
}
int fchmod(int a, mode_t b)
{
return 0;
}
int __open(struct efi_file_protocol* _rootdir, char* name, long mode, long attributes);
int mkdir(char const* name, mode_t _mode)
{
struct efi_file_protocol* new_directory;
long mode = EFI_FILE_MODE_CREATE | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ;
long attributes = EFI_FILE_DIRECTORY;
long new_directory = __open(_rootdir, name, mode, attributes);
if(new_directory != -1)
{
_close(new_directory);
return 0;
}
return -1;
}
int mknod(char const* a, mode_t b, dev_t c)
{
return -1;
}
mode_t umask(mode_t m)
{
return 0;
}
#endif
mescc-tools-1.5.2/M2libc/uefi/uefi.c 0000644 0000000 0000000 00000045040 14522760670 014005 0 ustar /* Copyright (C) 2022 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#define __uefi__ 1
#ifndef _UEFI_C
#define _UEFI_C
#include
#include
#define PAGE_SIZE 4096
#define USER_STACK_SIZE 8388608
#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 1
#define EFI_FILE_MODE_READ 1
#define EFI_FILE_MODE_WRITE 2
#define EFI_FILE_MODE_CREATE (1 << 63)
#define EFI_FILE_READ_ONLY 1
#define EFI_FILE_DIRECTORY 0x10
#define EFI_LOADER_DATA 2
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 2
#define EFI_SUCCESS 0
#define EFI_LOAD_ERROR (1 << 63) | 1
#define EFI_INVALID_PARAMETER (1 << 63) | 2
#define EFI_UNSUPPORTED (1 << 63) | 3
#define EFI_BUFFER_TOO_SMALL (1 << 63) | 5
#define EFI_NOT_FOUND (1 << 31) | 14
#define __PATH_MAX 4096
#define __ENV_NAME_MAX 4096
#define HARDWARE_DEVICE_PATH 1
#define MEMORY_MAPPED 3
#define END_HARDWARE_DEVICE_PATH 0x7F
#define END_ENTIRE_DEVICE_PATH 0xFF
void* _image_handle;
void* _root_device;
void* __user_stack;
int _argc;
char** _argv;
char** _envp;
char* _cwd;
struct efi_simple_text_output_protocol
{
void* reset;
void* output_string;
void* test_string;
void* query_mode;
void* set_mode;
void* set_attribute;
void* clear_screen;
void* set_cursor;
void* enable_cursor;
void* mode;
};
struct efi_table_header
{
unsigned signature;
unsigned revision_and_header_size;
unsigned crc32_and_reserved;
};
struct efi_boot_table
{
struct efi_table_header header;
/* Task Priority Services */
void* raise_tpl;
void* restore_tpl;
/* Memory Services */
void* allocate_pages;
void* free_pages;
void* get_memory_map;
void* allocate_pool;
void* free_pool;
/* Event & Timer Services */
void* create_event;
void* set_timer;
void* wait_for_event;
void* signal_event;
void* close_event;
void* check_event;
/* Protocol Handler Services */
void* install_protocol_interface;
void* reinstall_protocol_interface;
void* uninstall_protocol_interface;
void* handle_protocol;
void* reserved;
void* register_protocol_notify;
void* locate_handle;
void* locate_device_path;
void* install_configuration_table;
/* Image Services */
void* load_image;
void* start_image;
void* exit;
void* unload_image;
void* exit_boot_services;
/* Miscellaneous Services */
void* get_next_monotonic_count;
void* stall;
void* set_watchdog_timer;
/* DriverSupport Services */
void* connect_controller;
void* disconnect_controller;
/* Open and Close Protocol Services */
void* open_protocol;
void* close_protocol;
void* open_protocol_information;
/* Library Services */
void* protocols_per_handle;
void* locate_handle_buffer;
void* locate_protocol;
void* install_multiple_protocol_interfaces;
void* uninstall_multiple_protocol_interfaces;
/* 32-bit CRC Services */
void* copy_mem;
void* set_mem;
void* create_event_ex;
};
struct efi_runtime_table
{
struct efi_table_header header;
/* Time Services */
void* get_time;
void* set_time;
void* get_wakeup_time;
void* set_wakeup_time;
/* Virtual Memory Services */
void* set_virtual_address_map;
void* convert_pointer;
/* Variable Services */
void* get_variable;
void* get_next_variable_name;
void* set_variable;
/* Miscellaneous Services */
void* get_next_high_monotonic_count;
void* reset_system;
/* UEFI 2.0 Capsule Services */
void* update_capsule;
void* query_capsule_capabilities;
/* Miscellaneous UEFI 2.0 Services */
void* query_variable_info;
};
struct efi_system_table
{
struct efi_table_header header;
char* firmware_vendor;
unsigned firmware_revision;
void* console_in_handle;
void* con_in;
void* console_out_handle;
struct efi_simple_text_output_protocol* con_out;
void *standard_error_handle;
struct efi_simple_text_output_protocol* std_err;
struct efi_runtime_table* runtime_services;
struct efi_boot_table* boot_services;
unsigned number_table_entries;
void *configuration_table;
};
struct efi_system_table* _system;
struct efi_guid
{
uint32_t data1;
uint16_t data2;
uint16_t data3;
uint8_t data4[8];
};
struct efi_guid EFI_LOADED_IMAGE_PROTOCOL_GUID;
struct efi_guid EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
struct efi_guid EFI_FILE_INFO_GUID;
struct efi_guid EFI_SHELL_VARIABLE_GUID;
struct efi_loaded_image_protocol
{
unsigned revision;
void* parent;
void* system;
void* device;
void* filepath;
void* reserved;
/* Image's load options */
unsigned load_options_size;
void* load_options;
/* Location of the image in memory */
void* image_base;
unsigned image_size;
unsigned image_code_type;
unsigned image_data_type;
void* unload;
};
struct efi_loaded_image_protocol* _image;
struct efi_simple_file_system_protocol
{
unsigned revision;
void* open_volume;
};
struct efi_file_protocol
{
unsigned revision;
void* open;
void* close;
void* delete;
void* read;
void* write;
void* get_position;
void* set_position;
void* get_info;
void* set_info;
void* flush;
void* open_ex;
void* read_ex;
void* write_ex;
void* flush_ex;
};
struct efi_file_protocol* _rootdir;
struct efi_time
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
uint8_t pad1;
uint32_t nanosecond;
uint16_t time_zone;
uint8_t daylight;
uint8_t pad2;
};
struct efi_file_info
{
unsigned size;
unsigned file_size;
unsigned physical_size;
struct efi_time create_time;
struct efi_time last_access_time;
struct efi_time modifiction_time;
unsigned attribute;
char file_name[__PATH_MAX];
};
struct efi_device_path_protocol
{
uint8_t type;
uint8_t subtype;
uint16_t length;
uint32_t memory_type;
unsigned start_address;
unsigned end_address;
};
unsigned __uefi_1(void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rax,[rbp+DWORD] %-16"
"mov_rax,[rax]"
"sub_rsp, %8"
"call_rax"
"add_rsp, %8");
#else
#error unsupported arch
#endif
}
unsigned __uefi_2(void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_rax,[rbp+DWORD] %-24"
"mov_rax,[rax]"
"sub_rsp, %16"
"call_rax"
"add_rsp, %16");
#else
#error unsupported arch
#endif
}
unsigned __uefi_3(void*, void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_rax,[rbp+DWORD] %-32"
"mov_rax,[rax]"
"sub_rsp, %24"
"call_rax"
"add_rsp, %24");
#else
#error unsupported arch
#endif
}
unsigned __uefi_4(void*, void*, void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-32"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %32");
#else
#error unsupported arch
#endif
}
unsigned __uefi_5(void*, void*, void*, void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-32"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-48"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %40");
#else
#error unsupported arch
#endif
}
unsigned __uefi_6(void*, void*, void*, void*, void*, void*, FUNCTION f)
{
#ifdef __x86_64__
asm("lea_rcx,[rbp+DWORD] %-8"
"mov_rcx,[rcx]"
"lea_rdx,[rbp+DWORD] %-16"
"mov_rdx,[rdx]"
"lea_r8,[rbp+DWORD] %-24"
"mov_r8,[r8]"
"lea_r9,[rbp+DWORD] %-32"
"mov_r9,[r9]"
"lea_rax,[rbp+DWORD] %-48"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-40"
"mov_rax,[rax]"
"push_rax"
"lea_rax,[rbp+DWORD] %-56"
"mov_rax,[rax]"
"sub_rsp, %32"
"call_rax"
"add_rsp, %48");
#else
#error unsupported arch
#endif
}
unsigned _allocate_pool(unsigned memory_type, unsigned size, void* pool)
{
return __uefi_3(memory_type, size, pool, _system->boot_services->allocate_pool);
}
void _free_pool(void* memory)
{
return __uefi_1(memory, _system->boot_services->free_pool);
}
unsigned _open_protocol(void* handle, struct efi_guid* protocol, void* agent_handle, void** interface, void* controller_handle, long attributes, FUNCTION open_protocol)
{
return __uefi_6(handle, protocol, agent_handle, interface, controller_handle, attributes, _system->boot_services->open_protocol);
}
unsigned _close_protocol(void* handle, struct efi_guid* protocol, void* agent_handle, void* controller_handle)
{
return __uefi_4(handle, protocol, agent_handle, controller_handle, _system->boot_services->close_protocol);
}
unsigned _open_volume(struct efi_simple_file_system_protocol* rootfs, struct efi_file_protocol** rootdir)
{
return __uefi_2(rootfs, rootdir, rootfs->open_volume);
}
unsigned _close(struct efi_file_protocol* file)
{
return __uefi_1(file, file->close);
}
unsigned _get_next_variable_name(unsigned* size, char* name, struct efi_guid* vendor_guid)
{
return __uefi_3(size, name, vendor_guid, _system->runtime_services->get_next_variable_name);
}
unsigned _get_variable(char* name, struct efi_guid* vendor_guid, uint32_t* attributes, unsigned* data_size, void* data)
{
return __uefi_5(name, vendor_guid, attributes, data_size, data, _system->runtime_services->get_variable);
}
char* _string2wide(char* narrow_string);
size_t strlen(char const* str);
void free(void* ptr);
unsigned _set_variable(char* name, void* data)
{
char* wide_name = _string2wide(name);
char* wide_data = _string2wide(data);
unsigned data_size = strlen(data) * 2;
uint32_t attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
unsigned rval = __uefi_5(wide_name, &EFI_SHELL_VARIABLE_GUID, attributes, data_size, wide_data, _system->runtime_services->set_variable);
free(wide_name);
free(wide_data);
return rval;
}
void exit(unsigned value)
{
goto FUNCTION__exit;
}
char* strcat(char* dest, char const* src);
char* strcpy(char* dest, char const* src);
size_t strlen(char const* str);
void* calloc(int count, int size);
char* _relative_path_to_absolute(char* narrow_string)
{
char* absolute_path = calloc(__PATH_MAX, 1);
if(narrow_string[0] != '/' && narrow_string[0] != '\\')
{
strcpy(absolute_path, _cwd);
}
strcat(absolute_path, narrow_string);
return absolute_path;
}
char* _posix_path_to_uefi(char* narrow_string)
{
char* absolute_path = _relative_path_to_absolute(narrow_string);
unsigned length = strlen(absolute_path);
unsigned i;
for(i = 0; i < length; i += 1)
{
if(absolute_path[i] == '/')
{
absolute_path[i] = '\\';
}
else
{
absolute_path[i] = absolute_path[i];
}
}
char* wide_string = _string2wide(absolute_path);
free(absolute_path);
return wide_string;
}
char* _string2wide(char* narrow_string)
{
unsigned length = strlen(narrow_string);
char* wide_string = calloc(length + 1, 2);
unsigned i;
for(i = 0; i < length; i += 1)
{
wide_string[2 * i] = narrow_string[i];
}
return wide_string;
}
int isspace(char _c);
void _process_load_options(char* load_options)
{
/* Determine argc */
_argc = 1; /* command name */
char *i = load_options;
unsigned was_space = 0;
do
{
if(isspace(i[0]))
{
if(!was_space)
{
_argc += 1;
was_space = 1;
}
}
else
{
was_space = 0;
}
i += 1;
} while(i[0] != 0);
/* Collect argv */
_argv = calloc(_argc + 1, sizeof(char*));
i = load_options;
unsigned j;
for(j = 0; j < _argc; j += 1)
{
_argv[j] = i;
do
{
i += 1;
} while(!isspace(i[0]) && i[0] != 0);
i[0] = 0;
do
{
i += 1;
} while(isspace(i[0]));
}
}
/* Function to find the length of a char**; an array of strings */
unsigned _array_length(char** array)
{
unsigned length = 0;
while(array[length] != NULL)
{
length += 1;
}
return length;
}
size_t wcstombs(char* dest, char* src, size_t n);
char* _get_environmental_variable(struct efi_guid* vendor_guid, char* name, unsigned size)
{
unsigned data_size;
char* data;
char* variable_data;
char* envp_line = NULL;
/* Call with data=NULL to obtain data size that we need to allocate */
_get_variable(name, vendor_guid, NULL, &data_size, NULL);
data = calloc(data_size + 1, 1);
_get_variable(name, vendor_guid, NULL, &data_size, data);
variable_data = calloc((data_size / 2) + 1, 1);
wcstombs(variable_data, data, (data_size / 2) + 1);
envp_line = calloc((size / 2) + (data_size / 2) + 1, 1);
wcstombs(envp_line, name, size / 2);
strcat(envp_line, "=");
strcat(envp_line, variable_data);
free(data);
free(variable_data);
return envp_line;
}
int memcmp(void const* lhs, void const* rhs, size_t count);
char** _get_environmental_variables(char** envp)
{
EFI_SHELL_VARIABLE_GUID.data1 = 0x158def5a;
EFI_SHELL_VARIABLE_GUID.data2 = 0xf656;
EFI_SHELL_VARIABLE_GUID.data3 = 0x419c;
EFI_SHELL_VARIABLE_GUID.data4[0] = 0xb0;
EFI_SHELL_VARIABLE_GUID.data4[1] = 0x27;
EFI_SHELL_VARIABLE_GUID.data4[2] = 0x7a;
EFI_SHELL_VARIABLE_GUID.data4[3] = 0x31;
EFI_SHELL_VARIABLE_GUID.data4[4] = 0x92;
EFI_SHELL_VARIABLE_GUID.data4[5] = 0xc0;
EFI_SHELL_VARIABLE_GUID.data4[6] = 0x79;
EFI_SHELL_VARIABLE_GUID.data4[7] = 0xd2;
unsigned size = __ENV_NAME_MAX;
unsigned rval;
unsigned envc = 0;
char* name = calloc(size, 1);
struct efi_guid vendor_guid;
/* First count the number of environmental variables */
do
{
size = __ENV_NAME_MAX;
rval = _get_next_variable_name(&size, name, &vendor_guid);
if(rval == EFI_SUCCESS)
{
if(memcmp(&vendor_guid, &EFI_SHELL_VARIABLE_GUID, sizeof(struct efi_guid)) == 0)
{
envc += 1;
}
}
} while(rval == EFI_SUCCESS);
/* Now redo the search but this time populate envp array */
envp = calloc(sizeof(char*), envc + 1);
name[0] = 0;
name[1] = 0;
unsigned j = 0;
do
{
size = __ENV_NAME_MAX;
rval = _get_next_variable_name(&size, name, &vendor_guid);
if(rval == EFI_SUCCESS)
{
if(memcmp(&vendor_guid, &EFI_SHELL_VARIABLE_GUID, sizeof(struct efi_guid)) == 0)
{
envp[j] = _get_environmental_variable(&vendor_guid, name, size);
j += 1;
}
}
} while(rval == EFI_SUCCESS);
envp[j] = 0;
free(name);
return envp;
}
void _wipe_environment()
{
char** envp = _get_environmental_variables(envp);
unsigned i = 0;
unsigned j;
char* name;
while(envp[i] != 0)
{
j = 0;
name = envp[i];
while(envp[i][j] != '=')
{
j += 1;
}
envp[i][j] = 0;
_set_variable(name, "");
i += 1;
}
free(envp);
}
int strcmp(char const* lhs, char const* rhs);
char* strchr(char const* str, int ch);
void _setup_current_working_directory(char** envp)
{
_cwd = calloc(__PATH_MAX, 1);
unsigned i = 0;
unsigned j;
unsigned k;
char* value;
char* match;
while(envp[i] != 0)
{
j = 0;
while(envp[i][j] != '=')
{
j += 1;
}
envp[i][j] = 0;
if(strcmp(envp[i], "cwd") == 0)
{
value = envp[i] + j + 1;
match = strchr(value, ':'); /* strip uefi device, e.g. fs0: */
if(match != NULL)
{
value = match + 1;
}
strcpy(_cwd, value);
k = 0;
while(_cwd[k] != '\0')
{
if(_cwd[k] == '\\')
{
_cwd[k] = '/';
}
k += 1;
}
}
envp[i][j] = '=';
i += 1;
}
if(strcmp(_cwd, "") == 0)
{
strcpy(_cwd, "/");
}
}
void* malloc(unsigned size);
void __init_io();
void _init()
{
/* Allocate user stack, UEFI stack is not big enough for compilers */
__user_stack = malloc(USER_STACK_SIZE) + USER_STACK_SIZE;
/* Process command line arguments */
EFI_LOADED_IMAGE_PROTOCOL_GUID.data1 = 0x5b1b31a1;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data2 = 0x9562;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data3 = 0x11d2;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[0] = 0x8e;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[1] = 0x3f;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[2] = 0;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[3] = 0xa0;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[4] = 0xc9;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[5] = 0x69;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[6] = 0x72;
EFI_LOADED_IMAGE_PROTOCOL_GUID.data4[7] = 0x3b;
__init_io();
_open_protocol(_image_handle, &EFI_LOADED_IMAGE_PROTOCOL_GUID, &_image, _image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
char* load_options = calloc(_image->load_options_size, 1);
wcstombs(load_options, _image->load_options, _image->load_options_size);
_process_load_options(load_options);
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data1 = 0x964E5B22;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data2 = 0x6459;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data3 = 0x11d2;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[0] = 0x8e;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[1] = 0x39;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[2] = 0;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[3] = 0xa0;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[4] = 0xc9;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[5] = 0x69;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[6] = 0x72;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID.data4[7] = 0x3b;
_root_device = _image->device;
struct efi_simple_file_system_protocol* rootfs;
_open_protocol(_root_device, &EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, &rootfs, _image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
_open_volume(rootfs, &_rootdir);
EFI_FILE_INFO_GUID.data1 = 0x09576e92;
EFI_FILE_INFO_GUID.data2 = 0x6d3f;
EFI_FILE_INFO_GUID.data3 = 0x11d2;
EFI_FILE_INFO_GUID.data4[0] = 0x8e;
EFI_FILE_INFO_GUID.data4[1] = 0x39;
EFI_FILE_INFO_GUID.data4[2] = 0;
EFI_FILE_INFO_GUID.data4[3] = 0xa0;
EFI_FILE_INFO_GUID.data4[4] = 0xc9;
EFI_FILE_INFO_GUID.data4[5] = 0x69;
EFI_FILE_INFO_GUID.data4[6] = 0x72;
EFI_FILE_INFO_GUID.data4[7] = 0x3b;
_envp = _get_environmental_variables(_envp);
_setup_current_working_directory(_envp);
}
void __kill_io();
void* _malloc_release_all(FUNCTION _free);
void _cleanup()
{
__kill_io();
_close(_rootdir);
_close_protocol(_root_device, &EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, _image_handle, 0);
_close_protocol(_image_handle, &EFI_LOADED_IMAGE_PROTOCOL_GUID, _image_handle, 0);
_malloc_release_all(_free_pool);
}
void* _malloc_uefi(unsigned size)
{
void* memory_block;
if(_allocate_pool(EFI_LOADER_DATA, size, &memory_block) != EFI_SUCCESS)
{
return 0;
}
return memory_block;
}
#endif
mescc-tools-1.5.2/M2libc/uefi/unistd.c 0000644 0000000 0000000 00000016366 14522760670 014374 0 ustar /* Copyright (C) 2022 Andrius Štikonas
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#include
#include
#define NULL 0
#define EOF 0xFFFFFFFF
/* For lseek */
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
void* malloc(unsigned size);
size_t strlen(char const* str);
char* strncpy(char* dest, char const* src, size_t count);
char* strncat(char* dest, char const* src, size_t count);
void* memcpy(void* dest, void const* src, size_t count);
int access(char* pathname, int mode)
{
return 0;
}
int chdir(char* path)
{
char* absolute_path = _relative_path_to_absolute(path);
strncpy(_cwd, absolute_path, __PATH_MAX);
if(_cwd[strlen(_cwd) - 1] != '\\')
{
strncat(_cwd, "/", __PATH_MAX);
}
free(absolute_path);
return 0;
}
int fchdir(int fd)
{
/* TODO: not yet implemented. */
return -1;
}
int _get_file_size(struct efi_file_protocol* f)
{
/* Preallocate some extra space for file_name */
size_t file_info_size = sizeof(struct efi_file_info);
struct efi_file_info* file_info = calloc(1, file_info_size);
unsigned rval = __uefi_4(f, &EFI_FILE_INFO_GUID, &file_info_size, file_info, f->get_info);
if(rval != EFI_SUCCESS)
{
return -1;
}
int file_size = file_info->file_size;
free(file_info);
return file_size;
}
void _set_environment(char** envp)
{
unsigned i;
unsigned j;
unsigned length = _array_length(envp);
char* name;
char* value;
for(i = 0; i < length; i += 1)
{
j = 0;
name = envp[i];
while(envp[i][j] != '=')
{
j += 1;
}
envp[i][j] = 0;
value = envp[i] + j + 1;
_set_variable(name, value);
envp[i][j] = '=';
}
}
FILE* fopen(char const* filename, char const* mode);
size_t fread(void* buffer, size_t size, size_t count, FILE* stream);
int fclose(FILE* stream);
int spawn(char* file_name, char** argv, char** envp)
{
FILE* fcmd = fopen(file_name, "r");
if(fcmd == NULL) return -1;
long program_size = _get_file_size(fcmd->fd);
void* executable = malloc(program_size);
size_t count = fread(executable, 1, program_size, fcmd);
if(count < program_size)
{
free(executable);
fclose(fcmd);
return -1;
}
fclose(fcmd);
struct efi_device_path_protocol* device_path = calloc(2, sizeof(struct efi_device_path_protocol));
device_path->type = HARDWARE_DEVICE_PATH;
device_path->subtype = MEMORY_MAPPED;
device_path->length = sizeof(struct efi_device_path_protocol);
device_path->memory_type = EFI_LOADER_DATA;
device_path->start_address = executable;
device_path->end_address = executable + program_size;
device_path[1].type = END_HARDWARE_DEVICE_PATH;
device_path[1].subtype = END_ENTIRE_DEVICE_PATH;
device_path[1].length = 4;
void* child_ih;
unsigned rval = __uefi_6(0, _image_handle, device_path, executable, program_size, &child_ih, _system->boot_services->load_image);
free(device_path);
free(executable);
if(rval != EFI_SUCCESS) return -1;
struct efi_loaded_image_protocol* child_image;
rval = _open_protocol(child_ih, &EFI_LOADED_IMAGE_PROTOCOL_GUID, &child_image, child_ih, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
if(rval != EFI_SUCCESS) return -1;
/* Concatenate char** argv array */
unsigned arg_length = -1 ;
unsigned i = 0;
while(argv[i] != NULL)
{
arg_length += strlen(argv[i]) + 1;
i += 1;
}
char* load_options = calloc(arg_length + 1, 1);
strcpy(load_options, argv[0]);
i = 1;
while(argv[i] != NULL)
{
strcat(load_options, " ");
strcat(load_options, argv[i]);
i += 1;
}
char* uefi_path = _string2wide(load_options);
child_image->load_options = uefi_path;
child_image->load_options_size = 2 * arg_length;
free(load_options);
child_image->device = _image->device;
rval = _close_protocol(child_ih, &EFI_LOADED_IMAGE_PROTOCOL_GUID, child_ih, 0);
if(rval != EFI_SUCCESS) return -1;
/* Setup environment for child process */
_set_environment(envp);
_set_variable("cwd", _cwd);
/* Run command */
rval = __uefi_3(child_ih, 0, 0, _system->boot_services->start_image);
free(uefi_path);
/* Restore initial environment
* For simplicity we just delete all variables and restore them from _envp.
* This assumes that _envp is not modified by application, e.g. kaem.
*/
_wipe_environment();
_set_environment(_envp);
return rval;
}
int fork()
{
return -1;
}
int waitpid (int pid, int* status_ptr, int options)
{
return -1;
}
int execve(char* file_name, char** argv, char** envp)
{
return -1;
}
int read(int fd, char* buf, unsigned count)
{
struct efi_file_protocol* f = fd;
__uefi_3(fd, &count, buf, f->read);
return count;
}
int write(int fd, char* buf, unsigned count)
{
struct efi_file_protocol* f = fd;
unsigned i;
char c = 0;
/* In UEFI StdErr might not be printing stuff to console, so just use stdout */
if(f == STDOUT_FILENO || f == STDERR_FILENO)
{
for(i = 0; i < count; i += 1)
{
c = buf[i];
__uefi_2(_system->con_out, &c, _system->con_out->output_string);
if('\n' == c)
{
c = '\r';
__uefi_2(_system->con_out, &c, _system->con_out->output_string);
}
}
return i;
}
/* Otherwise write to file */
__uefi_3(f, &count, buf, f->write);
return count;
}
int lseek(int fd, int offset, int whence)
{
struct efi_file_protocol* f = fd;
if(whence == SEEK_SET)
{
}
else if(whence == SEEK_CUR)
{
unsigned position;
__uefi_2(f, &position, f->get_position);
offset += position;
}
else if(whence == SEEK_END)
{
offset += _get_file_size(fd);
}
else
{
return -1;
}
unsigned rval = __uefi_2(f, offset, f->set_position);
if(rval == EFI_SUCCESS)
{
return offset;
}
return -1;
}
int close(int fd)
{
struct efi_file_protocol* f = fd;
unsigned rval = __uefi_1(f, f->close);
if(rval != EFI_SUCCESS)
{
return -1;
}
return rval;
}
int unlink(char* filename)
{
FILE* f = fopen(filename, "r");
struct efi_file_protocol* fd = f->fd;
__uefi_1(fd, fd->delete);
}
char* getcwd(char* buf, unsigned size)
{
size_t length = strlen(_cwd);
if(length >= size) return NULL;
strcpy(buf, _cwd);
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
return -1;
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
memcpy(unameData->sysname, "UEFI", 5);
memcpy(unameData->release, "1.0", 4);
memcpy(unameData->version, "1.0", 4);
#ifdef __x86_64__
memcpy(unameData->machine, "x86_64", 7);
#else
#error unsupported arch
#endif
}
#endif
mescc-tools-1.5.2/M2libc/unistd.h 0000644 0000000 0000000 00000004224 14522760670 013437 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_H
#define _UNISTD_H
#ifdef __M2__
#if __uefi__
#include
#elif __i386__
#include
#elif __x86_64__
#include
#elif __arm__
#include
#elif __aarch64__
#include
#elif __riscv && __riscv_xlen==32
#include
#elif __riscv && __riscv_xlen==64
#include
#else
#error arch not supported
#endif
#else
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode);
int chdir(char* path);
int fchdir(int fd);
void _exit(int value);
int fork();
int waitpid (int pid, int* status_ptr, int options);
int execve(char* file_name, char** argv, char** envp);
int read(int fd, char* buf, unsigned count);
int write(int fd, char* buf, unsigned count);
int lseek(int fd, int offset, int whence);
int close(int fd);
int unlink (char *filename);
int _getcwd(char* buf, int size);
char* getcwd(char* buf, unsigned size);
char* getwd(char* buf);
char* get_current_dir_name();
int brk(void *addr);
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData);
#endif
#endif
mescc-tools-1.5.2/M2libc/x86/ 0000755 0000000 0000000 00000000000 14522760670 012403 5 ustar mescc-tools-1.5.2/M2libc/x86/ELF-x86-debug.hex2 0000644 0000000 0000000 00000005642 14522760670 015317 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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 386
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_alignment
:ELF_text
mescc-tools-1.5.2/M2libc/x86/ELF-x86.hex2 0000644 0000000 0000000 00000005642 14522760670 014233 0 ustar ### Copyright (C) 2016 Jeremiah Orians
### Copyright (C) 2017 Jan Nieuwenhuizen
### This file is part of M2-Planet.
###
### M2-Planet 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.
###
### M2-Planet 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 M2-Planet. If not, see .
### stage0's hex2 format
### ! 1 byte relative
### $ 2 byte address
### @ 2 byte relative
### & 4 byte address
### % 4 byte relative
### 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 386
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
: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_alignment
:ELF_text
mescc-tools-1.5.2/M2libc/x86/libc-core.M1 0000644 0000000 0000000 00000003171 14522760670 014443 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_ebp,esp ; Protect esp
;; Prepare argv
lea_eax,[ebp+DWORD] %4 ; ARGV_address = EBP + 4
push_eax ; Put argv on the stack
;; Prepare envp
mov_eax,ebp ; Address we need to load from
mov_eax,[eax] ; Get ARGC
add_eax, %2 ; OFFSET = ARGC + 2
sal_eax, !2 ; OFFSET = OFFSET * WORDSIZE
add_eax,ebp ; ENVP_address = ESP + OFFSET
push_eax ; Put envp on the stack
;; Stack offset
add_ebp, %4 ; Fix ebp
;; Perform the main loop
call %FUNCTION_main
push_eax ; Put return on stack
push_eax ; so that _exit gets the value
;; Exit to kernel
:FUNCTION_exit
:FUNCTION__exit
mov_ebx,eax ; Using the return code given by main
mov_eax, %1 ; Syscall exit
int !0x80 ; Exit with that code
mescc-tools-1.5.2/M2libc/x86/libc-full.M1 0000644 0000000 0000000 00000003351 14522760670 014455 0 ustar ## Copyright (C) 2016 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
:_start
mov_ebp,esp ; Protect esp
;; Prepare argv
lea_eax,[ebp+DWORD] %4 ; ARGV_address = EBP + 4
push_eax ; Put argv on the stack
;; Prepare envp
mov_eax,ebp ; Address we need to load from
mov_eax,[eax] ; Get ARGC
add_eax, %2 ; OFFSET = ARGC + 2
sal_eax, !2 ; OFFSET = OFFSET * WORDSIZE
add_eax,ebp ; ENVP_address = ESP + OFFSET
push_eax ; Put envp on the stack
mov_ebx, &GLOBAL__envp ; Get _envp global
mov_[ebx],eax ; Save environment to _envp
;; Stack offset
add_ebp, %4 ; Fix ebp
;; Setup for malloc
call %FUNCTION___init_malloc
;; Setup for FILE*
call %FUNCTION___init_io
;; Perform the main loop
call %FUNCTION_main
push_eax ; Put return on stack
push_eax ; so that _exit gets the value
:FUNCTION_exit
call %FUNCTION___kill_io
:FUNCTION__exit
pop_ebx
pop_ebx
mov_eax, %1
int !0x80
:GLOBAL__envp
NULL
mescc-tools-1.5.2/M2libc/x86/linux/ 0000755 0000000 0000000 00000000000 14522760670 013542 5 ustar mescc-tools-1.5.2/M2libc/x86/linux/bootstrap.c 0000644 0000000 0000000 00000006135 14522760670 015730 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
// CONSTANT stdin 0
// CONSTANT stdout 1
// CONSTANT stderr 2
// CONSTANT EOF 0xFFFFFFFF
// CONSTANT NULL 0
// CONSTANT EXIT_FAILURE 1
// CONSTANT EXIT_SUCCESS 0
// CONSTANT TRUE 1
// CONSTANT FALSE 0
int fgetc(FILE* f)
{
asm("mov_eax, %3"
"lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"push_ebx"
"mov_ecx,esp"
"mov_edx, %1"
"int !0x80"
"test_eax,eax"
"pop_eax"
"jne %FUNCTION_fgetc_Done"
"mov_eax, %-1"
":FUNCTION_fgetc_Done");
}
void fputc(char s, FILE* f)
{
asm("mov_eax, %4"
"lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_edx, %1"
"int !0x80");
}
void fputs(char* s, FILE* f)
{
while(0 != s[0])
{
fputc(s[0], f);
s = s + 1;
}
}
FILE* open(char* name, int flag, int mode)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %5"
"int !0x80");
}
FILE* fopen(char* filename, char* mode)
{
FILE* f;
if('w' == mode[0])
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
f = open(filename, 577 , 384);
}
else
{ /* Everything else is a read */
f = open(filename, 0, 0);
}
/* Negative numbers are error codes */
if(0 > f)
{
return 0;
}
return f;
}
int close(int fd)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %6"
"int !0x80");
}
int fclose(FILE* stream)
{
int error = close(stream);
return error;
}
int brk(void *addr)
{
asm("mov_eax,[esp+DWORD] %4"
"push_eax"
"mov_eax, %45"
"pop_ebx"
"int !0x80");
}
long _malloc_ptr;
long _brk_ptr;
void* malloc(int size)
{
if(NULL == _brk_ptr)
{
_brk_ptr = brk(0);
_malloc_ptr = _brk_ptr;
}
if(_brk_ptr < _malloc_ptr + size)
{
_brk_ptr = brk(_malloc_ptr + size);
if(-1 == _brk_ptr) return 0;
}
long old_malloc = _malloc_ptr;
_malloc_ptr = _malloc_ptr + size;
return old_malloc;
}
int strlen(char* str )
{
int i = 0;
while(0 != str[i]) i = i + 1;
return i;
}
void* memset(void* ptr, int value, int num)
{
char* s;
for(s = ptr; 0 < num; num = num - 1)
{
s[0] = value;
s = s + 1;
}
}
void* calloc(int count, int size)
{
void* ret = malloc(count * size);
if(NULL == ret) return NULL;
memset(ret, 0, (count * size));
return ret;
}
void free(void* l)
{
return;
}
void exit(int value)
{
asm("pop_ebx"
"pop_ebx"
"mov_eax, %1"
"int !0x80");
}
mescc-tools-1.5.2/M2libc/x86/linux/fcntl.c 0000644 0000000 0000000 00000002435 14522760670 015020 0 ustar /* Copyright (C) 2016 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef __FCNTL_C
#define __FCNTL_C
#define O_RDONLY 0
#define O_WRONLY 1
#define O_RDWR 2
#define O_CREAT 00100
#define O_EXCL 00200
#define O_TRUNC 001000
#define O_APPEND 002000
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_IRWXU 00700
int _open(char* name, int flag, int mode)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %5"
"int !0x80");
}
#define STDIN_FILENO 0
#define STDOUT_FILENO 1
#define STDERR_FILENO 2
#endif
mescc-tools-1.5.2/M2libc/x86/linux/sys/ 0000755 0000000 0000000 00000000000 14522760670 014360 5 ustar mescc-tools-1.5.2/M2libc/x86/linux/sys/stat.c 0000644 0000000 0000000 00000003722 14522760670 015503 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _SYS_STAT_C
#define _SYS_STAT_C
#include
#define S_IRWXU 00700
#define S_IXUSR 00100
#define S_IWUSR 00200
#define S_IRUSR 00400
#define S_ISUID 04000
#define S_ISGID 02000
#define S_IXGRP 00010
#define S_IXOTH 00001
#define S_IRGRP 00040
#define S_IROTH 00004
#define S_IWGRP 00020
#define S_IWOTH 00002
#define S_IRWXG 00070
#define S_IRWXO 00007
int chmod(char *pathname, int mode)
{
asm("lea_ebx,[esp+DWORD] %8"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %4"
"mov_ecx,[ecx]"
"mov_eax, %15"
"int !0x80");
}
int fchmod(int a, mode_t b)
{
asm("lea_ebx,[esp+DWORD] %8"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %4"
"mov_ecx,[ecx]"
"mov_eax, %94"
"int !0x80");
}
int mkdir(char const* a, mode_t b)
{
asm("lea_ebx,[esp+DWORD] %8"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %4"
"mov_ecx,[ecx]"
"mov_eax, %39"
"int !0x80");
}
int mknod(char const* a, mode_t b, dev_t c)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %14"
"int !0x80");
}
mode_t umask(mode_t m)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %60"
"int !0x80");
}
#endif
mescc-tools-1.5.2/M2libc/x86/linux/unistd.c 0000644 0000000 0000000 00000007431 14522760670 015221 0 ustar /* Copyright (C) 2020 Jeremiah Orians
* This file is part of M2-Planet.
*
* M2-Planet 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.
*
* M2-Planet 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 M2-Planet. If not, see .
*/
#ifndef _UNISTD_C
#define _UNISTD_C
#define NULL 0
#define __PATH_MAX 4096
void* malloc(unsigned size);
int access(char* pathname, int mode)
{
asm("lea_ebx,[esp+DWORD] %8"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %4"
"mov_ecx,[ecx]"
"mov_eax, %33"
"int !0x80");
}
int chdir(char* path)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %12"
"int !0x80");
}
int fchdir(int fd)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %133"
"int !0x80");
}
/* Defined in the libc */
void _exit(int value);
int fork()
{
asm("mov_eax, %2"
"mov_ebx, %0"
"int !0x80");
}
int waitpid (int pid, int* status_ptr, int options)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %7"
"int !0x80");
}
int execve(char* file_name, char** argv, char** envp)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %11"
"int !0x80");
}
int read(int fd, char* buf, unsigned count) {
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %3"
"int !0x80");
}
int write(int fd, char* buf, unsigned count) {
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %4"
"int !0x80");
}
int lseek(int fd, int offset, int whence)
{
asm("lea_ebx,[esp+DWORD] %12"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %8"
"mov_ecx,[ecx]"
"lea_edx,[esp+DWORD] %4"
"mov_edx,[edx]"
"mov_eax, %19"
"int !0x80");
}
int close(int fd)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %6"
"int !0x80");
}
int unlink (char *filename)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %10"
"int !0x80");
}
int _getcwd(char* buf, int size)
{
asm("lea_ebx,[esp+DWORD] %8"
"mov_ebx,[ebx]"
"lea_ecx,[esp+DWORD] %4"
"mov_ecx,[ecx]"
"mov_eax, %183"
"int !0x80");
}
char* getcwd(char* buf, unsigned size)
{
int c = _getcwd(buf, size);
if(0 == c) return NULL;
return buf;
}
char* getwd(char* buf)
{
return getcwd(buf, __PATH_MAX);
}
char* get_current_dir_name()
{
return getcwd(malloc(__PATH_MAX), __PATH_MAX);
}
int brk(void *addr)
{
asm("mov_eax,[esp+DWORD] %4"
"push_eax"
"mov_eax, %45"
"pop_ebx"
"int !0x80");
}
struct utsname
{
char sysname[65]; /* Operating system name (e.g., "Linux") */
char nodename[65]; /* Name within "some implementation-defined network" */
char release[65]; /* Operating system release (e.g., "2.6.28") */
char version[65]; /* Operating system version */
char machine[65]; /* Hardware identifier */
};
int uname(struct utsname* unameData)
{
asm("lea_ebx,[esp+DWORD] %4"
"mov_ebx,[ebx]"
"mov_eax, %109"
"int !0x80");
}
#endif
mescc-tools-1.5.2/M2libc/x86/x86_defs.M1 0000644 0000000 0000000 00000005077 14522760670 014241 0 ustar ## Copyright (C) 2017 Jeremiah Orians
## This file is part of M2-Planet.
##
## M2-Planet 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.
##
## M2-Planet 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 M2-Planet. If not, see .
DEFINE add_eax, 81C0
DEFINE add_ebp, 81C5
DEFINE add_ebx,eax 01C3
DEFINE add_eax,ebp 01E8
DEFINE add_eax,ebx 01D8
DEFINE and_eax,ebx 21D8
DEFINE call E8
DEFINE call_eax FFD0
DEFINE cmp 39C3
DEFINE cdq 99
DEFINE div_ebx F7F3
DEFINE idiv_ebx F7FB
DEFINE int CD
DEFINE je 0F84
DEFINE jne 0F85
DEFINE jmp E9
DEFINE lea_eax,[ebp+DWORD] 8D85
DEFINE lea_eax,[esp+DWORD] 8D8424
DEFINE lea_ebx,[esp+DWORD] 8D9C24
DEFINE lea_ecx,[esp+DWORD] 8D8C24
DEFINE lea_edx,[esp+DWORD] 8D9424
DEFINE mov_eax,[esp+DWORD] 8B8424
DEFINE mov_eax,ebp 89E8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,ebx 89D8
DEFINE mov_eax,edx 89D0
DEFINE mov_ebx,eax 89C3
DEFINE mov_ecx,eax 89C1
DEFINE mov_ecx,esp 89E1
DEFINE mov_edi,esp 89E7
DEFINE mov_ebp,edi 89fd
DEFINE mov_ebp,esp 89E5
DEFINE mov_eax, B8
DEFINE mov_ebx, BB
DEFINE mov_edx, BA
DEFINE mov_eax,[eax] 8B00
DEFINE mov_ebx,[ebx] 8B1B
DEFINE mov_ecx,[ecx] 8B09
DEFINE mov_edx,[edx] 8B12
DEFINE mov_[ebx],al 8803
DEFINE mov_[ebx],ax 668903
DEFINE mov_[ebx],eax 8903
DEFINE movsx_eax,BYTE_PTR_[eax] 0FBE00
DEFINE movsx_ebx,BYTE_PTR_[ebx] 0FBE1B
DEFINE movsx_eax,WORD_PTR_[eax] 0FBF00
DEFINE movzx_eax,BYTE_PTR_[eax] 0FB600
DEFINE movzx_eax,WORD_PTR_[eax] 0FB700
DEFINE movzx_eax,al 0FB6C0
DEFINE mul_ebx F7E3
DEFINE imul_ebx F7EB
DEFINE NULL 00000000
DEFINE not_eax F7D0
DEFINE or_eax,ebx 09D8
DEFINE pop_eax 58
DEFINE pop_ebx 5B
DEFINE pop_ebp 5D
DEFINE pop_edi 5F
DEFINE push_eax 50
DEFINE push_ebx 53
DEFINE push_ebp 55
DEFINE push_edi 57
DEFINE ret C3
DEFINE sal_eax, C1E0
DEFINE sal_eax,cl D3F0
DEFINE shl_eax,cl D3E0
DEFINE sar_eax,cl D3F8
DEFINE shr_eax,cl D3E8
DEFINE seta_al 0F97C0
DEFINE setae_al 0F93C0
DEFINE setb_al 0F92C0
DEFINE setbe_al 0F96C0
DEFINE sete_al 0F94C0
DEFINE setle_al 0F9EC0
DEFINE setl_al 0F9CC0
DEFINE setge_al 0F9DC0
DEFINE setg_al 0F9FC0
DEFINE setne_al 0F95C0
DEFINE sub_ebx,eax 29C3
DEFINE test_eax,eax 85C0
DEFINE xchg_ebx,eax 93
DEFINE xor_eax,ebx 31D8
mescc-tools-1.5.2/README.md 0000644 0000000 0000000 00000003630 14522760670 012127 0 ustar ## 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-1.5.2/blood-elf.c 0000644 0000000 0000000 00000033242 14522760670 012661 0 ustar /* -*- 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"
// 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.1\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-1.5.2/catm.c 0000644 0000000 0000000 00000003211 14522760670 011733 0 ustar /* 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-1.5.2/check.sh 0000755 0000000 0000000 00000002551 14522760670 012265 0 ustar #! /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-1.5.2/docs/M1.1 0000644 0000000 0000000 00000004211 14522760670 012133 0 ustar .\"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-1.5.2/docs/blood-elf.1 0000644 0000000 0000000 00000002546 14522760670 013532 0 ustar .\"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-1.5.2/docs/get_machine.1 0000644 0000000 0000000 00000003371 14522760670 014127 0 ustar .\"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-1.5.2/docs/hex2.1 0000644 0000000 0000000 00000004731 14522760670 012533 0 ustar .\"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; particularly 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-1.5.2/docs/kaem.1 0000644 0000000 0000000 00000003201 14522760670 012571 0 ustar .\"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-1.5.2/elf_headers/elf32-ARM-debug.hex2 0000644 0000000 0000000 00000005713 14522760670 016321 0 ustar ### 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-1.5.2/elf_headers/elf32-ARM.hex2 0000644 0000000 0000000 00000005726 14522760670 015241 0 ustar ### 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-1.5.2/elf_headers/elf32-debug.hex2 0000644 0000000 0000000 00000005677 14522760670 015715 0 ustar ### 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-1.5.2/elf_headers/elf32.hex2 0000644 0000000 0000000 00000005717 14522760670 014624 0 ustar ### 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-1.5.2/elf_headers/elf64-ARM.hex2 0000644 0000000 0000000 00000006316 14522760670 015242 0 ustar ### 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-1.5.2/elf_headers/elf64-PPC64LE-debug.hex2 0000644 0000000 0000000 00000005217 14522760670 016723 0 ustar ### 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-1.5.2/elf_headers/elf64-PPC64LE.hex2 0000644 0000000 0000000 00000005175 14522760670 015642 0 ustar ### 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-1.5.2/elf_headers/elf64.hex2 0000644 0000000 0000000 00000005022 14522760670 014616 0 ustar ### 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-1.5.2/get_machine.c 0000644 0000000 0000000 00000011605 14522760670 013260 0 ustar /* -*- 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;
if((option_index + 1) < argc)
{
override_string = argv[option_index + 1];
option_index = option_index + 2;
}
else
{
fputs("--override requires an actual override string\n", stderr);
exit(EXIT_FAILURE);
}
}
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], "--endian"))
{
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)
|| match("i386", unameData->machine)
|| match("i486", unameData->machine)
|| match("i586", unameData->machine)
|| match("i686", unameData->machine)
|| match("i686-pae", unameData->machine))fputs("--little-endian", stdout);
else fputs("--big-endian", stdout);
fputc('\n', stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "--hex2"))
{
if(override) fputs(override_string, stdout);
else if(match("aarch64", unameData->machine)) fputs("0x400000", stdout);
else if(match("armv7l", unameData->machine)) fputs("0x10000", stdout);
else if(match("amd64", unameData->machine)
|| match("x86_64", unameData->machine)) fputs("0x600000", stdout);
else if(match("ppc64le", unameData->machine)) fputs("0x10000", stdout);
else if(match("riscv64", unameData->machine)) fputs("0x600000", stdout);
else if(match("i386", unameData->machine)
|| match("i486", unameData->machine)
|| match("i586", unameData->machine)
|| match("i686", unameData->machine)
|| match("i686-pae", unameData->machine)) fputs("0x08048000", stdout);
else fputs("0x0", stdout);
fputc('\n', stdout);
exit(EXIT_SUCCESS);
}
else if(match(argv[option_index], "-V") || match(argv[option_index], "--version"))
{
fputs("get_machine 1.5.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-1.5.2/guix.scm 0000644 0000000 0000000 00000006461 14522760670 012335 0 ustar ;;; 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-1.5.2/hex2.c 0000644 0000000 0000000 00000014531 14522760670 011664 0 ustar /* -*- 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*));
require(NULL != jump_tables, "Failed to allocate our jump_tables\n");
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));
require(NULL != scratch, "failed to allocate our scratch buffer\n");
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], "--big-endian"))
{
BigEndian = TRUE;
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], "--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], "-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));
require(NULL != temp, "failed to allocate file for processing\n");
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.5.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-1.5.2/hex2.h 0000644 0000000 0000000 00000002726 14522760670 011674 0 ustar /* -*- 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-1.5.2/hex2_globals.h 0000644 0000000 0000000 00000003224 14522760670 013371 0 ustar /* -*- 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, int absolute);
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-1.5.2/hex2_linker.c 0000644 0000000 0000000 00000032142 14522760670 013226 0 ustar /* -*- 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));
require(NULL != entry, "failed to allocate entry\n");
/* Ensure we have target address */
entry->target = ip;
/* Store string */
int c = consume_token(source_file);
entry->name = calloc(length(scratch) + 1, sizeof(char));
require(NULL != entry->name, "failed to allocate entry->name\n");
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, int absolute)
{
if(4 == number_of_bytes) return;
else if (absolute && (3 == number_of_bytes))
{
/* Deal with unsigned */
if((16777215 < displacement) || (displacement < 0))
{
fputs("An absolute displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 3 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (3 == number_of_bytes)
{
/* Deal with signed */
if((8388607 < displacement) || (displacement < -8388608))
{
fputs("A relative displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 3 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (absolute && (2 == number_of_bytes))
{
/* Deal with unsigned */
if((65535 < displacement) || (displacement < 0))
{
fputs("An absolute displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 2 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (2 == number_of_bytes)
{
/* Deal with signed */
if((32767 < displacement) || (displacement < -32768))
{
fputs("A relative displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 2 bytes\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (absolute && (1 == number_of_bytes))
{
/* Deal with unsigned */
if((255 < displacement) || (displacement < 0))
{
fputs("An absolute displacement of ", stderr);
fputs(int2str(displacement, 10, TRUE), stderr);
fputs(" does not fit in 1 byte\n", stderr);
exit(EXIT_FAILURE);
}
return;
}
else if (1 == number_of_bytes)
{
/* Deal with signed */
if((127 < displacement) || (displacement < -128))
{
fputs("A relative 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, int absolute)
{
unsigned value = displacement;
/* HALT HARD if we are going to do something BAD*/
range_check(displacement, number_of_bytes, absolute);
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, FALSE); /* Deal with ! */
else if('$' == ch) outputPointer(target, 2, TRUE); /* Deal with $ */
else if('@' == ch) outputPointer(displacement, 2, FALSE); /* Deal with @ */
else if('~' == ch) outputPointer(displacement, 3, FALSE); /* Deal with ~ */
else if('&' == ch) outputPointer(target, 4, TRUE); /* Deal with & */
else if('%' == ch) outputPointer(displacement, 4, FALSE); /* 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-1.5.2/hex2_word.c 0000644 0000000 0000000 00000021710 14522760670 012714 0 ustar /* -*- 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, TRUE); /* Deal with & */
else if('%' == ch) outputPointer(displacement, 4, FALSE); /* 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-1.5.2/makefile 0000644 0000000 0000000 00000010604 14522760670 012347 0 ustar ## 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
$(MAKE) -C Kaem 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
$(MAKE) -C Kaem 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 | results
test/test0/hello.sh
test1-binary: results hex2 M1 get_machine | results
test/test1/hello.sh
test2-binary: results hex2 M1 get_machine | results
test/test2/hello.sh
test3-binary: results hex2 M1 get_machine | results
test/test3/hello.sh
test4-binary: results hex2 M1 get_machine | results
test/test4/hello.sh
test5-binary: results hex2 M1 get_machine | results
test/test5/hello.sh
test6-binary: results hex2 M1 get_machine | results
test/test6/hello.sh
test7-binary: results hex2 M1 get_machine | results
test/test7/hello.sh
test8-binary: results hex2 M1 get_machine | results
test/test8/hello.sh
test9-binary: results hex2 M1 blood-elf get_machine | results
test/test9/hello.sh
test10-binary: results hex2 M1 get_machine | results
test/test10/hello.sh
test11-binary: results hex2 M1 blood-elf get_machine | results
test/test11/hello.sh
test12-binary: results hex2 M1 blood-elf get_machine | results
test/test12/hello.sh
test13-binary: results hex2 M1 blood-elf get_machine | results
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-1.5.2/mescc-tools.scm 0000644 0000000 0000000 00000004727 14522760670 013614 0 ustar ;;; 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-1.5.2/sha256.sh 0000644 0000000 0000000 00000003230 14522760670 012210 0 ustar #! /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-1.5.2/stringify.c 0000644 0000000 0000000 00000005023 14522760670 013030 0 ustar /* -*- 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-1.5.2/test.sh 0000755 0000000 0000000 00000001524 14522760670 012166 0 ustar #! /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-1.5.2/test/test.answers 0000644 0000000 0000000 00000002414 14522760670 014211 0 ustar 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-1.5.2/test/test0/hello.hex2 0000644 0000000 0000000 00000002372 14522760670 014563 0 ustar ## 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
## %