Compare commits
200 Commits
Release_1.
...
master
Author | SHA1 | Date |
---|---|---|
Jeremiah Orians | 754c5de7d9 | |
Andrius Štikonas | 85dd953b70 | |
Jeremiah Orians | f02aaaf67b | |
Andrius Štikonas | b908dac7c5 | |
Andrius Štikonas | a950c3088b | |
Jeremiah Orians | 286964d5f8 | |
Andrius Štikonas | dba5c792c0 | |
Andrius Štikonas | 4f17e046e8 | |
Andrius Štikonas | 259ff86c1b | |
Andrius Štikonas | 39ca206412 | |
Jeremiah Orians | ab8cc2dd7f | |
Andrius Štikonas | 62b53a554e | |
Andrius Štikonas | a9a0fe670b | |
Andrius Štikonas | d310700151 | |
Andrius Štikonas | 12d40f6c82 | |
Andrius Štikonas | 18a7484a99 | |
Andrius Štikonas | bf66daaf4c | |
Andrius Štikonas | 7e7558768a | |
Andrius Štikonas | adb4fb3781 | |
Andrius Štikonas | b8664784b6 | |
Andrius Štikonas | f7fcc0af6e | |
Jeremiah Orians | 62c6f6c80e | |
Jeremiah | c064b344dd | |
Andrius Štikonas | cbd7f67e93 | |
Jeremiah Orians | 73b39a8981 | |
Jeremiah Orians | c50dcade62 | |
Jeremiah Orians | 65444b33d2 | |
Jeremiah Orians | 0a07af340b | |
Jeremiah Orians | fba6dffb66 | |
Jeremiah Orians | c9b9920986 | |
Jeremiah Orians | a983ffaa63 | |
Jeremiah Orians | 406d0856df | |
Jeremiah Orians | 7a12113e2a | |
Andrius Štikonas | a495e6faf6 | |
Andrius Štikonas | 695b74e6f9 | |
Andrius Štikonas | 823be93875 | |
Andrius Štikonas | 1e784f5afb | |
Andrius Štikonas | 646bd15b19 | |
Jeremiah Orians | 9613c28c4b | |
Andrius Štikonas | 185ef7a7c2 | |
Andrius Štikonas | 511601bcd9 | |
Andrius Štikonas | ab49bcafa4 | |
Andrius Štikonas | ba51f3dcc8 | |
Andrius Štikonas | b2414918cc | |
Andrius Štikonas | 575f91cac1 | |
Jeremiah Orians | a025387b81 | |
Andrius Štikonas | 6ebe45f369 | |
Jeremiah Orians | 6d4d6c56ea | |
Jeremiah Orians | a09d9dcfd8 | |
Andrius Štikonas | 546cb1ac95 | |
Jeremiah Orians | cdb09b1608 | |
Jeremiah Orians | ff65efa99e | |
Jeremiah Orians | 876ebe7c68 | |
Jeremiah Orians | 9997d7a275 | |
Andrius Štikonas | 4c310a3f6d | |
Andrius Štikonas | 2da7b3f9a0 | |
Andrius Štikonas | e3651879a5 | |
Andrius Štikonas | de8f47fa9c | |
Andrius Štikonas | 7de9e684a6 | |
Andrius Štikonas | 7a7bfd4529 | |
Andrius Štikonas | 945743e2c6 | |
Jeremiah Orians | 6c59218781 | |
Jeremiah Orians | 54e5daace4 | |
Andrius Štikonas | a900bc6632 | |
Jeremiah Orians | d8fb878d7a | |
Jeremiah Orians | 55929d4ddf | |
Jeremiah Orians | 67786705a5 | |
Jeremiah Orians | ffe4e5f66e | |
Jeremiah Orians | ae9e700592 | |
Andrius Štikonas | 56ee526c4c | |
Jeremiah Orians | 5e74995c13 | |
Jeremiah Orians | 0577243444 | |
Jeremiah Orians | 4af9b79c1b | |
Andrius Štikonas | bbf67601e1 | |
Jeremiah Orians | 8c3fa49936 | |
Andrius Štikonas | ae48dbd6cb | |
Jeremiah Orians | 7fb9d682ec | |
Jeremiah Orians | 745998ac13 | |
Jeremiah Orians | 99df87bc0d | |
Jeremiah Orians | b37dfc7b12 | |
Jeremiah Orians | 3bac25a1ac | |
Jeremiah Orians | 51dfec1791 | |
Jeremiah Orians | a3c14bcd1b | |
Jeremiah Orians | 8bc09f2b2e | |
Jeremiah Orians | a925f90c3b | |
Jeremiah Orians | 0c1c22bc2f | |
Jeremiah Orians | da542698e7 | |
Jeremiah Orians | cece07145c | |
Jan (janneke) Nieuwenhuizen | d223581d4e | |
Jeremiah Orians | d80d8a652b | |
Jeremiah Orians | 46cf81af83 | |
Jeremiah Orians | b0b440c2df | |
Jeremiah Orians | 163dab268c | |
Jeremiah Orians | 37ca8e3df9 | |
Jeremiah Orians | 5f8484e683 | |
Jeremiah Orians | 32ef09f964 | |
Jeremiah Orians | fc4c1998aa | |
Jeremiah Orians | a9d88e8e6c | |
Jeremiah Orians | 8007ae9ce6 | |
Jeremiah Orians | 62eedce858 | |
Jeremiah Orians | a65619dbf4 | |
Jeremiah Orians | ba1fc44f29 | |
Jeremiah Orians | 695672985e | |
Jeremiah Orians | 6f8e2eb905 | |
deesix | 17c4c6b977 | |
deesix | cb27e5314a | |
deesix | dd67ccddce | |
deesix | 3400296b9b | |
deesix | 05d962fcfc | |
deesix | fb5bae96ab | |
deesix | ab055a8823 | |
deesix | 6bb784eae5 | |
deesix | f865e47646 | |
deesix | 1a9bbe6e63 | |
Jeremiah Orians | c5068b227a | |
Jeremiah Orians | 2043a574c9 | |
deesix | 548993a884 | |
deesix | ae897dcfdb | |
deesix | 52b638f48f | |
Jeremiah Orians | f2094a9e5b | |
Jeremiah Orians | 3c6b23f734 | |
Jeremiah Orians | 5dd81d871e | |
deesix | 818784228c | |
deesix | e660caca73 | |
deesix | 7860378b75 | |
deesix | 55db771e29 | |
deesix | e9553d5f13 | |
deesix | bcd0f49859 | |
Jeremiah Orians | 204d2612d7 | |
Jeremiah Orians | f5f996626a | |
Jeremiah Orians | d34bb92b0d | |
deesix | 9f26dbcc68 | |
deesix | 3aa8327334 | |
Jeremiah Orians | 4def464475 | |
Jeremiah Orians | 768f229c1d | |
Sanne Wouda | 0e3d5b609a | |
Sanne Wouda | b83086642e | |
Jeremiah Orians | 674a6f5569 | |
Sanne Wouda | dd1f5db9f1 | |
Jeremiah Orians | bb3b4eebd8 | |
Sanne Wouda | c4d329b6cc | |
Sanne Wouda | 45685d0c30 | |
Jeremiah Orians | 810d7da9fc | |
Jeremiah Orians | bc2f0e164d | |
Sanne Wouda | 09acd6253d | |
Sanne Wouda | a8551f2fcd | |
Sanne Wouda | 6f2cebc4ca | |
Sanne Wouda | 4550eec19e | |
Jeremiah Orians | 3c4c09b95e | |
Jeremiah Orians | 25fd5e66c9 | |
Jeremiah Orians | bdd4e65580 | |
Jeremiah Orians | 0ab7cb78eb | |
Sanne Wouda | 63bb59404d | |
Sanne Wouda | 49fbe8942f | |
Sanne Wouda | 89c6513cd8 | |
Sanne Wouda | cd96f65a23 | |
Sanne Wouda | 7b8a99db3c | |
Sanne Wouda | a18e0c1782 | |
Sanne Wouda | fa0f135ebb | |
Jeremiah Orians | 921cc86ce6 | |
Jeremiah Orians | 358b6cfb96 | |
Jeremiah Orians | e451abd667 | |
Jeremiah Orians | cc1a17a040 | |
Jeremiah Orians | 07baf02efe | |
Jeremiah Orians | c220d14928 | |
Jeremiah Orians | e25c1995aa | |
Jeremiah Orians | 6a3d3e78e0 | |
Jeremiah Orians | 44e14bb662 | |
Jeremiah Orians | 0ed81de9e1 | |
Jeremiah Orians | 4de11b1bc6 | |
Michael Schierl | 5afeb0743e | |
Michael Schierl | 608fba306f | |
Michael Schierl | 91bab2ef98 | |
Jeremiah Orians | 6fe6f44a29 | |
Jeremiah Orians | e7a0ecd244 | |
Jeremiah Orians | d9504e3872 | |
Sanne Wouda | 968fdfea65 | |
Jeremiah Orians | e5befc4fee | |
Jeremiah Orians | f2cae3d501 | |
Jeremiah Orians | eaf3861954 | |
Jeremiah Orians | 132e685f97 | |
Jeremiah Orians | 9da48c5ece | |
Jeremiah Orians | 5c22aac02d | |
Jeremiah | 196c66d19e | |
Sanne Wouda | a63b8837c0 | |
Jeremiah | d34ea502cc | |
Sanne Wouda | 58b563435b | |
Sanne Wouda | 624a5ac92d | |
Jeremiah Orians | 0615223052 | |
Jeremiah Orians | 93e8b0c0a4 | |
Jeremiah Orians | e3ca15c731 | |
Jeremiah Orians | a5bc08b23f | |
Jeremiah Orians | 1975d88581 | |
Jeremiah Orians | 67dbbbdcfc | |
Jeremiah Orians | 57264eb157 | |
Jeremiah Orians | 39915de931 | |
Jeremiah Orians | c4a636c99d | |
Jeremiah Orians | e9da9c802e | |
nimaje | 52114585bf | |
nimaje | 028bdaf951 |
|
@ -23,4 +23,3 @@ bin/
|
|||
temp/
|
||||
test/scratch/
|
||||
scratch/
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "M2libc"]
|
||||
path = M2libc
|
||||
url = https://github.com/oriansj/M2libc.git
|
141
CHANGELOG.org
141
CHANGELOG.org
|
@ -16,6 +16,147 @@
|
|||
|
||||
* Current
|
||||
** Added
|
||||
Generates a warning on unknown preprocessor commands
|
||||
Implemented C99 negation
|
||||
Add support for empty defines
|
||||
Implemented support for #ifdef and #ifndef
|
||||
Implemented #error statement support
|
||||
Add support for evaluating macro variables
|
||||
Define arch specific variables
|
||||
__i386__
|
||||
__x86_64__
|
||||
__arm__
|
||||
__aarch64__
|
||||
__riscv
|
||||
__riscv_xlen
|
||||
Implemented #undef statement support
|
||||
Add support for char** arrays
|
||||
Added basic test for multi-dimensional arrays
|
||||
Implemented minimal variable dereferencing support (base types only)
|
||||
Add support for assignment operators
|
||||
Add riscv32 port
|
||||
Enable riscv32 tests
|
||||
Added #FILENAME statement functionality to enable more flexiblity with debug messages
|
||||
|
||||
** Changed
|
||||
Updated M2libc dependency
|
||||
|
||||
** Fixed
|
||||
--max-string now validates passed input is an integer
|
||||
-D now throws an error if not passed an argument
|
||||
Fix segfault on half done #define statements
|
||||
Correct #define behavior inside of #if/#elif/#else/#endif blocks
|
||||
make clean now cleans up RISCV tests
|
||||
catch half broken #define (statements instead of segfaulting
|
||||
no longer segfault on null macro name
|
||||
no longer try to expand null tokens
|
||||
Catch the special case of attempting to remove a NULL macro token
|
||||
Fixed nested #if behavior to do the actual correct thing
|
||||
|
||||
** Removed
|
||||
|
||||
* 1.9 - 2021-10-03
|
||||
** Added
|
||||
Add riscv64 port
|
||||
Add tests for riscv64
|
||||
|
||||
** Changed
|
||||
Breakup program function to reduce complexity and risk of errors
|
||||
Update M2libc to enable RISC-V Development
|
||||
Update all tests to work around breaking update in blood-elf
|
||||
|
||||
** Fixed
|
||||
Stop hang on large global arrays
|
||||
Fixed Memory leak on read token
|
||||
Fixed Global buffer overflow in collect_weird_string
|
||||
Updated info in HACKING
|
||||
Report proper error message for negative global array values
|
||||
Fix global array initialization to allocate the correct amount of memory
|
||||
Fix Problem with global arrays
|
||||
Catch truncated function calls and truncated array statements
|
||||
|
||||
** Removed
|
||||
|
||||
* 1.8 - 2021-06-08
|
||||
** Added
|
||||
AArch64 added support for arithmetic right shift
|
||||
AMD64 added support for unsigned comparisons
|
||||
armv7l added support for unsigned comparisons
|
||||
AArch64 added support for unsigned comparison
|
||||
added support for --max-string to enable arbitrary large C tokens and strings
|
||||
Added prototype output buffering for x86
|
||||
List of known M2-Planet issues has been added
|
||||
Added first generation implemention of typedef
|
||||
Add newline tokens to parse stream
|
||||
Add a preprocessor-only mode (-E)
|
||||
Add macro directives to token_list
|
||||
Add support for conditional inclusion (#if, #elif, #else, #endif)
|
||||
Add error checking for unexpected #endif
|
||||
Added hacky version of #define support (#if defined($FOO))
|
||||
Add a test for supported preprocessor features
|
||||
Added simple macro expansion
|
||||
Add support for global char foo[12]; definitions
|
||||
Added support for make -j $num build operations for tests to speed up testing on multicore systems
|
||||
Enable virtualization of bare metal binaries
|
||||
Add support for &global_variable
|
||||
Added __M2__ to default macro environment to enable #if defined(__M2__) M2-Planet specific functionality
|
||||
Add support for -D variable and -D variable=value
|
||||
Added -e (errexit) shell option in scripts, where possible
|
||||
|
||||
** Changed
|
||||
knight-posix HEAP pointer now set by kernel rather than libc
|
||||
knight now leverages new SET instructions to reduce instruction count and processing time.
|
||||
Make type information localized to the inside of statements
|
||||
Default types available and added --bootstrap-mode flag to enable the old behavior for cc_* emulation
|
||||
Improve error reporting for unexpected non-newline
|
||||
Moved all low level primitives into M2libc
|
||||
Updated tests to leverage M2libc
|
||||
Standardized test scripts
|
||||
tests: use new-style mescc-tools flags
|
||||
Harmonize --debug behaviour for all scripts of the same test
|
||||
Unified all tests for all architectures
|
||||
Replace file_print with fputs
|
||||
Skip "extern" in type definitions. This makes supporting gcc >= 10 easier in GNU Mes.
|
||||
|
||||
** Fixed
|
||||
AArch64 Fix LSEEK syscall number
|
||||
Arithmetic recursion to match gcc behavior in regards to if(-1 > 0)
|
||||
Fix x86 behavior on unsigned compares
|
||||
Remove Segfault that occurs when outputing files in excess of 100MB in size
|
||||
Fix x86 close syscall
|
||||
Type abuse bugs that resulted in segfaults
|
||||
Fixed the backwards assignment of x86/AMD64 division
|
||||
Fix e25c1995aab5833323ee0784402ae7d3318b093e SCM MES regression
|
||||
Fixed the backwards modulus
|
||||
Various segfaults in the new macro preprocessor
|
||||
Fix all special cases where line number was wrong
|
||||
|
||||
** Removed
|
||||
Removed obsolete bootstrap directory
|
||||
Removed need for fixup
|
||||
Remove test/common_* files with M2libc transistion
|
||||
|
||||
* 1.7 - 2020-11-15
|
||||
** Added
|
||||
Added common error catch for the declaration of variables inside of loops that usually results in crashes
|
||||
Added support for C multi-strings
|
||||
|
||||
** Changed
|
||||
Changed ELF headers for FreeBSD compatibility
|
||||
Changed sha256 function to be more compatible with FreeBSD
|
||||
Changed malloc behavior to accept non-exact brk returns
|
||||
Changed looping tests to reflect new expected code behavior in regards to variable declaration inside of loops
|
||||
|
||||
** Fixed
|
||||
Type regression in cc_* compatibility
|
||||
Shift behavior to better match C standard
|
||||
64bit host behavior in regards to primary_expr_number in knight tests
|
||||
GCC 10 compatibility
|
||||
|
||||
** Removed
|
||||
|
||||
* 1.6 - 2020-04-30
|
||||
** Added
|
||||
Added test for chdir and getcwd family of posix primitives
|
||||
Added fflush stub, for code to match our behavior when compiled with GCC (we don't buffer)
|
||||
Added fseek and rewind functions
|
||||
|
|
18
HACKING
18
HACKING
|
@ -1,11 +1,12 @@
|
|||
-*-mode:org-*-
|
||||
|
||||
M2-Planet being based on the goal of bootstrapping the Minimal C compiler
|
||||
required to support structs, arrays, inline assembly and self hosting;
|
||||
is rather small, under 1.7Kloc according to sloccount
|
||||
required to support C macros, structs, arrays, inline assembly and self hosting;
|
||||
is rather small, around 3Kloc according to sloccount
|
||||
|
||||
* SETUP
|
||||
The most obvious way to setup for M2-Planet development is to clone and setup mescc-tools first (https://github.com/oriansj/mescc-tools.git)
|
||||
The most obvious way to setup for M2-Planet development is to clone --recursive
|
||||
and setup mescc-tools first (https://github.com/oriansj/mescc-tools.git)
|
||||
Then be sure to install any C compiler and make clone of your choice.
|
||||
|
||||
* BUILD
|
||||
|
@ -23,17 +24,18 @@ To all future release of M2-Planet. All minor releases are buildable by the last
|
|||
major release and All major releases are buildable by the last major release.
|
||||
|
||||
* DEBUG
|
||||
To get a properly debuggable binary: make M2-Planet-gcc
|
||||
However if you are comfortable with gdb, knowing that function names are
|
||||
prefixed with FUNCTION_ the M2-Planet binary is quite debuggable.
|
||||
To get a properly debuggable binary of M2-Planet: make M2-Planet
|
||||
M2-Planet also can create debuggable binaries with the help of blood-elf and the
|
||||
--debug option. if you are comfortable with gdb, knowing that function names are
|
||||
prefixed with FUNCTION_ M2-Planet built binaries are quite debuggable.
|
||||
|
||||
* Bugs
|
||||
M2-Planet assumes a very heavily restricted subset of the C language and many C
|
||||
programs will break hard when passed to M2-Planet.
|
||||
|
||||
M2-Planet does not actually implement any primitive functionality, it is assumed
|
||||
that will be written in inline assembly by the programmer or provided by the
|
||||
programmer durring the assembly and linking stages
|
||||
that will be written in inline assembly by the programmer or leveraged via M2libc
|
||||
which is the C library written in the M2-Planet C subset.
|
||||
|
||||
* Magic
|
||||
** argument and local stack
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1f4ac53d050bbd976deb40de3c9b4bd1de2782e3
|
|
@ -8,9 +8,3 @@ surprising part of all M2-Planet can self-host M2-Planet.
|
|||
|
||||
Further more M2-Planet is cross-platform and self-hosting across platforms
|
||||
with fully deterministic builds enabling perfect reproducibility.
|
||||
|
||||
To bootstrap from assembly simple run ./bootstrap-x86.sh after cd into the
|
||||
bootstrap directory (the only requirement is mescc-tools to be installed)
|
||||
|
||||
Or if you have no binaries to bootstrap from please use mescc-tools-seed;
|
||||
which will not only bootstrap mescc-tools but also M2-Planet
|
||||
|
|
16
cc-minimal.c
16
cc-minimal.c
|
@ -26,11 +26,11 @@ struct token_list* reverse_list(struct token_list* head);
|
|||
struct token_list* program();
|
||||
void recursive_output(struct token_list* i, FILE* out);
|
||||
int match(char* a, char* b);
|
||||
void file_print(char* s, FILE* f);
|
||||
char* parse_string(char* string);
|
||||
|
||||
int main()
|
||||
{
|
||||
MAX_STRING = 4096;
|
||||
hold_string = calloc(MAX_STRING, sizeof(char));
|
||||
FILE* in = fopen("tape_01", "r");
|
||||
FILE* destination_file = fopen("tape_02", "w");
|
||||
|
@ -38,9 +38,11 @@ int main()
|
|||
|
||||
global_token = read_all_tokens(in, global_token, "tape_01");
|
||||
|
||||
fclose(in);
|
||||
|
||||
if(NULL == global_token)
|
||||
{
|
||||
file_print("Either no input files were given or they were empty\n", stderr);
|
||||
fputs("Either no input files were given or they were empty\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
global_token = reverse_list(global_token);
|
||||
|
@ -51,12 +53,14 @@ int main()
|
|||
program();
|
||||
|
||||
/* Output the program we have compiled */
|
||||
file_print("\n# Core program\n", destination_file);
|
||||
fputs("\n# Core program\n", destination_file);
|
||||
recursive_output(output_list, destination_file);
|
||||
file_print("\n\n# Program global variables\n", destination_file);
|
||||
fputs("\n\n# Program global variables\n", destination_file);
|
||||
recursive_output(globals_list, destination_file);
|
||||
file_print("\n# Program strings\n", destination_file);
|
||||
fputs("\n# Program strings\n", destination_file);
|
||||
recursive_output(strings_list, destination_file);
|
||||
file_print("\n:STACK\n", destination_file);
|
||||
fputs("\n:STACK\n", destination_file);
|
||||
|
||||
fclose(destination_file);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
211
cc.c
211
cc.c
|
@ -24,18 +24,34 @@
|
|||
void initialize_types();
|
||||
struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename);
|
||||
struct token_list* reverse_list(struct token_list* head);
|
||||
|
||||
struct token_list* remove_line_comments(struct token_list* head);
|
||||
struct token_list* remove_line_comment_tokens(struct token_list* head);
|
||||
struct token_list* remove_preprocessor_directives(struct token_list* head);
|
||||
|
||||
void eat_newline_tokens();
|
||||
void init_macro_env(char* sym, char* value, char* source, int num);
|
||||
void preprocess();
|
||||
void program();
|
||||
void recursive_output(struct token_list* i, FILE* out);
|
||||
void output_tokens(struct token_list *i, FILE* out);
|
||||
int strtoint(char *a);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
hold_string = calloc(MAX_STRING, sizeof(char));
|
||||
require(NULL != hold_string, "Impossible Exhustion has occured\n");
|
||||
MAX_STRING = 4096;
|
||||
BOOTSTRAP_MODE = FALSE;
|
||||
PREPROCESSOR_MODE = FALSE;
|
||||
int DEBUG = FALSE;
|
||||
FILE* in = stdin;
|
||||
FILE* destination_file = stdout;
|
||||
Architecture = KNIGHT_NATIVE; /* Assume Knight-native */
|
||||
Architecture = 0; /* catch unset */
|
||||
init_macro_env("__M2__", "42", "__INTERNAL_M2__", 0); /* Setup __M2__ */
|
||||
char* arch;
|
||||
char* name;
|
||||
char* hold;
|
||||
int env=0;
|
||||
char* val;
|
||||
|
||||
int i = 1;
|
||||
while(i <= argc)
|
||||
|
@ -46,16 +62,29 @@ int main(int argc, char** argv)
|
|||
}
|
||||
else if(match(argv[i], "-f") || match(argv[i], "--file"))
|
||||
{
|
||||
char* name = argv[i + 1];
|
||||
if(NULL == hold_string)
|
||||
{
|
||||
hold_string = calloc(MAX_STRING + 4, sizeof(char));
|
||||
require(NULL != hold_string, "Impossible Exhaustion has occurred\n");
|
||||
}
|
||||
|
||||
name = argv[i + 1];
|
||||
if(NULL == name)
|
||||
{
|
||||
fputs("did not receive a file name\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
in = fopen(name, "r");
|
||||
if(NULL == in)
|
||||
{
|
||||
file_print("Unable to open for reading file: ", stderr);
|
||||
file_print(name, stderr);
|
||||
file_print("\n Aborting to avoid problems\n", stderr);
|
||||
fputs("Unable to open for reading file: ", stderr);
|
||||
fputs(name, stderr);
|
||||
fputs("\n Aborting to avoid problems\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
global_token = read_all_tokens(in, global_token, name);
|
||||
fclose(in);
|
||||
i = i + 2;
|
||||
}
|
||||
else if(match(argv[i], "-o") || match(argv[i], "--output"))
|
||||
|
@ -63,9 +92,9 @@ int main(int argc, char** argv)
|
|||
destination_file = fopen(argv[i + 1], "w");
|
||||
if(NULL == destination_file)
|
||||
{
|
||||
file_print("Unable to open for writing file: ", stderr);
|
||||
file_print(argv[i + 1], stderr);
|
||||
file_print("\n Aborting to avoid problems\n", stderr);
|
||||
fputs("Unable to open for writing file: ", stderr);
|
||||
fputs(argv[i + 1], stderr);
|
||||
fputs("\n Aborting to avoid problems\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
i = i + 2;
|
||||
|
@ -73,21 +102,80 @@ int main(int argc, char** argv)
|
|||
else if(match(argv[i], "-A") || match(argv[i], "--architecture"))
|
||||
{
|
||||
arch = argv[i + 1];
|
||||
if(match("knight-native", arch)) Architecture = KNIGHT_NATIVE;
|
||||
else if(match("knight-posix", arch)) Architecture = KNIGHT_POSIX;
|
||||
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 = AARCH64;
|
||||
if(match("knight-native", arch)) {
|
||||
Architecture = KNIGHT_NATIVE;
|
||||
init_macro_env("__knight__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("knight-posix", arch)) {
|
||||
Architecture = KNIGHT_POSIX;
|
||||
init_macro_env("__knight_posix__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("x86", arch))
|
||||
{
|
||||
Architecture = X86;
|
||||
init_macro_env("__i386__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("amd64", arch))
|
||||
{
|
||||
Architecture = AMD64;
|
||||
init_macro_env("__x86_64__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("armv7l", arch))
|
||||
{
|
||||
Architecture = ARMV7L;
|
||||
init_macro_env("__arm__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("aarch64", arch))
|
||||
{
|
||||
Architecture = AARCH64;
|
||||
init_macro_env("__aarch64__", "1", "--architecture", env);
|
||||
env = env + 1;
|
||||
}
|
||||
else if(match("riscv32", arch))
|
||||
{
|
||||
Architecture = RISCV32;
|
||||
init_macro_env("__riscv", "1", "--architecture", env);
|
||||
init_macro_env("__riscv_xlen", "32", "--architecture", env + 1);
|
||||
env = env + 2;
|
||||
}
|
||||
else if(match("riscv64", arch))
|
||||
{
|
||||
Architecture = RISCV64;
|
||||
init_macro_env("__riscv", "1", "--architecture", env);
|
||||
init_macro_env("__riscv_xlen", "64", "--architecture", env + 1);
|
||||
env = env + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
file_print("Unknown architecture: ", stderr);
|
||||
file_print(arch, stderr);
|
||||
file_print(" know values are: knight-native, knight-posix, x86, amd64, armv7l and aarch64", stderr);
|
||||
fputs("Unknown architecture: ", stderr);
|
||||
fputs(arch, stderr);
|
||||
fputs(" know values are: knight-native, knight-posix, x86, amd64, armv7l, aarch64, riscv32 and riscv64\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
i = i + 2;
|
||||
}
|
||||
else if(match(argv[i], "--max-string"))
|
||||
{
|
||||
hold = argv[i+1];
|
||||
if(NULL == hold)
|
||||
{
|
||||
fputs("--max-string requires a numeric argument\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
MAX_STRING = strtoint(hold);
|
||||
require(0 < MAX_STRING, "Not a valid string size\nAbort and fix your --max-string\n");
|
||||
i = i + 2;
|
||||
}
|
||||
else if(match(argv[i], "--bootstrap-mode"))
|
||||
{
|
||||
BOOTSTRAP_MODE = TRUE;
|
||||
i = i + 1;
|
||||
}
|
||||
else if(match(argv[i], "-g") || match(argv[i], "--debug"))
|
||||
{
|
||||
DEBUG = TRUE;
|
||||
|
@ -95,49 +183,112 @@ int main(int argc, char** argv)
|
|||
}
|
||||
else if(match(argv[i], "-h") || match(argv[i], "--help"))
|
||||
{
|
||||
file_print(" -f input file\n -o output file\n --help for this message\n --version for file version\n", stdout);
|
||||
fputs(" -f input file\n -o output file\n --help for this message\n --version for file version\n", stdout);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else if(match(argv[i], "-E"))
|
||||
{
|
||||
PREPROCESSOR_MODE = TRUE;
|
||||
i = i + 1;
|
||||
}
|
||||
else if(match(argv[i], "-D"))
|
||||
{
|
||||
val = argv[i+1];
|
||||
if(NULL == val)
|
||||
{
|
||||
fputs("-D requires an argument", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
while(0 != val[0])
|
||||
{
|
||||
if('=' == val[0])
|
||||
{
|
||||
val[0] = 0;
|
||||
val = val + 1;
|
||||
break;
|
||||
}
|
||||
val = val + 1;
|
||||
}
|
||||
init_macro_env(argv[i+1], val, "__ARGV__", env);
|
||||
env = env + 1;
|
||||
i = i + 2;
|
||||
}
|
||||
else if(match(argv[i], "-V") || match(argv[i], "--version"))
|
||||
{
|
||||
file_print("M2-Planet v1.5.0\n", stderr);
|
||||
fputs("M2-Planet v1.10.0\n", stderr);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
file_print("UNKNOWN ARGUMENT\n", stdout);
|
||||
fputs("UNKNOWN ARGUMENT\n", stdout);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Deal with special case of architecture not being set */
|
||||
if(0 == Architecture)
|
||||
{
|
||||
Architecture = KNIGHT_NATIVE;
|
||||
init_macro_env("__knight__", "1", "--architecture", env);
|
||||
}
|
||||
|
||||
/* Deal with special case of wanting to read from standard input */
|
||||
if(stdin == in)
|
||||
{
|
||||
hold_string = calloc(MAX_STRING + 4, sizeof(char));
|
||||
require(NULL != hold_string, "Impossible Exhaustion has occurred\n");
|
||||
global_token = read_all_tokens(in, global_token, "STDIN");
|
||||
}
|
||||
|
||||
if(NULL == global_token)
|
||||
{
|
||||
file_print("Either no input files were given or they were empty\n", stderr);
|
||||
fputs("Either no input files were given or they were empty\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
global_token = reverse_list(global_token);
|
||||
|
||||
if (BOOTSTRAP_MODE)
|
||||
{
|
||||
global_token = remove_line_comment_tokens(global_token);
|
||||
global_token = remove_preprocessor_directives(global_token);
|
||||
}
|
||||
else
|
||||
{
|
||||
global_token = remove_line_comments(global_token);
|
||||
preprocess();
|
||||
}
|
||||
|
||||
if (PREPROCESSOR_MODE)
|
||||
{
|
||||
fputs("\n/* Preprocessed source */\n", destination_file);
|
||||
output_tokens(global_token, destination_file);
|
||||
goto exit_success;
|
||||
}
|
||||
|
||||
/* the main parser doesn't know how to handle newline tokens */
|
||||
eat_newline_tokens();
|
||||
|
||||
initialize_types();
|
||||
reset_hold_string();
|
||||
output_list = NULL;
|
||||
program();
|
||||
|
||||
/* Output the program we have compiled */
|
||||
file_print("\n# Core program\n", destination_file);
|
||||
fputs("\n# Core program\n", destination_file);
|
||||
recursive_output(output_list, destination_file);
|
||||
if(KNIGHT_NATIVE == Architecture) file_print("\n", destination_file);
|
||||
else if(DEBUG) file_print("\n:ELF_data\n", destination_file);
|
||||
file_print("\n# Program global variables\n", destination_file);
|
||||
if(KNIGHT_NATIVE == Architecture) fputs("\n", destination_file);
|
||||
else if(DEBUG) fputs("\n:ELF_data\n", destination_file);
|
||||
fputs("\n# Program global variables\n", destination_file);
|
||||
recursive_output(globals_list, destination_file);
|
||||
file_print("\n# Program strings\n", destination_file);
|
||||
fputs("\n# Program strings\n", destination_file);
|
||||
recursive_output(strings_list, destination_file);
|
||||
if(KNIGHT_NATIVE == Architecture) file_print("\n:STACK\n", destination_file);
|
||||
else if(!DEBUG) file_print("\n:ELF_end\n", destination_file);
|
||||
if(KNIGHT_NATIVE == Architecture) fputs("\n:STACK\n", destination_file);
|
||||
else if(!DEBUG) fputs("\n:ELF_end\n", destination_file);
|
||||
|
||||
exit_success:
|
||||
if (destination_file != stdout)
|
||||
{
|
||||
fclose(destination_file);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
53
cc.h
53
cc.h
|
@ -20,31 +20,32 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// CONSTANT MAX_STRING 4096
|
||||
#define MAX_STRING 4096
|
||||
// CONSTANT FALSE 0
|
||||
#define FALSE 0
|
||||
// CONSTANT TRUE 1
|
||||
#define TRUE 1
|
||||
|
||||
// CONSTANT KNIGHT_NATIVE 0
|
||||
#define KNIGHT_NATIVE 0
|
||||
// CONSTANT KNIGHT_POSIX 1
|
||||
#define KNIGHT_POSIX 1
|
||||
// CONSTANT X86 2
|
||||
#define X86 2
|
||||
// CONSTANT AMD64 3
|
||||
#define AMD64 3
|
||||
// CONSTANT ARMV7L 4
|
||||
#define ARMV7L 4
|
||||
// CONSTANT AARCH64 5
|
||||
#define AARCH64 5
|
||||
// CONSTANT KNIGHT_NATIVE 1
|
||||
#define KNIGHT_NATIVE 1
|
||||
// CONSTANT KNIGHT_POSIX 2
|
||||
#define KNIGHT_POSIX 2
|
||||
// CONSTANT X86 3
|
||||
#define X86 3
|
||||
// CONSTANT AMD64 4
|
||||
#define AMD64 4
|
||||
// CONSTANT ARMV7L 5
|
||||
#define ARMV7L 5
|
||||
// CONSTANT AARCH64 6
|
||||
#define AARCH64 6
|
||||
// CONSTANT RISCV32 7
|
||||
#define RISCV32 7
|
||||
// CONSTANT RISCV64 8
|
||||
#define RISCV64 8
|
||||
|
||||
|
||||
char* copy_string(char* target, char* source);
|
||||
void copy_string(char* target, char* source, int max);
|
||||
int in_set(int c, char* s);
|
||||
int match(char* a, char* b);
|
||||
void file_print(char* s, FILE* f);
|
||||
void require(int bool, char* error);
|
||||
void reset_hold_string();
|
||||
|
||||
|
@ -83,22 +84,4 @@ struct token_list
|
|||
};
|
||||
};
|
||||
|
||||
/* What types we have */
|
||||
struct type* global_types;
|
||||
struct type* prim_types;
|
||||
|
||||
/* What we are currently working on */
|
||||
struct token_list* global_token;
|
||||
|
||||
/* Output reorder collections*/
|
||||
struct token_list* output_list;
|
||||
struct token_list* strings_list;
|
||||
struct token_list* globals_list;
|
||||
|
||||
/* Make our string collection more efficient */
|
||||
char* hold_string;
|
||||
int string_index;
|
||||
|
||||
/* Our Target Architecture */
|
||||
int Architecture;
|
||||
int register_size;
|
||||
#include "cc_globals.h"
|
||||
|
|
|
@ -16,18 +16,31 @@
|
|||
* along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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 */
|
||||
};
|
||||
/* What types we have */
|
||||
struct type* global_types;
|
||||
struct type* prim_types;
|
||||
|
||||
int uname(struct utsname* unameData)
|
||||
{
|
||||
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
|
||||
"SET_X8_TO_SYS_UNAME"
|
||||
"SYSCALL");
|
||||
}
|
||||
/* What we are currently working on */
|
||||
struct token_list* global_token;
|
||||
|
||||
/* Output reorder collections*/
|
||||
struct token_list* output_list;
|
||||
struct token_list* strings_list;
|
||||
struct token_list* globals_list;
|
||||
|
||||
/* Make our string collection more efficient */
|
||||
char* hold_string;
|
||||
int string_index;
|
||||
|
||||
/* Our Target Architecture */
|
||||
int Architecture;
|
||||
int register_size;
|
||||
|
||||
int MAX_STRING;
|
||||
struct type* integer;
|
||||
|
||||
/* enable bootstrap-mode */
|
||||
int BOOTSTRAP_MODE;
|
||||
|
||||
/* enable preprocessor-only mode */
|
||||
int PREPROCESSOR_MODE;
|
|
@ -0,0 +1,49 @@
|
|||
/* Copyright (C) 2016 Jeremiah Orians
|
||||
* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* What types we have */
|
||||
extern struct type* global_types;
|
||||
extern struct type* prim_types;
|
||||
|
||||
/* What we are currently working on */
|
||||
extern struct token_list* global_token;
|
||||
|
||||
/* Output reorder collections*/
|
||||
extern struct token_list* output_list;
|
||||
extern struct token_list* strings_list;
|
||||
extern struct token_list* globals_list;
|
||||
|
||||
/* Make our string collection more efficient */
|
||||
extern char* hold_string;
|
||||
extern int string_index;
|
||||
|
||||
/* Our Target Architecture */
|
||||
extern int Architecture;
|
||||
extern int register_size;
|
||||
|
||||
/* Allow us to have a single settable max string */
|
||||
extern int MAX_STRING;
|
||||
|
||||
/* make default type integer */
|
||||
extern struct type* integer;
|
||||
|
||||
/* enable bootstrap-mode */
|
||||
extern int BOOTSTRAP_MODE;
|
||||
|
||||
/* enable preprocessor-only mode */
|
||||
extern int PREPROCESSOR_MODE;
|
|
@ -0,0 +1,835 @@
|
|||
/* Copyright (C) 2021 Sanne Wouda
|
||||
* Copyright (C) 2021 Andrius Štikonas <andrius@stikonas.eu>
|
||||
* Copyright (C) 2022 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "cc.h"
|
||||
#include "gcc_req.h"
|
||||
|
||||
void require(int bool, char* error);
|
||||
int strtoint(char* a);
|
||||
void line_error_token(struct token_list* list);
|
||||
struct token_list* eat_token(struct token_list* head);
|
||||
|
||||
struct conditional_inclusion
|
||||
{
|
||||
struct conditional_inclusion* prev;
|
||||
int include; /* 1 == include, 0 == skip */
|
||||
int previous_condition_matched; /* 1 == all subsequent conditions treated as FALSE */
|
||||
};
|
||||
|
||||
struct macro_list
|
||||
{
|
||||
struct macro_list* next;
|
||||
char* symbol;
|
||||
struct token_list* expansion;
|
||||
};
|
||||
|
||||
struct macro_list* macro_env;
|
||||
struct conditional_inclusion* conditional_inclusion_top;
|
||||
|
||||
/* point where we are currently modifying the global_token list */
|
||||
struct token_list* macro_token;
|
||||
|
||||
void init_macro_env(char* sym, char* value, char* source, int num)
|
||||
{
|
||||
struct macro_list* hold = macro_env;
|
||||
macro_env = calloc(1, sizeof(struct macro_list));
|
||||
macro_env->symbol = sym;
|
||||
macro_env->next = hold;
|
||||
macro_env->expansion = calloc(1, sizeof(struct token_list));
|
||||
macro_env->expansion->s = value;
|
||||
macro_env->expansion->filename = source;
|
||||
macro_env->expansion->linenumber = num;
|
||||
}
|
||||
|
||||
void eat_current_token()
|
||||
{
|
||||
int update_global_token = FALSE;
|
||||
if (macro_token == global_token)
|
||||
update_global_token = TRUE;
|
||||
|
||||
macro_token = eat_token(macro_token);
|
||||
|
||||
if(update_global_token)
|
||||
global_token = macro_token;
|
||||
}
|
||||
|
||||
void eat_newline_tokens()
|
||||
{
|
||||
macro_token = global_token;
|
||||
|
||||
while(TRUE)
|
||||
{
|
||||
if(NULL == macro_token) return;
|
||||
|
||||
if(match("\n", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
}
|
||||
else
|
||||
{
|
||||
macro_token = macro_token->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the first token inserted; inserts *before* point */
|
||||
struct token_list* insert_tokens(struct token_list* point, struct token_list* token)
|
||||
{
|
||||
struct token_list* copy;
|
||||
struct token_list* first = NULL;
|
||||
|
||||
while (NULL != token)
|
||||
{
|
||||
copy = calloc(1, sizeof(struct token_list));
|
||||
copy->s = token->s;
|
||||
copy->filename = token->filename;
|
||||
copy->linenumber = token->linenumber;
|
||||
|
||||
if(NULL == first)
|
||||
{
|
||||
first = copy;
|
||||
}
|
||||
|
||||
copy->next = point;
|
||||
|
||||
if (NULL != point)
|
||||
{
|
||||
copy->prev = point->prev;
|
||||
|
||||
if(NULL != point->prev)
|
||||
{
|
||||
point->prev->next = copy;
|
||||
}
|
||||
|
||||
point->prev = copy;
|
||||
}
|
||||
|
||||
token = token->next;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
struct macro_list* lookup_macro(struct token_list* token)
|
||||
{
|
||||
if(NULL == token)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("null token received in lookup_macro\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct macro_list* hold = macro_env;
|
||||
|
||||
while (NULL != hold)
|
||||
{
|
||||
if (match(token->s, hold->symbol))
|
||||
{
|
||||
/* found! */
|
||||
return hold;
|
||||
}
|
||||
|
||||
hold = hold->next;
|
||||
}
|
||||
|
||||
/* not found! */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void remove_macro(struct token_list* token)
|
||||
{
|
||||
if(NULL == token)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("received a null in remove_macro\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct macro_list* hold = macro_env;
|
||||
struct macro_list* temp;
|
||||
|
||||
/* Deal with the first element */
|
||||
if (match(token->s, hold->symbol)) {
|
||||
macro_env = hold->next;
|
||||
free(hold);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove element form the middle of linked list */
|
||||
while (NULL != hold->next)
|
||||
{
|
||||
if (match(token->s, hold->next->symbol))
|
||||
{
|
||||
temp = hold->next;
|
||||
hold->next = hold->next->next;
|
||||
free(temp);
|
||||
return;
|
||||
}
|
||||
|
||||
hold = hold->next;
|
||||
}
|
||||
|
||||
/* nothing to undefine */
|
||||
return;
|
||||
}
|
||||
|
||||
int macro_expression();
|
||||
int macro_variable()
|
||||
{
|
||||
int value = 0;
|
||||
struct macro_list* hold = lookup_macro(macro_token);
|
||||
if (NULL != hold)
|
||||
{
|
||||
if(NULL == hold->expansion)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("hold->expansion is a null\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
value = strtoint(hold->expansion->s);
|
||||
}
|
||||
eat_current_token();
|
||||
return value;
|
||||
}
|
||||
|
||||
int macro_number()
|
||||
{
|
||||
int result = strtoint(macro_token->s);
|
||||
eat_current_token();
|
||||
return result;
|
||||
}
|
||||
|
||||
int macro_primary_expr()
|
||||
{
|
||||
int defined_has_paren = FALSE;
|
||||
int hold;
|
||||
require(NULL != macro_token, "got an EOF terminated macro primary expression\n");
|
||||
|
||||
if('-' == macro_token->s[0])
|
||||
{
|
||||
eat_current_token();
|
||||
return -macro_primary_expr();
|
||||
}
|
||||
else if('!' == macro_token->s[0])
|
||||
{
|
||||
eat_current_token();
|
||||
return !macro_primary_expr();
|
||||
}
|
||||
else if('(' == macro_token->s[0])
|
||||
{
|
||||
eat_current_token();
|
||||
hold = macro_expression();
|
||||
require(')' == macro_token->s[0], "missing ) in macro expression\n");
|
||||
eat_current_token();
|
||||
return hold;
|
||||
}
|
||||
else if(match("defined", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
|
||||
require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
|
||||
|
||||
if('(' == macro_token->s[0])
|
||||
{
|
||||
defined_has_paren = TRUE;
|
||||
eat_current_token();
|
||||
}
|
||||
|
||||
if (NULL != lookup_macro(macro_token))
|
||||
{
|
||||
hold = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
hold = FALSE;
|
||||
}
|
||||
eat_current_token();
|
||||
|
||||
if(TRUE == defined_has_paren)
|
||||
{
|
||||
if(NULL == macro_token)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("unterminated define ( statement\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
require(')' == macro_token->s[0], "missing close parenthesis for defined()\n");
|
||||
eat_current_token();
|
||||
}
|
||||
|
||||
return hold;
|
||||
}
|
||||
else if(in_set(macro_token->s[0], "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"))
|
||||
{
|
||||
return macro_variable();
|
||||
}
|
||||
else if(in_set(macro_token->s[0], "0123456789"))
|
||||
{
|
||||
return macro_number();
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0; /* FIXME: error handling */
|
||||
}
|
||||
}
|
||||
|
||||
int macro_additive_expr()
|
||||
{
|
||||
int lhs = macro_primary_expr();
|
||||
int hold;
|
||||
|
||||
require(NULL != macro_token, "got an EOF terminated macro additive expression\n");
|
||||
if(match("+", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs + macro_additive_expr();
|
||||
}
|
||||
else if(match("-", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs - macro_additive_expr();
|
||||
}
|
||||
else if(match("*", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs * macro_additive_expr();
|
||||
}
|
||||
else if(match("/", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
hold = macro_additive_expr();
|
||||
require(0 != hold, "divide by zero not valid even in C macros\n");
|
||||
return lhs / hold;
|
||||
}
|
||||
else if(match("%", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
hold = macro_additive_expr();
|
||||
require(0 != hold, "modulus by zero not valid even in C macros\n");
|
||||
return lhs % hold;
|
||||
}
|
||||
else if(match(">>", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs >> macro_additive_expr();
|
||||
}
|
||||
else if(match("<<", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs << macro_additive_expr();
|
||||
}
|
||||
else
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
int macro_relational_expr()
|
||||
{
|
||||
int lhs = macro_additive_expr();
|
||||
|
||||
if(match("<", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs < macro_relational_expr();
|
||||
}
|
||||
else if(match("<=", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs <= macro_relational_expr();
|
||||
}
|
||||
else if(match(">=", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs >= macro_relational_expr();
|
||||
}
|
||||
else if(match(">", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs > macro_relational_expr();
|
||||
}
|
||||
else if(match("==", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs == macro_relational_expr();
|
||||
}
|
||||
else if(match("!=", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs != macro_relational_expr();
|
||||
}
|
||||
else
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
int macro_bitwise_expr()
|
||||
{
|
||||
int rhs;
|
||||
int lhs = macro_relational_expr();
|
||||
|
||||
if(match("&", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
return lhs & macro_bitwise_expr();
|
||||
}
|
||||
else if(match("&&", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
rhs = macro_bitwise_expr();
|
||||
return lhs && rhs;
|
||||
}
|
||||
else if(match("|", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
rhs = macro_bitwise_expr();
|
||||
return lhs | rhs;
|
||||
}
|
||||
else if(match("||", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
rhs = macro_bitwise_expr();
|
||||
return lhs || rhs;
|
||||
}
|
||||
else if(match("^", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
rhs = macro_bitwise_expr();
|
||||
return lhs ^ rhs;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
int macro_expression()
|
||||
{
|
||||
return macro_bitwise_expr();
|
||||
}
|
||||
|
||||
void handle_define()
|
||||
{
|
||||
struct macro_list* hold;
|
||||
struct token_list* expansion_end = NULL;
|
||||
|
||||
/* don't use #define statements from non-included blocks */
|
||||
int conditional_define = TRUE;
|
||||
if(NULL != conditional_inclusion_top)
|
||||
{
|
||||
if(FALSE == conditional_inclusion_top->include)
|
||||
{
|
||||
conditional_define = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
|
||||
require(NULL != macro_token, "got an EOF terminated #define\n");
|
||||
require('\n' != macro_token->s[0], "unexpected newline after #define\n");
|
||||
|
||||
/* insert new macro */
|
||||
hold = calloc(1, sizeof(struct macro_list));
|
||||
hold->symbol = macro_token->s;
|
||||
hold->next = macro_env;
|
||||
/* provided it isn't in a non-included block */
|
||||
if(conditional_define) macro_env = hold;
|
||||
|
||||
/* discard the macro name */
|
||||
eat_current_token();
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
require(NULL != macro_token, "got an EOF terminated #define\n");
|
||||
|
||||
if ('\n' == macro_token->s[0])
|
||||
{
|
||||
if(NULL == expansion_end)
|
||||
{
|
||||
hold->expansion = NULL;
|
||||
expansion_end = macro_token;
|
||||
return;
|
||||
}
|
||||
expansion_end->next = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
require(NULL != hold, "#define got something it can't handle\n");
|
||||
|
||||
expansion_end = macro_token;
|
||||
|
||||
/* in the first iteration, we set the first token of the expansion, if
|
||||
it exists */
|
||||
if (NULL == hold->expansion)
|
||||
{
|
||||
hold->expansion = macro_token;
|
||||
}
|
||||
|
||||
/* throw away if not used */
|
||||
if(!conditional_define && (NULL != hold))
|
||||
{
|
||||
free(hold);
|
||||
hold = NULL;
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
}
|
||||
}
|
||||
|
||||
void handle_undef()
|
||||
{
|
||||
eat_current_token();
|
||||
remove_macro(macro_token);
|
||||
eat_current_token();
|
||||
}
|
||||
|
||||
void handle_error(int warning_p)
|
||||
{
|
||||
/* don't use #error statements from non-included blocks */
|
||||
int conditional_error = TRUE;
|
||||
if(NULL != conditional_inclusion_top)
|
||||
{
|
||||
if(FALSE == conditional_inclusion_top->include)
|
||||
{
|
||||
conditional_error = FALSE;
|
||||
}
|
||||
}
|
||||
eat_current_token();
|
||||
/* provided it isn't in a non-included block */
|
||||
if(conditional_error)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
if(warning_p) fputs(" warning: #warning ", stderr);
|
||||
else fputs(" error: #error ", stderr);
|
||||
while (TRUE)
|
||||
{
|
||||
require(NULL != macro_token, "\nFailed to properly terminate error message with \\n\n");
|
||||
if ('\n' == macro_token->s[0]) break;
|
||||
fputs(macro_token->s, stderr);
|
||||
macro_token = macro_token->next;
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
fputs("\n", stderr);
|
||||
if(!warning_p) exit(EXIT_FAILURE);
|
||||
}
|
||||
while (TRUE)
|
||||
{
|
||||
require(NULL != macro_token, "\nFailed to properly terminate error message with \\n\n");
|
||||
/* discard the error */
|
||||
if ('\n' == macro_token->s[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
eat_current_token();
|
||||
}
|
||||
}
|
||||
|
||||
void eat_block();
|
||||
void macro_directive()
|
||||
{
|
||||
struct conditional_inclusion *t;
|
||||
int result;
|
||||
|
||||
/* FIXME: whitespace is allowed between "#"" and "if" */
|
||||
if(match("#if", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
/* evaluate constant integer expression */
|
||||
result = macro_expression();
|
||||
/* push conditional inclusion */
|
||||
t = calloc(1, sizeof(struct conditional_inclusion));
|
||||
t->prev = conditional_inclusion_top;
|
||||
conditional_inclusion_top = t;
|
||||
t->include = TRUE;
|
||||
|
||||
if(FALSE == result)
|
||||
{
|
||||
t->include = FALSE;
|
||||
eat_block();
|
||||
}
|
||||
|
||||
t->previous_condition_matched = t->include;
|
||||
}
|
||||
else if(match("#ifdef", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
|
||||
if (NULL != lookup_macro(macro_token))
|
||||
{
|
||||
result = TRUE;
|
||||
eat_current_token();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FALSE;
|
||||
eat_block();
|
||||
}
|
||||
|
||||
/* push conditional inclusion */
|
||||
t = calloc(1, sizeof(struct conditional_inclusion));
|
||||
t->prev = conditional_inclusion_top;
|
||||
conditional_inclusion_top = t;
|
||||
t->include = TRUE;
|
||||
|
||||
if(FALSE == result)
|
||||
{
|
||||
t->include = FALSE;
|
||||
}
|
||||
|
||||
t->previous_condition_matched = t->include;
|
||||
}
|
||||
else if(match("#ifndef", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
require(NULL != macro_token, "got an EOF terminated macro defined expression\n");
|
||||
if (NULL != lookup_macro(macro_token))
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = TRUE;
|
||||
eat_current_token();
|
||||
}
|
||||
|
||||
/* push conditional inclusion */
|
||||
t = calloc(1, sizeof(struct conditional_inclusion));
|
||||
t->prev = conditional_inclusion_top;
|
||||
conditional_inclusion_top = t;
|
||||
t->include = TRUE;
|
||||
|
||||
if(FALSE == result)
|
||||
{
|
||||
t->include = FALSE;
|
||||
eat_block();
|
||||
}
|
||||
|
||||
t->previous_condition_matched = t->include;
|
||||
}
|
||||
else if(match("#elif", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
result = macro_expression();
|
||||
require(NULL != conditional_inclusion_top, "#elif without leading #if\n");
|
||||
conditional_inclusion_top->include = result && !conditional_inclusion_top->previous_condition_matched;
|
||||
conditional_inclusion_top->previous_condition_matched =
|
||||
conditional_inclusion_top->previous_condition_matched || conditional_inclusion_top->include;
|
||||
if(FALSE == result)
|
||||
{
|
||||
eat_block();
|
||||
}
|
||||
}
|
||||
else if(match("#else", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
require(NULL != conditional_inclusion_top, "#else without leading #if\n");
|
||||
conditional_inclusion_top->include = !conditional_inclusion_top->previous_condition_matched;
|
||||
if(FALSE == conditional_inclusion_top->include)
|
||||
{
|
||||
eat_block();
|
||||
}
|
||||
}
|
||||
else if(match("#endif", macro_token->s))
|
||||
{
|
||||
if(NULL == conditional_inclusion_top)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("unexpected #endif\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
/* pop conditional inclusion */
|
||||
t = conditional_inclusion_top;
|
||||
conditional_inclusion_top = conditional_inclusion_top->prev;
|
||||
free(t);
|
||||
}
|
||||
else if(match("#define", macro_token->s))
|
||||
{
|
||||
handle_define();
|
||||
}
|
||||
else if(match("#undef", macro_token->s))
|
||||
{
|
||||
handle_undef();
|
||||
}
|
||||
else if(match("#error", macro_token->s))
|
||||
{
|
||||
handle_error(FALSE);
|
||||
}
|
||||
else if(match("#warning", macro_token->s))
|
||||
{
|
||||
handle_error(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!match("#include", macro_token->s))
|
||||
{
|
||||
/* Put a big fat warning but see if we can just ignore */
|
||||
fputs(">>WARNING<<\n>>WARNING<<\n", stderr);
|
||||
line_error_token(macro_token);
|
||||
fputs("feature: ", stderr);
|
||||
fputs(macro_token->s, stderr);
|
||||
fputs(" unsupported in M2-Planet\nIgnoring line, may result in bugs\n>>WARNING<<\n>>WARNING<<\n\n", stderr);
|
||||
}
|
||||
|
||||
/* unhandled macro directive; let's eat until a newline; om nom nom */
|
||||
while(TRUE)
|
||||
{
|
||||
if(NULL == macro_token)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if('\n' == macro_token->s[0])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void eat_until_endif()
|
||||
{
|
||||
/* This #if block is nested inside of an #if block that needs to be dropped, lose EVERYTHING */
|
||||
do
|
||||
{
|
||||
require(NULL != macro_token, "Unterminated #if block\n");
|
||||
if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
eat_until_endif();
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
require(NULL != macro_token, "Unterminated #if block\n");
|
||||
} while(!match("#endif", macro_token->s));
|
||||
}
|
||||
|
||||
void eat_block()
|
||||
{
|
||||
/* This conditional #if block is wrong, drop everything until the #elif/#else/#endif */
|
||||
do
|
||||
{
|
||||
if(match("#if", macro_token->s) || match("#ifdef", macro_token->s) || match("#ifndef", macro_token->s))
|
||||
{
|
||||
eat_current_token();
|
||||
eat_until_endif();
|
||||
}
|
||||
|
||||
eat_current_token();
|
||||
require(NULL != macro_token, "Unterminated #if block\n");
|
||||
if(match("#elif", macro_token->s)) break;
|
||||
if(match("#else", macro_token->s)) break;
|
||||
if(match("#endif", macro_token->s)) break;
|
||||
} while(TRUE);
|
||||
require(NULL != macro_token->prev, "impossible #if block\n");
|
||||
|
||||
/* rewind the newline */
|
||||
if(match("\n", macro_token->prev->s)) macro_token = macro_token->prev;
|
||||
}
|
||||
|
||||
|
||||
struct token_list* maybe_expand(struct token_list* token)
|
||||
{
|
||||
if(NULL == token)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("maybe_expand passed a null token\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct macro_list* hold = lookup_macro(token);
|
||||
struct token_list* hold2;
|
||||
if(NULL == token->next)
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("we can't expand a null token: ", stderr);
|
||||
fputs(token->s, stderr);
|
||||
fputc('\n', stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (NULL == hold)
|
||||
{
|
||||
return token->next;
|
||||
}
|
||||
|
||||
token = eat_token(token);
|
||||
|
||||
if (NULL == hold->expansion)
|
||||
{
|
||||
return token->next;
|
||||
}
|
||||
hold2 = insert_tokens(token, hold->expansion);
|
||||
|
||||
return hold2->next;
|
||||
}
|
||||
|
||||
void preprocess()
|
||||
{
|
||||
int start_of_line = TRUE;
|
||||
macro_token = global_token;
|
||||
|
||||
while(NULL != macro_token)
|
||||
{
|
||||
if(start_of_line && '#' == macro_token->s[0])
|
||||
{
|
||||
macro_directive();
|
||||
|
||||
if(macro_token)
|
||||
{
|
||||
if('\n' != macro_token->s[0])
|
||||
{
|
||||
line_error_token(macro_token);
|
||||
fputs("newline expected at end of macro directive\n", stderr);
|
||||
fputs("found: '", stderr);
|
||||
fputs(macro_token->s, stderr);
|
||||
fputs("'\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if('\n' == macro_token->s[0])
|
||||
{
|
||||
start_of_line = TRUE;
|
||||
macro_token = macro_token->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
start_of_line = FALSE;
|
||||
if(NULL == conditional_inclusion_top)
|
||||
{
|
||||
macro_token = maybe_expand(macro_token);
|
||||
}
|
||||
else if(!conditional_inclusion_top->include)
|
||||
{
|
||||
/* rewrite the token stream to exclude the current token */
|
||||
eat_block();
|
||||
start_of_line = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
macro_token = maybe_expand(macro_token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
329
cc_reader.c
329
cc_reader.c
|
@ -1,4 +1,5 @@
|
|||
/* Copyright (C) 2016 Jeremiah Orians
|
||||
* Copyright (C) 2021 Andrius Štikonas <andrius@stikonas.eu>
|
||||
* This file is part of M2-Planet.
|
||||
*
|
||||
* M2-Planet is free software: you can redistribute it and/or modify
|
||||
|
@ -17,20 +18,24 @@
|
|||
|
||||
#include "cc.h"
|
||||
|
||||
int strtoint(char *a);
|
||||
|
||||
/* Globals */
|
||||
FILE* input;
|
||||
struct token_list* token;
|
||||
int line;
|
||||
char* file;
|
||||
|
||||
int grab_byte()
|
||||
{
|
||||
int c = fgetc(input);
|
||||
if(10 == c) line = line + 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
int clearWhiteSpace(int c)
|
||||
{
|
||||
if((32 == c) || (9 == c)) return clearWhiteSpace(fgetc(input));
|
||||
else if (10 == c)
|
||||
{
|
||||
line = line + 1;
|
||||
return clearWhiteSpace(fgetc(input));
|
||||
}
|
||||
if((32 == c) || (9 == c)) return clearWhiteSpace(grab_byte());
|
||||
return c;
|
||||
}
|
||||
|
||||
|
@ -38,8 +43,8 @@ int consume_byte(int c)
|
|||
{
|
||||
hold_string[string_index] = c;
|
||||
string_index = string_index + 1;
|
||||
require(MAX_STRING > string_index, "Token exceeded 4096char limit\n");
|
||||
return fgetc(input);
|
||||
require(MAX_STRING > string_index, "Token exceeded MAX_STRING char limit\nuse --max-string number to increase\n");
|
||||
return grab_byte();
|
||||
}
|
||||
|
||||
int preserve_string(int c)
|
||||
|
@ -53,10 +58,23 @@ int preserve_string(int c)
|
|||
c = consume_byte(c);
|
||||
require(EOF != c, "Unterminated string\n");
|
||||
} while(escape || (c != frequent));
|
||||
return fgetc(input);
|
||||
return grab_byte();
|
||||
}
|
||||
|
||||
void fixup_label()
|
||||
|
||||
void copy_string(char* target, char* source, int max)
|
||||
{
|
||||
int i = 0;
|
||||
while(0 != source[i])
|
||||
{
|
||||
target[i] = source[i];
|
||||
i = i + 1;
|
||||
if(i == max) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fixup_label()
|
||||
{
|
||||
int hold = ':';
|
||||
int prev;
|
||||
|
@ -79,30 +97,141 @@ int preserve_keyword(int c, char* S)
|
|||
return c;
|
||||
}
|
||||
|
||||
int purge_macro(int ch)
|
||||
{
|
||||
while(10 != ch)
|
||||
{
|
||||
ch = fgetc(input);
|
||||
require(EOF != ch, "Hit EOF inside macro\n");
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
void reset_hold_string()
|
||||
{
|
||||
int i = string_index + 2;
|
||||
while(0 != i)
|
||||
int i = MAX_STRING;
|
||||
while(0 <= i)
|
||||
{
|
||||
hold_string[i] = 0;
|
||||
i = i - 1;
|
||||
}
|
||||
string_index = 0;
|
||||
}
|
||||
|
||||
/* note if this is the first token in the list, head needs fixing up */
|
||||
struct token_list* eat_token(struct token_list* token)
|
||||
{
|
||||
if(NULL != token->prev)
|
||||
{
|
||||
token->prev->next = token->next;
|
||||
}
|
||||
|
||||
/* update backlinks */
|
||||
if(NULL != token->next)
|
||||
{
|
||||
token->next->prev = token->prev;
|
||||
}
|
||||
|
||||
return token->next;
|
||||
}
|
||||
|
||||
struct token_list* eat_until_newline(struct token_list* head)
|
||||
{
|
||||
while (NULL != head)
|
||||
{
|
||||
if('\n' == head->s[0])
|
||||
{
|
||||
return head;
|
||||
}
|
||||
else
|
||||
{
|
||||
head = eat_token(head);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct token_list* remove_line_comments(struct token_list* head)
|
||||
{
|
||||
struct token_list* first = NULL;
|
||||
|
||||
while (NULL != head)
|
||||
{
|
||||
if(match("//", head->s))
|
||||
{
|
||||
head = eat_until_newline(head);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL == first)
|
||||
{
|
||||
first = head;
|
||||
}
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
struct token_list* remove_line_comment_tokens(struct token_list* head)
|
||||
{
|
||||
struct token_list* first = NULL;
|
||||
|
||||
while (NULL != head)
|
||||
{
|
||||
if(match("//", head->s))
|
||||
{
|
||||
head = eat_token(head);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL == first)
|
||||
{
|
||||
first = head;
|
||||
}
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
struct token_list* remove_preprocessor_directives(struct token_list* head)
|
||||
{
|
||||
struct token_list* first = NULL;
|
||||
|
||||
while (NULL != head)
|
||||
{
|
||||
if('#' == head->s[0])
|
||||
{
|
||||
head = eat_until_newline(head);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL == first)
|
||||
{
|
||||
first = head;
|
||||
}
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
void new_token(char* s, int size)
|
||||
{
|
||||
struct token_list* current = calloc(1, sizeof(struct token_list));
|
||||
require(NULL != current, "Exhausted memory while getting token\n");
|
||||
|
||||
/* More efficiently allocate memory for string */
|
||||
current->s = calloc(size, sizeof(char));
|
||||
require(NULL != current->s, "Exhausted memory while trying to copy a token\n");
|
||||
copy_string(current->s, s, MAX_STRING);
|
||||
|
||||
current->prev = token;
|
||||
current->next = token;
|
||||
current->linenumber = line;
|
||||
current->filename = file;
|
||||
token = current;
|
||||
}
|
||||
|
||||
int get_token(int c)
|
||||
{
|
||||
struct token_list* current = calloc(1, sizeof(struct token_list));
|
||||
require(NULL != current, "Exhusted memory while getting token\n");
|
||||
require(NULL != current, "Exhausted memory while getting token\n");
|
||||
|
||||
reset:
|
||||
reset_hold_string();
|
||||
|
@ -116,8 +245,8 @@ reset:
|
|||
}
|
||||
else if('#' == c)
|
||||
{
|
||||
c = purge_macro(c);
|
||||
goto reset;
|
||||
c = consume_byte(c);
|
||||
c = preserve_keyword(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
}
|
||||
else if(in_set(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"))
|
||||
{
|
||||
|
@ -128,9 +257,9 @@ reset:
|
|||
c = ' ';
|
||||
}
|
||||
}
|
||||
else if(in_set(c, "<=>|&!-"))
|
||||
else if(in_set(c, "<=>|&!^%"))
|
||||
{
|
||||
c = preserve_keyword(c, "<=>|&!-");
|
||||
c = preserve_keyword(c, "<=>|&!^%");
|
||||
}
|
||||
else if(in_set(c, "'\""))
|
||||
{
|
||||
|
@ -141,26 +270,67 @@ reset:
|
|||
c = consume_byte(c);
|
||||
if(c == '*')
|
||||
{
|
||||
c = fgetc(input);
|
||||
c = grab_byte();
|
||||
while(c != '/')
|
||||
{
|
||||
while(c != '*')
|
||||
{
|
||||
c = fgetc(input);
|
||||
c = grab_byte();
|
||||
require(EOF != c, "Hit EOF inside of block comment\n");
|
||||
if('\n' == c) line = line + 1;
|
||||
}
|
||||
c = fgetc(input);
|
||||
c = grab_byte();
|
||||
require(EOF != c, "Hit EOF inside of block comment\n");
|
||||
if('\n' == c) line = line + 1;
|
||||
}
|
||||
c = fgetc(input);
|
||||
c = grab_byte();
|
||||
goto reset;
|
||||
}
|
||||
else if(c == '/')
|
||||
{
|
||||
c = fgetc(input);
|
||||
goto reset;
|
||||
c = consume_byte(c);
|
||||
}
|
||||
else if(c == '=')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
else if(c == '*')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
if(c == '=')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
}
|
||||
else if(c == '+')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
if(c == '=')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
if(c == '+')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
}
|
||||
else if(c == '-')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
if(c == '=')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
if(c == '>')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
if(c == '-')
|
||||
{
|
||||
c = consume_byte(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -168,25 +338,83 @@ reset:
|
|||
c = consume_byte(c);
|
||||
}
|
||||
|
||||
/* More efficiently allocate memory for string */
|
||||
current->s = calloc(string_index + 2, sizeof(char));
|
||||
require(NULL != current->s, "Exhusted memory while trying to copy a token\n");
|
||||
copy_string(current->s, hold_string);
|
||||
|
||||
current->prev = token;
|
||||
current->next = token;
|
||||
current->linenumber = line;
|
||||
current->filename = file;
|
||||
token = current;
|
||||
new_token(hold_string, string_index + 2);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int consume_filename(int c)
|
||||
{
|
||||
reset_hold_string();
|
||||
int done = FALSE;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
if(c == EOF)
|
||||
{
|
||||
fputs("we don't support EOF as a filename in #FILENAME statements\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else if((32 == c) || (9 == c) || (c == '\n'))
|
||||
{
|
||||
c = grab_byte();
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
c = consume_byte(c);
|
||||
require(EOF != c, "Unterminated filename in #FILENAME\n");
|
||||
} while((32 != c) && (9 != c) && ('\n' != c));
|
||||
done = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* with just a little extra to put in the matching at the end */
|
||||
new_token(hold_string, string_index + 3);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
int change_filename(int ch)
|
||||
{
|
||||
require(EOF != ch, "#FILENAME failed to receive filename\n");
|
||||
/* Remove the #FILENAME */
|
||||
token = token->next;
|
||||
|
||||
/* Get new filename */
|
||||
ch = consume_filename(ch);
|
||||
file = token->s;
|
||||
/* Remove it from the processing list */
|
||||
token = token->next;
|
||||
require(EOF != ch, "#FILENAME failed to receive filename\n");
|
||||
|
||||
/* Get new line number */
|
||||
ch = get_token(ch);
|
||||
line = strtoint(token->s);
|
||||
if(0 == line)
|
||||
{
|
||||
if('0' != token->s[0])
|
||||
{
|
||||
fputs("non-line number: ", stderr);
|
||||
fputs(token->s, stderr);
|
||||
fputs(" provided to #FILENAME\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
/* Remove it from the processing list */
|
||||
token = token->next;
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
struct token_list* reverse_list(struct token_list* head)
|
||||
{
|
||||
struct token_list* root = NULL;
|
||||
struct token_list* next;
|
||||
while(NULL != head)
|
||||
{
|
||||
struct token_list* next = head->next;
|
||||
next = head->next;
|
||||
head->next = root;
|
||||
root = head;
|
||||
head = next;
|
||||
|
@ -200,8 +428,13 @@ struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* fi
|
|||
line = 1;
|
||||
file = filename;
|
||||
token = current;
|
||||
int ch =fgetc(input);
|
||||
while(EOF != ch) ch = get_token(ch);
|
||||
int ch = grab_byte();
|
||||
while(EOF != ch)
|
||||
{
|
||||
ch = get_token(ch);
|
||||
require(NULL != token, "Empty files don't need to be compiled\n");
|
||||
if(match("#FILENAME", token->s)) ch = change_filename(ch);
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
|
28
cc_strings.c
28
cc_strings.c
|
@ -19,7 +19,6 @@
|
|||
#include "cc.h"
|
||||
#include <stdint.h>
|
||||
|
||||
int char2hex(int c);
|
||||
struct token_list* emit(char *s, struct token_list* head);
|
||||
void require(int bool, char* error);
|
||||
|
||||
|
@ -33,13 +32,22 @@ char upcase(char a)
|
|||
return a;
|
||||
}
|
||||
|
||||
|
||||
int char2hex(int c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (c - 48);
|
||||
else if (c >= 'a' && c <= 'f') return (c - 87);
|
||||
else if (c >= 'A' && c <= 'F') return (c - 55);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int hexify(int c, int high)
|
||||
{
|
||||
int i = char2hex(c);
|
||||
|
||||
if(0 > i)
|
||||
{
|
||||
file_print("Tried to print non-hex number\n", stderr);
|
||||
fputs("Tried to print non-hex number\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -95,9 +103,9 @@ int escape_lookup(char* c)
|
|||
else if(c[1] == '\'') return 39;
|
||||
else if(c[1] == '\\') return 92;
|
||||
|
||||
file_print("Unknown escape received: ", stderr);
|
||||
file_print(c, stderr);
|
||||
file_print(" Unable to process\n", stderr);
|
||||
fputs("Unknown escape received: ", stderr);
|
||||
fputs(c, stderr);
|
||||
fputs(" Unable to process\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -126,8 +134,8 @@ collect_regular_string_reset:
|
|||
hold_string[string_index] = '"';
|
||||
hold_string[string_index + 1] = '\n';
|
||||
char* message = calloc(string_index + 3, sizeof(char));
|
||||
require(NULL != message, "Exhusted memory while storing regular string\n");
|
||||
copy_string(message, hold_string);
|
||||
require(NULL != message, "Exhausted memory while storing regular string\n");
|
||||
copy_string(message, hold_string, string_index + 2);
|
||||
reset_hold_string();
|
||||
return message;
|
||||
}
|
||||
|
@ -144,7 +152,7 @@ collect_weird_string_reset:
|
|||
require((MAX_STRING - 6) > string_index, "Attempt at parsing weird string exceeds max length\n");
|
||||
string = string + 1;
|
||||
hold_string[string_index] = ' ';
|
||||
temp = escape_lookup(string);
|
||||
temp = escape_lookup(string) & 0xFF;
|
||||
hold_string[string_index + 1] = table[(temp >> 4)];
|
||||
hold_string[string_index + 2] = table[(temp & 15)];
|
||||
|
||||
|
@ -164,8 +172,8 @@ collect_weird_string_reset:
|
|||
hold_string[string_index + 4] = '\n';
|
||||
|
||||
char* hold = calloc(string_index + 6, sizeof(char));
|
||||
require(NULL != hold, "Exhusted available memory while attempting to collect a weird string\n");
|
||||
copy_string(hold, hold_string);
|
||||
require(NULL != hold, "Exhausted available memory while attempting to collect a weird string\n");
|
||||
copy_string(hold, hold_string, string_index + 5);
|
||||
reset_hold_string();
|
||||
return hold;
|
||||
}
|
||||
|
|
287
cc_types.c
287
cc_types.c
|
@ -15,145 +15,132 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "cc.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Imported functions */
|
||||
int numerate_string(char *a);
|
||||
int strtoint(char *a);
|
||||
void line_error();
|
||||
void require(int bool, char* error);
|
||||
|
||||
/* enable easy primitive extension */
|
||||
struct type* add_primitive(struct type* a)
|
||||
{
|
||||
if(NULL == prim_types) return a;
|
||||
struct type* i = prim_types;
|
||||
while(NULL != i->next)
|
||||
{
|
||||
i = i->next;
|
||||
}
|
||||
i->next = a;
|
||||
|
||||
return prim_types;
|
||||
}
|
||||
|
||||
/* enable easy primitive creation */
|
||||
struct type* new_primitive(char* name0, char* name1, char* name2, int size, int sign)
|
||||
{
|
||||
/* Create type** */
|
||||
struct type* a = calloc(1, sizeof(struct type));
|
||||
require(NULL != a, "Exhausted memory while declaring new primitive**\n");
|
||||
a->name = name2;
|
||||
a->size = register_size;
|
||||
a->indirect = a;
|
||||
a->is_signed = sign;
|
||||
|
||||
/* Create type* */
|
||||
struct type* b = calloc(1, sizeof(struct type));
|
||||
require(NULL != b, "Exhausted memory while declaring new primitive*\n");
|
||||
b->name = name1;
|
||||
b->size = register_size;
|
||||
b->is_signed = sign;
|
||||
b->indirect = a;
|
||||
a->type = b;
|
||||
|
||||
struct type* r = calloc(1, sizeof(struct type));
|
||||
require(NULL != r, "Exhausted memory while declaring new primitive\n");
|
||||
r->name = name0;
|
||||
r->size = size;
|
||||
r->is_signed = sign;
|
||||
r->indirect = b;
|
||||
r->type = r;
|
||||
b->type = r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Initialize default types */
|
||||
void initialize_types()
|
||||
{
|
||||
if(AMD64 == Architecture || AARCH64 == Architecture) register_size = 8;
|
||||
if(AMD64 == Architecture || AARCH64 == Architecture || RISCV64 == Architecture) register_size = 8;
|
||||
else register_size = 4;
|
||||
|
||||
/* Define void */
|
||||
global_types = calloc(1, sizeof(struct type));
|
||||
require(NULL != global_types, "Exhusted memory while intializing VOID\n");
|
||||
global_types->name = "void";
|
||||
global_types->is_signed = FALSE;
|
||||
global_types->size = register_size;
|
||||
global_types->type = global_types;
|
||||
/* void* has the same properties as void */
|
||||
global_types->indirect = global_types;
|
||||
struct type* hold = new_primitive("void", "void*", "void**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define unsigned LONG */
|
||||
struct type* a = calloc(1, sizeof(struct type));
|
||||
require(NULL != a, "Exhusted memory while intializing SCM\n");
|
||||
a->name = "SCM";
|
||||
a->is_signed = FALSE;
|
||||
a->size = register_size;
|
||||
a->indirect = a;
|
||||
a->type = a;
|
||||
hold = new_primitive("SCM","SCM*", "SCM**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define LONG */
|
||||
struct type* b = calloc(1, sizeof(struct type));
|
||||
require(NULL != b, "Exhusted memory while intializing LONG\n");
|
||||
b->name = "long";
|
||||
b->is_signed = TRUE;
|
||||
b->size = register_size;
|
||||
b->indirect = b;
|
||||
b->type = b;
|
||||
hold = new_primitive("long", "long*", "long**", register_size, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define UNSIGNED */
|
||||
struct type* c = calloc(1, sizeof(struct type));
|
||||
require(NULL != c, "Exhusted memory while intializing UNSIGNE\n");
|
||||
c->name = "unsigned";
|
||||
c->is_signed = FALSE;
|
||||
c->size = register_size;
|
||||
c->type = c;
|
||||
/* unsigned* has the same properties as unsigned */
|
||||
c->indirect = c;
|
||||
hold = new_primitive("unsigned", "unsigned*", "unsigned**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define int */
|
||||
struct type* d = calloc(1, sizeof(struct type));
|
||||
require(NULL != d, "Exhusted memory while intializing INT\n");
|
||||
d->name = "int";
|
||||
d->is_signed = TRUE;
|
||||
d->size = register_size;
|
||||
/* int* has the same properties as int */
|
||||
d->indirect = d;
|
||||
d->type = d;
|
||||
integer = new_primitive("int", "int*", "int**", register_size, TRUE);
|
||||
prim_types = add_primitive(integer);
|
||||
|
||||
/* Define char* */
|
||||
struct type* e = calloc(1, sizeof(struct type));
|
||||
require(NULL != e, "Exhusted memory while intializing CHAR*\n");
|
||||
e->name = "char*";
|
||||
e->is_signed = FALSE;
|
||||
e->size = register_size;
|
||||
e->type = e;
|
||||
/* Define uint32_t */
|
||||
hold = new_primitive("uint32_t", "uint32_t*", "uint32_t**", 4, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define int32_t */
|
||||
hold = new_primitive("int32_t", "int32_t*", "int32_t**", 4, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define uint16_t */
|
||||
hold = new_primitive("uint16_t", "uint16_t*", "uint16_t**", 2, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define int16_t */
|
||||
hold = new_primitive("int16_t", "int16_t*", "int16_t**", 2, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define uint8_t */
|
||||
hold = new_primitive("uint8_t", "uint8_t*", "uint8_t**", 1, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define int8_t */
|
||||
hold = new_primitive("int8_t", "int8_t*", "int8_t**", 1, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define char */
|
||||
struct type* f = calloc(1, sizeof(struct type));
|
||||
require(NULL != f, "Exhusted memory while intializing CHAR\n");
|
||||
f->name = "char";
|
||||
f->is_signed = FALSE;
|
||||
f->size = 1;
|
||||
f->type = f;
|
||||
|
||||
/* Define char** */
|
||||
struct type* g = calloc(1, sizeof(struct type));
|
||||
require(NULL != g, "Exhusted memory while intializing CHAR**\n");
|
||||
g->name = "char**";
|
||||
g->is_signed = FALSE;
|
||||
g->size = register_size;
|
||||
g->type = e;
|
||||
g->indirect = g;
|
||||
|
||||
/*fix up indirects for chars */
|
||||
f->indirect = e;
|
||||
e->indirect = g;
|
||||
|
||||
/* Define FILE */
|
||||
struct type* h = calloc(1, sizeof(struct type));
|
||||
require(NULL != h, "Exhusted memory while intializing FILE\n");
|
||||
h->name = "FILE";
|
||||
h->is_signed = FALSE;
|
||||
h->size = register_size;
|
||||
h->type = h;
|
||||
/* FILE* has the same properties as FILE */
|
||||
h->indirect = h;
|
||||
hold = new_primitive("char", "char*", "char**", 1, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Define FUNCTION */
|
||||
struct type* i = calloc(1, sizeof(struct type));
|
||||
require(NULL != i, "Exhusted memory while intializing FUNCTION\n");
|
||||
i->name = "FUNCTION";
|
||||
i->is_signed = FALSE;
|
||||
i->size = register_size;
|
||||
i->type = i;
|
||||
/* FUNCTION* has the same properties as FUNCTION */
|
||||
i->indirect = i;
|
||||
hold = new_primitive("FUNCTION", "FUNCTION*", "FUNCTION**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Primitives mes.c wanted */
|
||||
struct type* j = calloc(1, sizeof(struct type));
|
||||
require(NULL != j, "Exhusted memory while intializing SIZE_T\n");
|
||||
j->name = "size_t";
|
||||
j->is_signed = FALSE;
|
||||
j->size = register_size;
|
||||
j->indirect = j;
|
||||
if(BOOTSTRAP_MODE)
|
||||
{
|
||||
/* Define FILE */
|
||||
hold = new_primitive("FILE", "FILE*", "FILE**", register_size, TRUE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
struct type* k = calloc(1, sizeof(struct type));
|
||||
require(NULL != k, "Exhusted memory while intializing SSIZE_T\n");
|
||||
k->name = "ssize_t";
|
||||
k->is_signed = FALSE;
|
||||
k->size = register_size;
|
||||
k->indirect = k;
|
||||
/* Primitives mes.c wanted */
|
||||
hold = new_primitive("size_t", "size_t*", "size_t**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
|
||||
/* Finalize type list */
|
||||
j->next = k;
|
||||
i->next = j;
|
||||
h->next = i;
|
||||
g->next = h;
|
||||
f->next = g;
|
||||
d->next = f;
|
||||
c->next = d;
|
||||
b->next = c;
|
||||
a->next = b;
|
||||
global_types->next = a;
|
||||
prim_types = global_types;
|
||||
hold = new_primitive("ssize_t", "ssize_t*", "ssize_t**", register_size, FALSE);
|
||||
prim_types = add_primitive(hold);
|
||||
}
|
||||
|
||||
global_types = prim_types;
|
||||
}
|
||||
|
||||
struct type* lookup_type(char* s, struct type* start)
|
||||
|
@ -178,13 +165,13 @@ struct type* lookup_member(struct type* parent, char* name)
|
|||
if(match(i->name, name)) return i;
|
||||
}
|
||||
|
||||
file_print("ERROR in lookup_member ", stderr);
|
||||
file_print(parent->name, stderr);
|
||||
file_print("->", stderr);
|
||||
file_print(global_token->s, stderr);
|
||||
file_print(" does not exist\n", stderr);
|
||||
fputs("ERROR in lookup_member ", stderr);
|
||||
fputs(parent->name, stderr);
|
||||
fputs("->", stderr);
|
||||
fputs(global_token->s, stderr);
|
||||
fputs(" does not exist\n", stderr);
|
||||
line_error();
|
||||
file_print("\n", stderr);
|
||||
fputs("\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -195,7 +182,7 @@ int member_size;
|
|||
struct type* build_member(struct type* last, int offset)
|
||||
{
|
||||
struct type* i = calloc(1, sizeof(struct type));
|
||||
require(NULL != i, "Exhusted memory while building a struct member\n");
|
||||
require(NULL != i, "Exhausted memory while building a struct member\n");
|
||||
i->members = last;
|
||||
i->offset = offset;
|
||||
|
||||
|
@ -211,10 +198,10 @@ struct type* build_member(struct type* last, int offset)
|
|||
{
|
||||
global_token = global_token->next;
|
||||
require(NULL != global_token, "struct member arrays can not be EOF sized\n");
|
||||
i->size = member_type->type->size * numerate_string(global_token->s);
|
||||
i->size = member_type->type->size * strtoint(global_token->s);
|
||||
if(0 == i->size)
|
||||
{
|
||||
file_print("Struct only supports [num] form\n", stderr);
|
||||
fputs("Struct only supports [num] form\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
global_token = global_token->next;
|
||||
|
@ -254,21 +241,28 @@ void create_struct()
|
|||
int offset = 0;
|
||||
member_size = 0;
|
||||
struct type* head = calloc(1, sizeof(struct type));
|
||||
require(NULL != head, "Exhusted memory while creating a struct\n");
|
||||
require(NULL != head, "Exhausted memory while creating a struct\n");
|
||||
struct type* i = calloc(1, sizeof(struct type));
|
||||
require(NULL != i, "Exhusted memory while creating a struct indirection\n");
|
||||
require(NULL != i, "Exhausted memory while creating a struct indirection\n");
|
||||
struct type* ii = calloc(1, sizeof(struct type));
|
||||
require(NULL != ii, "Exhausted memory while creating a struct double indirection\n");
|
||||
head->name = global_token->s;
|
||||
head->type = head;
|
||||
i->name = global_token->s;
|
||||
i->type = i;
|
||||
head->indirect = i;
|
||||
i->indirect = head;
|
||||
head->next = global_types;
|
||||
i->name = global_token->s;
|
||||
i->type = head;
|
||||
i->indirect = ii;
|
||||
i->size = register_size;
|
||||
ii->name = global_token->s;
|
||||
ii->type = i;
|
||||
ii->indirect = ii;
|
||||
ii->size = register_size;
|
||||
global_types = head;
|
||||
global_token = global_token->next;
|
||||
i->size = register_size;
|
||||
require_match("ERROR in create_struct\n Missing {\n", "{");
|
||||
struct type* last = NULL;
|
||||
require(NULL != global_token, "Incomplete struct definition at end of file\n");
|
||||
while('}' != global_token->s[0])
|
||||
{
|
||||
if(match(global_token->s, "union"))
|
||||
|
@ -297,7 +291,14 @@ struct type* type_name()
|
|||
{
|
||||
struct type* ret;
|
||||
|
||||
require(NULL != global_token, "Recieved EOF instead of type name\n");
|
||||
require(NULL != global_token, "Received EOF instead of type name\n");
|
||||
|
||||
if(match("extern", global_token->s))
|
||||
{
|
||||
global_token = global_token->next;
|
||||
require(NULL != global_token, "unfinished type definition in extern\n");
|
||||
}
|
||||
|
||||
if(match("struct", global_token->s))
|
||||
{
|
||||
global_token = global_token->next;
|
||||
|
@ -314,10 +315,11 @@ struct type* type_name()
|
|||
ret = lookup_type(global_token->s, global_types);
|
||||
if(NULL == ret)
|
||||
{
|
||||
file_print("Unknown type ", stderr);
|
||||
file_print(global_token->s, stderr);
|
||||
file_print("\n", stderr);
|
||||
fputs("Unknown type ", stderr);
|
||||
fputs(global_token->s, stderr);
|
||||
fputs("\n", stderr);
|
||||
line_error();
|
||||
fputs("\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
@ -340,3 +342,28 @@ struct type* type_name()
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct type* mirror_type(struct type* source, char* name)
|
||||
{
|
||||
struct type* head = calloc(1, sizeof(struct type));
|
||||
require(NULL != head, "Exhausted memory while creating a struct\n");
|
||||
struct type* i = calloc(1, sizeof(struct type));
|
||||
require(NULL != i, "Exhausted memory while creating a struct indirection\n");
|
||||
|
||||
head->name = name;
|
||||
i->name = name;
|
||||
head->size = source->size;
|
||||
i->size = source->indirect->size;
|
||||
head->offset = source->offset;
|
||||
i->offset = source->indirect->offset;
|
||||
head->is_signed = source->is_signed;
|
||||
i->is_signed = source->indirect->is_signed;
|
||||
head->indirect = i;
|
||||
i->indirect = head;
|
||||
head->members = source->members;
|
||||
i->members = source->indirect->members;
|
||||
head->type = head;
|
||||
i->type = i;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
|
|
@ -20,29 +20,32 @@ to make a more powerful C compiler. (with a few extras for convience)
|
|||
Those core primitives being: if (with continue), while (with
|
||||
break), asm, structs (with -> support) gotos (with labels) and return.
|
||||
|
||||
With do and for loops, arrays and function pointers as nice extras
|
||||
With do and for loops, arrays, function pointers and simple macro support
|
||||
as nice extras
|
||||
.br
|
||||
The supported ARCHITECTURES are as follows: knight-native,
|
||||
knight-posix, x86, amd64, armv7l, aarch64.
|
||||
knight-posix, x86, amd64, armv7l, aarch64 and riscv64.
|
||||
|
||||
Unofficially all tested armv7l binaries have also worked on armv6l
|
||||
hosts that have thus far been tested but no promise of compatibilty
|
||||
until someone is willing to put in the work.
|
||||
|
||||
(with planned ports to z80 and 6502)
|
||||
If you fail to specify an architecture, the default of knight-native
|
||||
will be used.
|
||||
|
||||
The option --bootstrap-mode exists purely for testing C code for cc_*
|
||||
compatibility
|
||||
|
||||
.br
|
||||
|
||||
As M2-Planet's libc is literally only a half-dozen lines of assembly
|
||||
you will likely need to import libc primitives when building or
|
||||
having previously built them seperately.
|
||||
The minimal libc required to work with M2-Planet generated output is
|
||||
literally only a half-dozen lines of assembly and to simplify use
|
||||
M2libc (https://github.com/oriansj/M2libc.git) was created with the
|
||||
goal of providing commonly desired C library functionality.
|
||||
|
||||
You can find examples for such primitives in:
|
||||
test/common_x86/functions/
|
||||
test/common_amd64/functions/
|
||||
test/common_armv7l/functions/
|
||||
test/common_aarch64/functions/
|
||||
test/common_knight/functions/
|
||||
|
||||
with the default libc implementations and elf-headers in the
|
||||
parent directories correspondingly.
|
||||
with architecture specific elf-headers and functions in the
|
||||
directories matching the architecture name.
|
||||
|
||||
.br
|
||||
|
||||
|
@ -60,12 +63,12 @@ with blood-elf generating dwarf stubs if additional debug info is
|
|||
desired.
|
||||
.br
|
||||
|
||||
# M1 -f test/common_x86/x86_defs.M1 -f test/common_x86/libc-core.M1 \
|
||||
-f return.M1 --LittleEndian --architecture x86 -o return.hex2
|
||||
# M1 -f M2libc/x86/x86_defs.M1 -f M2libc/x86/libc-full.M1 \
|
||||
-f return.M1 --little-endian --architecture x86 -o return.hex2
|
||||
|
||||
|
||||
# hex2 -f test/common_x86/ELF-i386.hex2 -f return.hex2 --LittleEndian \
|
||||
--architecture x86 --BaseAddress 0x8048000 -o example --exec_enable
|
||||
# hex2 -f M2libc/x86/ELF-x86.hex2 -f return.hex2 --little-endian \
|
||||
--architecture x86 --base-address 0x8048000 -o example
|
||||
.br
|
||||
|
||||
.SH COMPATIBILITY
|
||||
|
@ -77,12 +80,20 @@ even the ones that try to be Turing complete -1
|
|||
Jeremiah Orians <Jeremiah@pdp10.guru>
|
||||
.br
|
||||
Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||
.br
|
||||
deesix <deesix@tuta.io>
|
||||
.br
|
||||
Sanne Wouda <sanne.wouda@gmail.com>
|
||||
|
||||
.SH COPYRIGHT
|
||||
Copyright 2016-2019 Jeremiah Orians <Jeremiah@pdp10.guru>
|
||||
Copyright 2016-2021 Jeremiah Orians <Jeremiah@pdp10.guru>
|
||||
.br
|
||||
Copyright 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
.br
|
||||
Copyright 2020-2021 deesix <deesix@tuta.io>
|
||||
.br
|
||||
Copyright 2020-2021 Sanne Wouda <sanne.wouda@gmail.com>
|
||||
.br
|
||||
License GPLv3+.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
// void* malloc(int size);
|
||||
|
||||
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;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include<stdio.h>
|
||||
// void fputc(char s, FILE* f);
|
||||
|
||||
void file_print(char* s, FILE* f)
|
||||
{
|
||||
while(0 != s[0])
|
||||
{
|
||||
fputc(s[0], f);
|
||||
s = s + 1;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define FALSE 0
|
||||
// CONSTANT FALSE 0
|
||||
#define TRUE 1
|
||||
// CONSTANT TRUE 1
|
||||
|
||||
int match(char* a, char* b)
|
||||
{
|
||||
int i = -1;
|
||||
do
|
||||
{
|
||||
i = i + 1;
|
||||
if(a[i] != b[i])
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
} while((0 != a[i]) && (0 !=b[i]));
|
||||
return TRUE;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include<stdio.h>
|
||||
// void* calloc(int count, int size);
|
||||
int hex2char(int c);
|
||||
void file_print(char* s, FILE* f);
|
||||
void require(int bool, char* error);
|
||||
|
||||
char* number_to_hex(int a, int bytes)
|
||||
{
|
||||
require(bytes > 0, "number to hex must have a positive number of bytes greater than zero\n");
|
||||
char* result = calloc(1 + (bytes << 1), sizeof(char));
|
||||
if(NULL == result)
|
||||
{
|
||||
file_print("calloc failed in number_to_hex\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int i = 0;
|
||||
|
||||
int divisor = (bytes << 3);
|
||||
require(divisor > 0, "unexpected wrap around in number_to_hex\n");
|
||||
|
||||
/* Simply collect numbers until divisor is gone */
|
||||
while(0 != divisor)
|
||||
{
|
||||
divisor = divisor - 4;
|
||||
result[i] = hex2char((a >> divisor) & 0xF);
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include<stdio.h>
|
||||
// void* calloc(int count, int size);
|
||||
#define TRUE 1
|
||||
//CONSTANT TRUE 1
|
||||
#define FALSE 0
|
||||
//CONSTANT FALSE 0
|
||||
int in_set(int c, char* s);
|
||||
void file_print(char* s, FILE* f);
|
||||
|
||||
|
||||
char* numerate_number(int a)
|
||||
{
|
||||
char* result = calloc(16, sizeof(char));
|
||||
if(NULL == result)
|
||||
{
|
||||
file_print("calloc failed in prepend_char\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
int i = 0;
|
||||
|
||||
/* Deal with Zero case */
|
||||
if(0 == a)
|
||||
{
|
||||
result[0] = '0';
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Deal with negatives */
|
||||
if(0 > a)
|
||||
{
|
||||
result[0] = '-';
|
||||
i = 1;
|
||||
a = a * -1;
|
||||
}
|
||||
|
||||
/* Using the largest 10^n number possible in 32bits */
|
||||
int divisor = 0x3B9ACA00;
|
||||
/* Skip leading Zeros */
|
||||
while(0 == (a / divisor)) divisor = divisor / 10;
|
||||
|
||||
/* Now simply collect numbers until divisor is gone */
|
||||
while(0 < divisor)
|
||||
{
|
||||
result[i] = ((a / divisor) + 48);
|
||||
a = a % divisor;
|
||||
divisor = divisor / 10;
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int char2hex(int c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (c - 48);
|
||||
else if (c >= 'a' && c <= 'f') return (c - 87);
|
||||
else if (c >= 'A' && c <= 'F') return (c - 55);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
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 char2dec(int c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return (c - 48);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
int dec2char(int c)
|
||||
{
|
||||
if((c >= 0) && (c <= 9)) return (c + 48);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int toupper(int c)
|
||||
{
|
||||
if(in_set(c, "abcdefghijklmnopqrstuvwxyz")) return (c & 0xDF);
|
||||
return c;
|
||||
}
|
||||
|
||||
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 numerate_string(char *a)
|
||||
{
|
||||
/* If NULL string */
|
||||
if(0 == a[0])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* Deal with binary*/
|
||||
else if ('0' == a[0] && 'b' == a[1])
|
||||
{
|
||||
return set_reader("01", 2, a+2);
|
||||
}
|
||||
/* Deal with hex */
|
||||
else if ('0' == a[0] && 'x' == a[1])
|
||||
{
|
||||
return set_reader("0123456789ABCDEFabcdef", 16, a+2);
|
||||
}
|
||||
/* Deal with octal */
|
||||
else if('0' == a[0])
|
||||
{
|
||||
return set_reader("01234567", 8, a+1);
|
||||
}
|
||||
/* Deal with decimal */
|
||||
else
|
||||
{
|
||||
return set_reader("0123456789", 10, a);
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#define MAX_STRING 4096
|
||||
//CONSTANT MAX_STRING 4096
|
||||
// void* calloc(int count, int size);
|
||||
void file_print(char* s, FILE* f);
|
||||
|
||||
char* copy_string(char* target, char* source)
|
||||
{
|
||||
while(0 != source[0])
|
||||
{
|
||||
target[0] = source[0];
|
||||
target = target + 1;
|
||||
source = source + 1;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
char* postpend_char(char* s, char a)
|
||||
{
|
||||
char* ret = calloc(MAX_STRING, sizeof(char));
|
||||
if(NULL == ret)
|
||||
{
|
||||
file_print("calloc failed in postpend_char\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
char* hold = copy_string(ret, s);
|
||||
hold[0] = a;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* prepend_char(char a, char* s)
|
||||
{
|
||||
char* ret = calloc(MAX_STRING, sizeof(char));
|
||||
if(NULL == ret)
|
||||
{
|
||||
file_print("calloc failed in prepend_char\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ret[0] = a;
|
||||
copy_string((ret+1), s);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* prepend_string(char* add, char* base)
|
||||
{
|
||||
char* ret = calloc(MAX_STRING, sizeof(char));
|
||||
if(NULL == ret)
|
||||
{
|
||||
file_print("calloc failed in prepend_string\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
copy_string(copy_string(ret, add), base);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int string_length(char* a)
|
||||
{
|
||||
int i = 0;
|
||||
while(0 != a[i]) i = i + 1;
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
M2-Planet is subset of the C programming language.
|
||||
|
||||
Mostly by eliminating features that have yet to be proven useful in building compilers, linkers or assemblers.
|
||||
|
||||
* AMD64 & AArch64 int initialization wrong
|
||||
right now the code in cc_core.c in the function void program() simply doesn't output the correct output for AArch64 or AMD64.
|
||||
As the function should numerate the string global_token to determine if the leading 32bits should be 0 or 0xFFFFFFFF and output %0 or %0xFFFFFFFF accordingly.
|
||||
|
||||
** example of failing code
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#include<string.h>
|
||||
|
||||
void write_string(char* s, FILE* f)
|
||||
{
|
||||
while(0 != s[0])
|
||||
{
|
||||
fputc(s[0], f);
|
||||
s = s + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void* empty = 0;
|
||||
|
||||
int main()
|
||||
{
|
||||
if (0 == empty)
|
||||
{
|
||||
write_string("Yes, is empty\n", stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
write_string("Oops, why not?\n", stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
* Pointer arithmetic wrong
|
||||
It isn't uncommon for complex C programs to iterate over an array using a pointer.
|
||||
|
||||
** example of failing code
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void walk_array(char** array, char** array_end)
|
||||
{
|
||||
char** i = array;
|
||||
while(i < array_end)
|
||||
{
|
||||
fputs(i[0], stdout);
|
||||
fputc('\n', stdout);
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char** array = calloc(10, sizeof(char*));
|
||||
array[0] = "hello";
|
||||
array[1] = "world";
|
||||
array[2] = "how";
|
||||
array[3] = "are";
|
||||
array[4] = "you";
|
||||
array[5] = "today";
|
||||
array[6] = "I";
|
||||
array[7] = "am";
|
||||
array[8] = "doing";
|
||||
array[9] = "fine";
|
||||
walk_array(array, array + 10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
** work around code
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__M2__)
|
||||
#define pointer_size sizeof(char*)
|
||||
#else
|
||||
#define pointer_size 1
|
||||
#endif
|
||||
|
||||
void walk_array(char** array, char** array_end)
|
||||
{
|
||||
char** i = array;
|
||||
while(i < array_end)
|
||||
{
|
||||
fputs(i[0], stdout);
|
||||
fputc('\n', stdout);
|
||||
i = i + pointer_size;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char** array = calloc(10, sizeof(char*));
|
||||
array[0] = "hello";
|
||||
array[1] = "world";
|
||||
array[2] = "how";
|
||||
array[3] = "are";
|
||||
array[4] = "you";
|
||||
array[5] = "today";
|
||||
array[6] = "I";
|
||||
array[7] = "am";
|
||||
array[8] = "doing";
|
||||
array[9] = "fine";
|
||||
walk_array(array, array + (10 * pointer_size));
|
||||
return 0;
|
||||
}
|
||||
|
||||
* struct initialization
|
||||
M2-Planet doesn't support static initialization for structs yet.
|
||||
|
||||
Simply because time hasn't been made available for the effort.
|
||||
|
||||
Patches for adding support are welcome.
|
||||
|
||||
* C style function pointers
|
||||
M2-Planet supports universal function pointer FUNCTION
|
||||
Simply delete the typedef and the code works fine in M2-Planet
|
||||
|
||||
** example of failing code
|
||||
#include <stdio.h>
|
||||
typedef int (*FUNCTION) ();
|
||||
|
||||
struct function
|
||||
{
|
||||
FUNCTION function;
|
||||
int arity;
|
||||
char* name;
|
||||
};
|
||||
|
||||
struct function fun_make_cell_;
|
||||
|
||||
int make_cell_ ()
|
||||
{
|
||||
char* i = fun_make_cell_.name;
|
||||
while(0 != i[0])
|
||||
{
|
||||
fputc(i[0], stdout);
|
||||
i = i + 1;
|
||||
}
|
||||
return fun_make_cell_.arity;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
fun_make_cell_.function = make_cell_;
|
||||
fun_make_cell_.arity = 2;
|
||||
fun_make_cell_.name = "bar\n";
|
||||
fun_make_cell_.function();
|
||||
}
|
||||
|
||||
* logical and do not short circuit
|
||||
Both sides of && evaluate because it hasn't been shown to be worth the effort of implementation of short-circuit logic
|
||||
|
||||
** example of failing code
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int boom()
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv)
|
||||
{
|
||||
if((0 == argc) && boom())
|
||||
{
|
||||
fputs("impossible code\n", stderr);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
** work around code
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int boom()
|
||||
{
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv)
|
||||
{
|
||||
if(0 == argc)
|
||||
{
|
||||
if(boom())fputs("impossible code\n", stderr);
|
||||
}
|
||||
return 0;
|
||||
}
|
806
makefile
806
makefile
|
@ -1,5 +1,5 @@
|
|||
## Copyright (C) 2017 Jeremiah Orians
|
||||
## Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
## Copyright (C) 2020-2021 deesix <deesix@tuta.io>
|
||||
## This file is part of M2-Planet.
|
||||
##
|
||||
## M2-Planet is free software: you can redistribute it and/or modify
|
||||
|
@ -24,40 +24,31 @@ CC?=gcc
|
|||
CFLAGS:=$(CFLAGS) -D_GNU_SOURCE -O0 -std=c99 -ggdb
|
||||
|
||||
all: M2-Planet
|
||||
|
||||
M2-Planet: bin results cc.h cc_reader.c cc_strings.c cc_types.c cc_core.c cc.c
|
||||
.NOTPARALLEL:
|
||||
M2-Planet: bin results cc.h cc_reader.c cc_strings.c cc_types.c cc_core.c cc.c cc_globals.c cc_globals.h cc_macro.c | bin
|
||||
$(CC) $(CFLAGS) \
|
||||
functions/match.c \
|
||||
functions/in_set.c \
|
||||
functions/numerate_number.c \
|
||||
functions/file_print.c \
|
||||
functions/number_pack.c \
|
||||
functions/string.c \
|
||||
functions/require.c \
|
||||
M2libc/bootstrappable.c \
|
||||
cc_reader.c \
|
||||
cc_strings.c \
|
||||
cc_types.c \
|
||||
cc_core.c \
|
||||
cc_macro.c \
|
||||
cc.c \
|
||||
cc.h \
|
||||
cc_globals.c \
|
||||
gcc_req.h \
|
||||
-o bin/M2-Planet
|
||||
|
||||
M2-minimal: bin results cc.h cc_reader.c cc_strings.c cc_types.c cc_core.c cc-minimal.c
|
||||
$(CC) $(CFLAGS) \
|
||||
functions/match.c \
|
||||
functions/in_set.c \
|
||||
functions/numerate_number.c \
|
||||
functions/file_print.c \
|
||||
functions/number_pack.c \
|
||||
functions/string.c \
|
||||
functions/require.c \
|
||||
M2libc/bootstrappable.c \
|
||||
cc_reader.c \
|
||||
cc_strings.c \
|
||||
cc_types.c \
|
||||
cc_core.c \
|
||||
cc-minimal.c \
|
||||
cc.h \
|
||||
cc_globals.c \
|
||||
gcc_req.h \
|
||||
-o bin/M2-minimal
|
||||
|
||||
|
@ -65,753 +56,58 @@ M2-minimal: bin results cc.h cc_reader.c cc_strings.c cc_types.c cc_core.c cc-mi
|
|||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf bin/ test/results/
|
||||
./test/test0000/cleanup.sh
|
||||
./test/test0001/cleanup.sh
|
||||
./test/test0002/cleanup.sh
|
||||
./test/test0003/cleanup.sh
|
||||
./test/test0004/cleanup.sh
|
||||
./test/test0005/cleanup.sh
|
||||
./test/test0006/cleanup.sh
|
||||
./test/test0007/cleanup.sh
|
||||
./test/test0008/cleanup.sh
|
||||
./test/test0009/cleanup.sh
|
||||
./test/test0010/cleanup.sh
|
||||
./test/test0011/cleanup.sh
|
||||
./test/test0012/cleanup.sh
|
||||
./test/test0013/cleanup.sh
|
||||
./test/test0014/cleanup.sh
|
||||
./test/test0015/cleanup.sh
|
||||
./test/test0016/cleanup.sh
|
||||
./test/test0017/cleanup.sh
|
||||
./test/test0018/cleanup.sh
|
||||
./test/test0019/cleanup.sh
|
||||
./test/test0020/cleanup.sh
|
||||
./test/test0021/cleanup.sh
|
||||
./test/test0022/cleanup.sh
|
||||
./test/test0023/cleanup.sh
|
||||
./test/test0100/cleanup.sh
|
||||
./test/test0101/cleanup.sh
|
||||
./test/test0102/cleanup.sh
|
||||
./test/test0103/cleanup.sh
|
||||
./test/test0104/cleanup.sh
|
||||
./test/test0105/cleanup.sh
|
||||
./test/test0106/cleanup.sh
|
||||
./test/test1000/cleanup.sh
|
||||
./test/cleanup_test.sh 0000
|
||||
./test/cleanup_test.sh 0001
|
||||
./test/cleanup_test.sh 0002
|
||||
./test/cleanup_test.sh 0003
|
||||
./test/cleanup_test.sh 0004
|
||||
./test/cleanup_test.sh 0005
|
||||
./test/cleanup_test.sh 0006
|
||||
./test/cleanup_test.sh 0007
|
||||
./test/cleanup_test.sh 0008
|
||||
./test/cleanup_test.sh 0009
|
||||
./test/cleanup_test.sh 0010
|
||||
./test/cleanup_test.sh 0011
|
||||
./test/cleanup_test.sh 0012
|
||||
./test/cleanup_test.sh 0013
|
||||
./test/cleanup_test.sh 0014
|
||||
./test/cleanup_test.sh 0015
|
||||
./test/cleanup_test.sh 0016
|
||||
./test/cleanup_test.sh 0017
|
||||
./test/cleanup_test.sh 0018
|
||||
./test/cleanup_test.sh 0019
|
||||
./test/cleanup_test.sh 0020
|
||||
./test/cleanup_test.sh 0021
|
||||
./test/cleanup_test.sh 0022
|
||||
./test/cleanup_test.sh 0023
|
||||
./test/cleanup_test.sh 0024
|
||||
./test/cleanup_test.sh 0025
|
||||
./test/cleanup_test.sh 0026
|
||||
./test/cleanup_test.sh 0027
|
||||
./test/cleanup_test.sh 0028
|
||||
./test/cleanup_test.sh 0029
|
||||
./test/cleanup_test.sh 0030
|
||||
./test/cleanup_test.sh 0100
|
||||
./test/cleanup_test.sh 0101
|
||||
./test/cleanup_test.sh 0102
|
||||
./test/cleanup_test.sh 0103
|
||||
./test/cleanup_test.sh 0104
|
||||
./test/cleanup_test.sh 0105
|
||||
./test/cleanup_test.sh 0106
|
||||
./test/cleanup_test.sh 1000
|
||||
|
||||
# Directories
|
||||
bin:
|
||||
mkdir -p bin
|
||||
|
||||
results:
|
||||
test/results:
|
||||
mkdir -p test/results
|
||||
|
||||
# tests
|
||||
test: test0000-aarch64-binary \
|
||||
test0001-aarch64-binary \
|
||||
test0002-aarch64-binary \
|
||||
test0003-aarch64-binary \
|
||||
test0004-aarch64-binary \
|
||||
test0005-aarch64-binary \
|
||||
test0006-aarch64-binary \
|
||||
test0007-aarch64-binary \
|
||||
test0008-aarch64-binary \
|
||||
test0009-aarch64-binary \
|
||||
test0010-aarch64-binary \
|
||||
test0011-aarch64-binary \
|
||||
test0012-aarch64-binary \
|
||||
test0013-aarch64-binary \
|
||||
test0014-aarch64-binary \
|
||||
test0015-aarch64-binary \
|
||||
test0016-aarch64-binary \
|
||||
test0017-aarch64-binary \
|
||||
test0018-aarch64-binary \
|
||||
test0019-aarch64-binary \
|
||||
test0020-aarch64-binary \
|
||||
test0021-aarch64-binary \
|
||||
test0022-aarch64-binary \
|
||||
test0023-aarch64-binary \
|
||||
test0100-aarch64-binary \
|
||||
test0101-aarch64-binary \
|
||||
test0102-aarch64-binary \
|
||||
test0103-aarch64-binary \
|
||||
test0104-aarch64-binary \
|
||||
test0105-aarch64-binary \
|
||||
test0106-aarch64-binary \
|
||||
test1000-aarch64-binary \
|
||||
test0000-amd64-binary \
|
||||
test0001-amd64-binary \
|
||||
test0002-amd64-binary \
|
||||
test0003-amd64-binary \
|
||||
test0004-amd64-binary \
|
||||
test0005-amd64-binary \
|
||||
test0006-amd64-binary \
|
||||
test0007-amd64-binary \
|
||||
test0008-amd64-binary \
|
||||
test0009-amd64-binary \
|
||||
test0010-amd64-binary \
|
||||
test0011-amd64-binary \
|
||||
test0012-amd64-binary \
|
||||
test0013-amd64-binary \
|
||||
test0014-amd64-binary \
|
||||
test0015-amd64-binary \
|
||||
test0016-amd64-binary \
|
||||
test0017-amd64-binary \
|
||||
test0018-amd64-binary \
|
||||
test0019-amd64-binary \
|
||||
test0020-amd64-binary \
|
||||
test0021-amd64-binary \
|
||||
test0022-amd64-binary \
|
||||
test0023-amd64-binary \
|
||||
test0100-amd64-binary \
|
||||
test0101-amd64-binary \
|
||||
test0102-amd64-binary \
|
||||
test0103-amd64-binary \
|
||||
test0104-amd64-binary \
|
||||
test0105-amd64-binary \
|
||||
test0106-amd64-binary \
|
||||
test1000-amd64-binary \
|
||||
test0000-knight-posix-binary \
|
||||
test0001-knight-posix-binary \
|
||||
test0002-knight-posix-binary \
|
||||
test0003-knight-posix-binary \
|
||||
test0004-knight-posix-binary \
|
||||
test0005-knight-posix-binary \
|
||||
test0006-knight-posix-binary \
|
||||
test0007-knight-posix-binary \
|
||||
test0008-knight-posix-binary \
|
||||
test0009-knight-posix-binary \
|
||||
test0010-knight-posix-binary \
|
||||
test0011-knight-posix-binary \
|
||||
test0012-knight-posix-binary \
|
||||
test0013-knight-posix-binary \
|
||||
test0014-knight-posix-binary \
|
||||
test0015-knight-posix-binary \
|
||||
test0016-knight-posix-binary \
|
||||
test0017-knight-posix-binary \
|
||||
test0018-knight-posix-binary \
|
||||
test0019-knight-posix-binary \
|
||||
test0020-knight-posix-binary \
|
||||
test0021-knight-posix-binary \
|
||||
test0022-knight-posix-binary \
|
||||
test0023-knight-posix-binary \
|
||||
test0100-knight-posix-binary \
|
||||
test0101-knight-posix-binary \
|
||||
test0102-knight-posix-binary \
|
||||
test0103-knight-posix-binary \
|
||||
test0106-knight-posix-binary \
|
||||
test1000-knight-posix-binary \
|
||||
test0000-knight-native-binary\
|
||||
test0001-knight-native-binary\
|
||||
test0002-knight-native-binary\
|
||||
test0003-knight-native-binary\
|
||||
test0004-knight-native-binary\
|
||||
test0005-knight-native-binary\
|
||||
test0006-knight-native-binary\
|
||||
test0007-knight-native-binary\
|
||||
test0008-knight-native-binary\
|
||||
test0009-knight-native-binary\
|
||||
test0010-knight-native-binary\
|
||||
test0011-knight-native-binary\
|
||||
test0012-knight-native-binary\
|
||||
test0013-knight-native-binary\
|
||||
test0017-knight-native-binary\
|
||||
test0018-knight-native-binary\
|
||||
test0020-knight-native-binary\
|
||||
test0106-knight-native-binary\
|
||||
test0000-armv7l-binary \
|
||||
test0001-armv7l-binary \
|
||||
test0002-armv7l-binary \
|
||||
test0003-armv7l-binary \
|
||||
test0004-armv7l-binary \
|
||||
test0005-armv7l-binary \
|
||||
test0006-armv7l-binary \
|
||||
test0007-armv7l-binary \
|
||||
test0008-armv7l-binary \
|
||||
test0009-armv7l-binary \
|
||||
test0010-armv7l-binary \
|
||||
test0011-armv7l-binary \
|
||||
test0012-armv7l-binary \
|
||||
test0013-armv7l-binary \
|
||||
test0014-armv7l-binary \
|
||||
test0015-armv7l-binary \
|
||||
test0016-armv7l-binary \
|
||||
test0017-armv7l-binary \
|
||||
test0018-armv7l-binary \
|
||||
test0019-armv7l-binary \
|
||||
test0020-armv7l-binary \
|
||||
test0021-armv7l-binary \
|
||||
test0022-armv7l-binary \
|
||||
test0023-armv7l-binary \
|
||||
test0100-armv7l-binary \
|
||||
test0101-armv7l-binary \
|
||||
test0102-armv7l-binary \
|
||||
test0103-armv7l-binary \
|
||||
test0104-armv7l-binary \
|
||||
test0105-armv7l-binary \
|
||||
test0106-armv7l-binary \
|
||||
test1000-armv7l-binary \
|
||||
test0000-x86-binary \
|
||||
test0001-x86-binary \
|
||||
test0002-x86-binary \
|
||||
test0003-x86-binary \
|
||||
test0004-x86-binary \
|
||||
test0005-x86-binary \
|
||||
test0006-x86-binary \
|
||||
test0007-x86-binary \
|
||||
test0008-x86-binary \
|
||||
test0009-x86-binary \
|
||||
test0010-x86-binary \
|
||||
test0011-x86-binary \
|
||||
test0012-x86-binary \
|
||||
test0013-x86-binary \
|
||||
test0014-x86-binary \
|
||||
test0015-x86-binary \
|
||||
test0016-x86-binary \
|
||||
test0017-x86-binary \
|
||||
test0018-x86-binary \
|
||||
test0019-x86-binary \
|
||||
test0020-x86-binary \
|
||||
test0021-x86-binary \
|
||||
test0022-x86-binary \
|
||||
test0023-x86-binary \
|
||||
test0100-x86-binary \
|
||||
test0101-x86-binary \
|
||||
test0102-x86-binary \
|
||||
test0103-x86-binary \
|
||||
test0104-x86-binary \
|
||||
test0105-x86-binary \
|
||||
test0106-x86-binary \
|
||||
test1000-x86-binary | results
|
||||
test: M2-Planet | bin test/results
|
||||
+make -f makefile-tests --output-sync
|
||||
sha256sum -c test/test.answers
|
||||
|
||||
test0000-aarch64-binary: M2-Planet | results
|
||||
test/test0000/hello-aarch64.sh
|
||||
|
||||
test0001-aarch64-binary: M2-Planet | results
|
||||
test/test0001/hello-aarch64.sh
|
||||
|
||||
test0002-aarch64-binary: M2-Planet | results
|
||||
test/test0002/hello-aarch64.sh
|
||||
|
||||
test0003-aarch64-binary: M2-Planet | results
|
||||
test/test0003/hello-aarch64.sh
|
||||
|
||||
test0004-aarch64-binary: M2-Planet | results
|
||||
test/test0004/hello-aarch64.sh
|
||||
|
||||
test0005-aarch64-binary: M2-Planet | results
|
||||
test/test0005/hello-aarch64.sh
|
||||
|
||||
test0006-aarch64-binary: M2-Planet | results
|
||||
test/test0006/hello-aarch64.sh
|
||||
|
||||
test0007-aarch64-binary: M2-Planet | results
|
||||
test/test0007/hello-aarch64.sh
|
||||
|
||||
test0008-aarch64-binary: M2-Planet | results
|
||||
test/test0008/hello-aarch64.sh
|
||||
|
||||
test0009-aarch64-binary: M2-Planet | results
|
||||
test/test0009/hello-aarch64.sh
|
||||
|
||||
test0010-aarch64-binary: M2-Planet | results
|
||||
test/test0010/hello-aarch64.sh
|
||||
|
||||
test0011-aarch64-binary: M2-Planet | results
|
||||
test/test0011/hello-aarch64.sh
|
||||
|
||||
test0012-aarch64-binary: M2-Planet | results
|
||||
test/test0012/hello-aarch64.sh
|
||||
|
||||
test0013-aarch64-binary: M2-Planet | results
|
||||
test/test0013/hello-aarch64.sh
|
||||
|
||||
test0014-aarch64-binary: M2-Planet | results
|
||||
test/test0014/hello-aarch64.sh
|
||||
|
||||
test0015-aarch64-binary: M2-Planet | results
|
||||
test/test0015/hello-aarch64.sh
|
||||
|
||||
test0016-aarch64-binary: M2-Planet | results
|
||||
test/test0016/hello-aarch64.sh
|
||||
|
||||
test0017-aarch64-binary: M2-Planet | results
|
||||
test/test0017/hello-aarch64.sh
|
||||
|
||||
test0018-aarch64-binary: M2-Planet | results
|
||||
test/test0018/hello-aarch64.sh
|
||||
|
||||
test0019-aarch64-binary: M2-Planet | results
|
||||
test/test0019/hello-aarch64.sh
|
||||
|
||||
test0020-aarch64-binary: M2-Planet | results
|
||||
test/test0020/hello-aarch64.sh
|
||||
|
||||
test0021-aarch64-binary: M2-Planet | results
|
||||
test/test0021/hello-aarch64.sh
|
||||
|
||||
test0022-aarch64-binary: M2-Planet | results
|
||||
test/test0022/hello-aarch64.sh
|
||||
|
||||
test0023-aarch64-binary: M2-Planet | results
|
||||
test/test0023/hello-aarch64.sh
|
||||
|
||||
test0100-aarch64-binary: M2-Planet | results
|
||||
test/test0100/hello-aarch64.sh
|
||||
|
||||
test0101-aarch64-binary: M2-Planet | results
|
||||
test/test0101/hello-aarch64.sh
|
||||
|
||||
test0102-aarch64-binary: M2-Planet | results
|
||||
test/test0102/hello-aarch64.sh
|
||||
|
||||
test0103-aarch64-binary: M2-Planet | results
|
||||
test/test0103/hello-aarch64.sh
|
||||
|
||||
test0104-aarch64-binary: M2-Planet | results
|
||||
test/test0104/hello-aarch64.sh
|
||||
|
||||
test0105-aarch64-binary: M2-Planet | results
|
||||
test/test0105/hello-aarch64.sh
|
||||
|
||||
test0106-aarch64-binary: M2-Planet | results
|
||||
test/test0106/hello-aarch64.sh
|
||||
|
||||
test1000-aarch64-binary: M2-Planet | results
|
||||
test/test1000/hello-aarch64.sh
|
||||
|
||||
test0000-amd64-binary: M2-Planet | results
|
||||
test/test0000/hello-amd64.sh
|
||||
|
||||
test0001-amd64-binary: M2-Planet | results
|
||||
test/test0001/hello-amd64.sh
|
||||
|
||||
test0002-amd64-binary: M2-Planet | results
|
||||
test/test0002/hello-amd64.sh
|
||||
|
||||
test0003-amd64-binary: M2-Planet | results
|
||||
test/test0003/hello-amd64.sh
|
||||
|
||||
test0004-amd64-binary: M2-Planet | results
|
||||
test/test0004/hello-amd64.sh
|
||||
|
||||
test0005-amd64-binary: M2-Planet | results
|
||||
test/test0005/hello-amd64.sh
|
||||
|
||||
test0006-amd64-binary: M2-Planet | results
|
||||
test/test0006/hello-amd64.sh
|
||||
|
||||
test0007-amd64-binary: M2-Planet | results
|
||||
test/test0007/hello-amd64.sh
|
||||
|
||||
test0008-amd64-binary: M2-Planet | results
|
||||
test/test0008/hello-amd64.sh
|
||||
|
||||
test0009-amd64-binary: M2-Planet | results
|
||||
test/test0009/hello-amd64.sh
|
||||
|
||||
test0010-amd64-binary: M2-Planet | results
|
||||
test/test0010/hello-amd64.sh
|
||||
|
||||
test0011-amd64-binary: M2-Planet | results
|
||||
test/test0011/hello-amd64.sh
|
||||
|
||||
test0012-amd64-binary: M2-Planet | results
|
||||
test/test0012/hello-amd64.sh
|
||||
|
||||
test0013-amd64-binary: M2-Planet | results
|
||||
test/test0013/hello-amd64.sh
|
||||
|
||||
test0014-amd64-binary: M2-Planet | results
|
||||
test/test0014/hello-amd64.sh
|
||||
|
||||
test0015-amd64-binary: M2-Planet | results
|
||||
test/test0015/hello-amd64.sh
|
||||
|
||||
test0016-amd64-binary: M2-Planet | results
|
||||
test/test0016/hello-amd64.sh
|
||||
|
||||
test0017-amd64-binary: M2-Planet | results
|
||||
test/test0017/hello-amd64.sh
|
||||
|
||||
test0018-amd64-binary: M2-Planet | results
|
||||
test/test0018/hello-amd64.sh
|
||||
|
||||
test0019-amd64-binary: M2-Planet | results
|
||||
test/test0019/hello-amd64.sh
|
||||
|
||||
test0020-amd64-binary: M2-Planet | results
|
||||
test/test0020/hello-amd64.sh
|
||||
|
||||
test0021-amd64-binary: M2-Planet | results
|
||||
test/test0021/hello-amd64.sh
|
||||
|
||||
test0022-amd64-binary: M2-Planet | results
|
||||
test/test0022/hello-amd64.sh
|
||||
|
||||
test0023-amd64-binary: M2-Planet | results
|
||||
test/test0023/hello-amd64.sh
|
||||
|
||||
test0100-amd64-binary: M2-Planet | results
|
||||
test/test0100/hello-amd64.sh
|
||||
|
||||
test0101-amd64-binary: M2-Planet | results
|
||||
test/test0101/hello-amd64.sh
|
||||
|
||||
test0102-amd64-binary: M2-Planet | results
|
||||
test/test0102/hello-amd64.sh
|
||||
|
||||
test0103-amd64-binary: M2-Planet | results
|
||||
test/test0103/hello-amd64.sh
|
||||
|
||||
test0104-amd64-binary: M2-Planet | results
|
||||
test/test0104/hello-amd64.sh
|
||||
|
||||
test0105-amd64-binary: M2-Planet | results
|
||||
test/test0105/hello-amd64.sh
|
||||
|
||||
test0106-amd64-binary: M2-Planet | results
|
||||
test/test0106/hello-amd64.sh
|
||||
|
||||
test1000-amd64-binary: M2-Planet | results
|
||||
test/test1000/hello-amd64.sh
|
||||
|
||||
test0000-knight-posix-binary: M2-Planet | results
|
||||
test/test0000/hello-knight-posix.sh
|
||||
|
||||
test0001-knight-posix-binary: M2-Planet | results
|
||||
test/test0001/hello-knight-posix.sh
|
||||
|
||||
test0002-knight-posix-binary: M2-Planet | results
|
||||
test/test0002/hello-knight-posix.sh
|
||||
|
||||
test0003-knight-posix-binary: M2-Planet | results
|
||||
test/test0003/hello-knight-posix.sh
|
||||
|
||||
test0004-knight-posix-binary: M2-Planet | results
|
||||
test/test0004/hello-knight-posix.sh
|
||||
|
||||
test0005-knight-posix-binary: M2-Planet | results
|
||||
test/test0005/hello-knight-posix.sh
|
||||
|
||||
test0006-knight-posix-binary: M2-Planet | results
|
||||
test/test0006/hello-knight-posix.sh
|
||||
|
||||
test0007-knight-posix-binary: M2-Planet | results
|
||||
test/test0007/hello-knight-posix.sh
|
||||
|
||||
test0008-knight-posix-binary: M2-Planet | results
|
||||
test/test0008/hello-knight-posix.sh
|
||||
|
||||
test0009-knight-posix-binary: M2-Planet | results
|
||||
test/test0009/hello-knight-posix.sh
|
||||
|
||||
test0010-knight-posix-binary: M2-Planet | results
|
||||
test/test0010/hello-knight-posix.sh
|
||||
|
||||
test0011-knight-posix-binary: M2-Planet | results
|
||||
test/test0011/hello-knight-posix.sh
|
||||
|
||||
test0012-knight-posix-binary: M2-Planet | results
|
||||
test/test0012/hello-knight-posix.sh
|
||||
|
||||
test0013-knight-posix-binary: M2-Planet | results
|
||||
test/test0013/hello-knight-posix.sh
|
||||
|
||||
test0014-knight-posix-binary: M2-Planet | results
|
||||
test/test0014/hello-knight-posix.sh
|
||||
|
||||
test0015-knight-posix-binary: M2-Planet | results
|
||||
test/test0015/hello-knight-posix.sh
|
||||
|
||||
test0016-knight-posix-binary: M2-Planet | results
|
||||
test/test0016/hello-knight-posix.sh
|
||||
|
||||
test0017-knight-posix-binary: M2-Planet | results
|
||||
test/test0017/hello-knight-posix.sh
|
||||
|
||||
test0018-knight-posix-binary: M2-Planet | results
|
||||
test/test0018/hello-knight-posix.sh
|
||||
|
||||
test0019-knight-posix-binary: M2-Planet | results
|
||||
test/test0019/hello-knight-posix.sh
|
||||
|
||||
test0020-knight-posix-binary: M2-Planet | results
|
||||
test/test0020/hello-knight-posix.sh
|
||||
|
||||
test0021-knight-posix-binary: M2-Planet | results
|
||||
test/test0021/hello-knight-posix.sh
|
||||
|
||||
test0022-knight-posix-binary: M2-Planet | results
|
||||
test/test0022/hello-knight-posix.sh
|
||||
|
||||
test0023-knight-posix-binary: M2-Planet | results
|
||||
test/test0023/hello-knight-posix.sh
|
||||
|
||||
test0100-knight-posix-binary: M2-Planet | results
|
||||
test/test0100/hello-knight-posix.sh
|
||||
|
||||
test0101-knight-posix-binary: M2-Planet | results
|
||||
test/test0101/hello-knight-posix.sh
|
||||
|
||||
test0102-knight-posix-binary: M2-Planet | results
|
||||
test/test0102/hello-knight-posix.sh
|
||||
|
||||
test0103-knight-posix-binary: M2-Planet | results
|
||||
test/test0103/hello-knight-posix.sh
|
||||
|
||||
test0106-knight-posix-binary: M2-Planet | results
|
||||
test/test0106/hello-knight-posix.sh
|
||||
|
||||
test1000-knight-posix-binary: M2-Planet | results
|
||||
test/test1000/hello-knight-posix.sh
|
||||
|
||||
test0000-knight-native-binary: M2-Planet | results
|
||||
test/test0000/hello-knight-native.sh
|
||||
|
||||
test0001-knight-native-binary: M2-Planet | results
|
||||
test/test0001/hello-knight-native.sh
|
||||
|
||||
test0002-knight-native-binary: M2-Planet | results
|
||||
test/test0002/hello-knight-native.sh
|
||||
|
||||
test0003-knight-native-binary: M2-Planet | results
|
||||
test/test0003/hello-knight-native.sh
|
||||
|
||||
test0004-knight-native-binary: M2-Planet | results
|
||||
test/test0004/hello-knight-native.sh
|
||||
|
||||
test0005-knight-native-binary: M2-Planet | results
|
||||
test/test0005/hello-knight-native.sh
|
||||
|
||||
test0006-knight-native-binary: M2-Planet | results
|
||||
test/test0006/hello-knight-native.sh
|
||||
|
||||
test0007-knight-native-binary: M2-Planet | results
|
||||
test/test0007/hello-knight-native.sh
|
||||
|
||||
test0008-knight-native-binary: M2-Planet | results
|
||||
test/test0008/hello-knight-native.sh
|
||||
|
||||
test0009-knight-native-binary: M2-Planet | results
|
||||
test/test0009/hello-knight-native.sh
|
||||
|
||||
test0010-knight-native-binary: M2-Planet | results
|
||||
test/test0010/hello-knight-native.sh
|
||||
|
||||
test0011-knight-native-binary: M2-Planet | results
|
||||
test/test0011/hello-knight-native.sh
|
||||
|
||||
test0012-knight-native-binary: M2-Planet | results
|
||||
test/test0012/hello-knight-native.sh
|
||||
|
||||
test0013-knight-native-binary: M2-Planet | results
|
||||
test/test0013/hello-knight-native.sh
|
||||
|
||||
test0017-knight-native-binary: M2-Planet | results
|
||||
test/test0017/hello-knight-native.sh
|
||||
|
||||
test0018-knight-native-binary: M2-Planet | results
|
||||
test/test0018/hello-knight-native.sh
|
||||
|
||||
test0020-knight-native-binary: M2-Planet | results
|
||||
test/test0020/hello-knight-native.sh
|
||||
|
||||
test0106-knight-native-binary: M2-Planet | results
|
||||
test/test0106/hello-knight-native.sh
|
||||
|
||||
test0000-armv7l-binary: M2-Planet | results
|
||||
test/test0000/hello-armv7l.sh
|
||||
|
||||
test0001-armv7l-binary: M2-Planet | results
|
||||
test/test0001/hello-armv7l.sh
|
||||
|
||||
test0002-armv7l-binary: M2-Planet | results
|
||||
test/test0002/hello-armv7l.sh
|
||||
|
||||
test0003-armv7l-binary: M2-Planet | results
|
||||
test/test0003/hello-armv7l.sh
|
||||
|
||||
test0004-armv7l-binary: M2-Planet | results
|
||||
test/test0004/hello-armv7l.sh
|
||||
|
||||
test0005-armv7l-binary: M2-Planet | results
|
||||
test/test0005/hello-armv7l.sh
|
||||
|
||||
test0006-armv7l-binary: M2-Planet | results
|
||||
test/test0006/hello-armv7l.sh
|
||||
|
||||
test0007-armv7l-binary: M2-Planet | results
|
||||
test/test0007/hello-armv7l.sh
|
||||
|
||||
test0008-armv7l-binary: M2-Planet | results
|
||||
test/test0008/hello-armv7l.sh
|
||||
|
||||
test0009-armv7l-binary: M2-Planet | results
|
||||
test/test0009/hello-armv7l.sh
|
||||
|
||||
test0010-armv7l-binary: M2-Planet | results
|
||||
test/test0010/hello-armv7l.sh
|
||||
|
||||
test0011-armv7l-binary: M2-Planet | results
|
||||
test/test0011/hello-armv7l.sh
|
||||
|
||||
test0012-armv7l-binary: M2-Planet | results
|
||||
test/test0012/hello-armv7l.sh
|
||||
|
||||
test0013-armv7l-binary: M2-Planet | results
|
||||
test/test0013/hello-armv7l.sh
|
||||
|
||||
test0014-armv7l-binary: M2-Planet | results
|
||||
test/test0014/hello-armv7l.sh
|
||||
|
||||
test0015-armv7l-binary: M2-Planet | results
|
||||
test/test0015/hello-armv7l.sh
|
||||
|
||||
test0016-armv7l-binary: M2-Planet | results
|
||||
test/test0016/hello-armv7l.sh
|
||||
|
||||
test0017-armv7l-binary: M2-Planet | results
|
||||
test/test0017/hello-armv7l.sh
|
||||
|
||||
test0018-armv7l-binary: M2-Planet | results
|
||||
test/test0018/hello-armv7l.sh
|
||||
|
||||
test0019-armv7l-binary: M2-Planet | results
|
||||
test/test0019/hello-armv7l.sh
|
||||
|
||||
test0020-armv7l-binary: M2-Planet | results
|
||||
test/test0020/hello-armv7l.sh
|
||||
|
||||
test0021-armv7l-binary: M2-Planet | results
|
||||
test/test0021/hello-armv7l.sh
|
||||
|
||||
test0022-armv7l-binary: M2-Planet | results
|
||||
test/test0022/hello-armv7l.sh
|
||||
|
||||
test0023-armv7l-binary: M2-Planet | results
|
||||
test/test0023/hello-armv7l.sh
|
||||
|
||||
test0100-armv7l-binary: M2-Planet | results
|
||||
test/test0100/hello-armv7l.sh
|
||||
|
||||
test0101-armv7l-binary: M2-Planet | results
|
||||
test/test0101/hello-armv7l.sh
|
||||
|
||||
test0102-armv7l-binary: M2-Planet | results
|
||||
test/test0102/hello-armv7l.sh
|
||||
|
||||
test0103-armv7l-binary: M2-Planet | results
|
||||
test/test0103/hello-armv7l.sh
|
||||
|
||||
test0104-armv7l-binary: M2-Planet | results
|
||||
test/test0104/hello-armv7l.sh
|
||||
|
||||
test0105-armv7l-binary: M2-Planet | results
|
||||
test/test0105/hello-armv7l.sh
|
||||
|
||||
test0106-armv7l-binary: M2-Planet | results
|
||||
test/test0106/hello-armv7l.sh
|
||||
|
||||
test1000-armv7l-binary: M2-Planet | results
|
||||
test/test1000/hello-armv7l.sh
|
||||
|
||||
test0000-x86-binary: M2-Planet | results
|
||||
test/test0000/hello-x86.sh
|
||||
|
||||
test0001-x86-binary: M2-Planet | results
|
||||
test/test0001/hello-x86.sh
|
||||
|
||||
test0002-x86-binary: M2-Planet | results
|
||||
test/test0002/hello-x86.sh
|
||||
|
||||
test0003-x86-binary: M2-Planet | results
|
||||
test/test0003/hello-x86.sh
|
||||
|
||||
test0004-x86-binary: M2-Planet | results
|
||||
test/test0004/hello-x86.sh
|
||||
|
||||
test0005-x86-binary: M2-Planet | results
|
||||
test/test0005/hello-x86.sh
|
||||
|
||||
test0006-x86-binary: M2-Planet | results
|
||||
test/test0006/hello-x86.sh
|
||||
|
||||
test0007-x86-binary: M2-Planet | results
|
||||
test/test0007/hello-x86.sh
|
||||
|
||||
test0008-x86-binary: M2-Planet | results
|
||||
test/test0008/hello-x86.sh
|
||||
|
||||
test0009-x86-binary: M2-Planet | results
|
||||
test/test0009/hello-x86.sh
|
||||
|
||||
test0010-x86-binary: M2-Planet | results
|
||||
test/test0010/hello-x86.sh
|
||||
|
||||
test0011-x86-binary: M2-Planet | results
|
||||
test/test0011/hello-x86.sh
|
||||
|
||||
test0012-x86-binary: M2-Planet | results
|
||||
test/test0012/hello-x86.sh
|
||||
|
||||
test0013-x86-binary: M2-Planet | results
|
||||
test/test0013/hello-x86.sh
|
||||
|
||||
test0014-x86-binary: M2-Planet | results
|
||||
test/test0014/hello-x86.sh
|
||||
|
||||
test0015-x86-binary: M2-Planet | results
|
||||
test/test0015/hello-x86.sh
|
||||
|
||||
test0016-x86-binary: M2-Planet | results
|
||||
test/test0016/hello-x86.sh
|
||||
|
||||
test0017-x86-binary: M2-Planet | results
|
||||
test/test0017/hello-x86.sh
|
||||
|
||||
test0018-x86-binary: M2-Planet | results
|
||||
test/test0018/hello-x86.sh
|
||||
|
||||
test0019-x86-binary: M2-Planet | results
|
||||
test/test0019/hello-x86.sh
|
||||
|
||||
test0020-x86-binary: M2-Planet | results
|
||||
test/test0020/hello-x86.sh
|
||||
|
||||
test0021-x86-binary: M2-Planet | results
|
||||
test/test0021/hello-x86.sh
|
||||
|
||||
test0022-x86-binary: M2-Planet | results
|
||||
test/test0022/hello-x86.sh
|
||||
|
||||
test0023-x86-binary: M2-Planet | results
|
||||
test/test0023/hello-x86.sh
|
||||
|
||||
test0100-x86-binary: M2-Planet | results
|
||||
test/test0100/hello-x86.sh
|
||||
|
||||
test0101-x86-binary: M2-Planet | results
|
||||
test/test0101/hello-x86.sh
|
||||
|
||||
test0102-x86-binary: M2-Planet | results
|
||||
test/test0102/hello-x86.sh
|
||||
|
||||
test0103-x86-binary: M2-Planet | results
|
||||
test/test0103/hello-x86.sh
|
||||
|
||||
test0104-x86-binary: M2-Planet | results
|
||||
test/test0104/hello-x86.sh
|
||||
|
||||
test0105-x86-binary: M2-Planet | results
|
||||
test/test0105/hello-x86.sh
|
||||
|
||||
test0106-x86-binary: M2-Planet | results
|
||||
test/test0106/hello-x86.sh
|
||||
|
||||
test1000-x86-binary: M2-Planet | results
|
||||
test/test1000/hello-x86.sh
|
||||
|
||||
# Generate test answers
|
||||
.PHONY: Generate-test-answers
|
||||
Generate-test-answers:
|
||||
|
@ -825,7 +121,7 @@ install: M2-Planet
|
|||
mkdir -p $(bindir)
|
||||
cp $^ $(bindir)
|
||||
|
||||
### dist
|
||||
### dist
|
||||
.PHONY: dist
|
||||
|
||||
COMMIT=$(shell git describe --dirty)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
24
sha256.sh
24
sha256.sh
|
@ -1,5 +1,6 @@
|
|||
#! /bin/sh
|
||||
#! /usr/bin/env sh
|
||||
# Copyright (C) 2019 ng0 <ng0@n0.is>
|
||||
# Copyright (C) 2019 Jeremiah Orians
|
||||
#
|
||||
# This file is part of mescc-tools
|
||||
#
|
||||
|
@ -23,12 +24,25 @@ set -ex
|
|||
# accordingly.
|
||||
sha256_check()
|
||||
{
|
||||
if [ "$(get_machine --OS)" = "Linux" ]; then
|
||||
if [ -e "$(which sha256sum)" ]; then
|
||||
LANG=C sha256sum -c "$1"
|
||||
elif [ "$(get_machine --OS)" = "NetBSD" ]; then
|
||||
sum -a SHA256 -n -c "$1"
|
||||
elif [ "$(get_machine --OS)" = "FreeBSD" ]; then
|
||||
sha256 -r -c "$1"
|
||||
LANG=C 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
|
||||
LANG=C sum -a SHA256 -n -c "$1"
|
||||
elif [ -e "$(which sha256)" ]; then
|
||||
LANG=C sha256 -r -c "$1"
|
||||
else
|
||||
echo "Unsupported sha256 tool, please send a patch to support it"
|
||||
exit 77
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
## Copyright (C) 2017 Jeremiah Orians
|
||||
## Copyright (C) 2021 deesix <deesix@tuta.io>
|
||||
## This file is part of M2-Planet.
|
||||
##
|
||||
## M2-Planet is free software: you can redistribute it and/or modify
|
||||
|
@ -13,5 +14,13 @@
|
|||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Ignore all generated contents of tests
|
||||
results/
|
||||
test????/tmp-*/
|
||||
test????/proof
|
||||
test0106/cc1
|
||||
test0106/cc2
|
||||
|
||||
# A place to put a good run for comparison
|
||||
test????/actual.M1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#! /bin/sh
|
||||
## Copyright (C) 2017 Jeremiah Orians
|
||||
## Copyright (C) 2021 deesix <deesix@tuta.io>
|
||||
## This file is part of M2-Planet.
|
||||
##
|
||||
## M2-Planet is free software: you can redistribute it and/or modify
|
||||
|
@ -15,6 +15,16 @@
|
|||
## You should have received a copy of the GNU General Public License
|
||||
## along with M2-Planet. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
rm -f test/test0004/call.M1
|
||||
rm -f test/test0004/call.hex2
|
||||
for ARCH in aarch64 amd64 armv7l knight-native knight-posix x86 riscv32 riscv64; do
|
||||
rm -rf "test/test$1/tmp-$ARCH"
|
||||
done
|
||||
|
||||
# Not all, but most tests generate a 'proof' file.
|
||||
rm -f "test/test$1/proof"
|
||||
|
||||
# Test 0106 generates these two files when the host is x86.
|
||||
if [ "0106" = "$1" ] ; then
|
||||
rm -f "test/test$1/cc1" "test/test$1/cc2"
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -1,75 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text 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
|
|
@ -1,75 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text 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
|
|
@ -1,143 +0,0 @@
|
|||
## Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
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_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_BYTE_W0_[X1] 20000039
|
||||
DEFINE DEREF_X0 000040f9
|
||||
DEFINE DEREF_X0_BYTE 00004039
|
||||
|
||||
|
||||
# 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 RSHIFT_X0_X1_X0 2024c09a
|
||||
|
||||
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_FCHMODAT a80680d2
|
||||
DEFINE SET_X8_TO_SYS_GETCWD 280280d2
|
||||
DEFINE SET_X8_TO_SYS_LSEEK 288480d2 # FIXME if wrong
|
||||
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 SYSCALL 010000d4
|
|
@ -1,29 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void exit(int value);
|
||||
|
||||
void _exit(int value)
|
||||
{
|
||||
exit(value);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT EXIT_FAILURE 1
|
||||
// CONSTANT EXIT_SUCCESS 0
|
||||
|
||||
void exit(int value)
|
||||
{
|
||||
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
|
||||
"SET_X8_TO_SYS_EXIT"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
/* Copyright (C) 2016 Jeremiah Orians
|
||||
* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0
|
||||
// CONSTANT stdout 1
|
||||
// CONSTANT stderr 2
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Important values needed for open
|
||||
* O_RDONLY => 0
|
||||
* O_WRONLY => 1
|
||||
* O_RDWR => 2
|
||||
* O_CREAT => 64
|
||||
* O_TRUNC => 512
|
||||
* S_IRWXU => 00700
|
||||
* S_IXUSR => 00100
|
||||
* S_IWUSR => 00200
|
||||
* S_IRUSR => 00400
|
||||
*/
|
||||
|
||||
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 fflush(FILE *stream){
|
||||
/* We don't buffer, nothing to flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CONSTANT SEEK_SET 0
|
||||
// CONSTANT SEEK_CUR 1
|
||||
// CONSTANT SEEK_END 2
|
||||
|
||||
int fseek(FILE* f, long 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");
|
||||
}
|
||||
|
||||
void rewind(FILE* f)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int getchar()
|
||||
{
|
||||
asm("SET_X0_TO_0"
|
||||
"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");
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/* Copyright (C) 2020 Jeremiah Orians
|
||||
* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
//CONSTANT PATH_MAX 4096
|
||||
#define PATH_MAX 4096
|
||||
|
||||
int _getcwd(char* buf, size_t 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, size_t 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);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT NULL 0
|
||||
|
||||
void* malloc(int size)
|
||||
{
|
||||
asm("SET_X0_FROM_BP" "SUB_X0_8" "DEREF_X0"
|
||||
"SET_X1_FROM_X0"
|
||||
"SET_X0_TO_0" "SET_X8_TO_SYS_BRK" "SYSCALL"
|
||||
"PUSH_X0"
|
||||
"ADD_X0_X1_X0"
|
||||
"PUSH_X0"
|
||||
"SYSCALL"
|
||||
"POP_X1"
|
||||
/* TODO: Compare obtained with requested, as error checking. */
|
||||
"POP_X0"
|
||||
/* TODO: Override to return error if detected by the compare. */
|
||||
);
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
/* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
asm("SET_X0_FROM_BP" "SUB_X0_8"
|
||||
"SET_X1_FROM_X0"
|
||||
"SET_X0_TO_1"
|
||||
"SET_X2_TO_1"
|
||||
"SET_X8_TO_SYS_WRITE"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/* Copyright (C) 2016 Jeremiah Orians
|
||||
* Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* chmod() changes the mode of the file specified whose pathname is given in
|
||||
* pathname, which is dereferenced if it is a symbolic link.
|
||||
* fchmod() changes the mode of the file referred to by the open file
|
||||
* descriptor fd.
|
||||
* The new file mode is specified in mode, which is a bit mask created by
|
||||
* ORing together zero or more of the following:
|
||||
* S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
|
||||
* S_ISGID (02000) set-group-ID (set process effective group ID on execve(2)
|
||||
* mandatory locking, as described in fcntl(2); take a new file's group from
|
||||
* parent directory, as described in chown(2) and mkdir(2))
|
||||
* S_ISVTX (01000) sticky bit (restricted deletion flag, as described in
|
||||
* unlink(2))
|
||||
* S_IRUSR (00400) read by owner
|
||||
* S_IWUSR (00200) write by owner
|
||||
* S_IXUSR (00100) execute/search by owner ("search" applies for directories
|
||||
* , and means that entries within the directory can be accessed)
|
||||
* S_IRGRP (00040) read by group
|
||||
* S_IWGRP (00020) write by group
|
||||
* S_IXGRP (00010) execute/search by group
|
||||
* S_IROTH (00004) read by others
|
||||
* S_IWOTH (00002) write by others
|
||||
* S_IXOTH (00001) execute/search by others
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
## Copyright (C) 2020 deesix <deesix@tuta.io>
|
||||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_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
|
||||
SET_X8_TO_SYS_EXIT
|
||||
SYSCALL
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text 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
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text 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
|
|
@ -1,93 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
DEFINE ADD_IMMEDIATE_to_rax 4805
|
||||
DEFINE ADD_IMMEDIATE_to_rbp 4881C5
|
||||
DEFINE ADD_rax_to_rbx 4801C3
|
||||
DEFINE ADD_rbp_to_rax 4801E8
|
||||
DEFINE ADD_rbx_to_rax 4801D8
|
||||
DEFINE AND_rax_rbx 4821D8
|
||||
DEFINE CALL_IMMEDIATE E8
|
||||
DEFINE CALL_rax FFD0
|
||||
DEFINE CMP 4839C3
|
||||
DEFINE COPY_rax_to_rcx 4889C1
|
||||
DEFINE COPY_rax_to_rdi 4889C7
|
||||
DEFINE COPY_rbx_to_rax 4889D8
|
||||
DEFINE COPY_rbp_to_rax 4889E8
|
||||
DEFINE COPY_rbx_to_rdi 4889DF
|
||||
DEFINE COPY_rdi_to_rbp 4889FD
|
||||
DEFINE COPY_rsp_to_rbp 4889E5
|
||||
DEFINE COPY_RSP_to_RDI 4889E7
|
||||
DEFINE CQTO 4899
|
||||
DEFINE DIVIDE_rax_by_rbx_into_rax 48F7FB
|
||||
DEFINE DIVIDES_rax_by_rbx_into_rax 48F7F3
|
||||
DEFINE JUMP E9
|
||||
DEFINE JUMP_EQ 0F84
|
||||
DEFINE JUMP_NE 0F85
|
||||
DEFINE LOAD_BASE_ADDRESS_rax 488D85
|
||||
DEFINE LOAD_BYTE 0FBE00
|
||||
DEFINE LOAD_EFFECTIVE_ADDRESS_rax 488D8424
|
||||
DEFINE LOAD_EFFECTIVE_ADDRESS_rdi 488DBC24
|
||||
DEFINE LOAD_EFFECTIVE_ADDRESS_rdx 488D9424
|
||||
DEFINE LOAD_EFFECTIVE_ADDRESS_rsi 488DB424
|
||||
DEFINE LOAD_IMMEDIATE_r10 48C7C2
|
||||
DEFINE LOAD_IMMEDIATE_rax 48C7C0
|
||||
DEFINE LOAD_IMMEDIATE_rbx 48C7C3
|
||||
DEFINE LOAD_IMMEDIATE_rdi 48C7C7
|
||||
DEFINE LOAD_IMMEDIATE_rdx 48C7C2
|
||||
DEFINE LOAD_IMMEDIATE_rsi 48C7C6
|
||||
DEFINE LOAD_INTEGER 488B00
|
||||
DEFINE LOAD_INTEGER_rdi 488B3F
|
||||
DEFINE LOAD_INTEGER_rdx 488B12
|
||||
DEFINE LOAD_INTEGER_rsi 488B36
|
||||
DEFINE LOAD_RSP_IMMEDIATE_into_rax 488B8424
|
||||
DEFINE MODULUS_rax_from_rbx_into_rbx 48F7FB
|
||||
DEFINE MODULUSS_rax_from_rbx_into_rbx 48F7F3
|
||||
DEFINE MOVE_rbx_to_rax 4889D8
|
||||
DEFINE MOVE_rdx_to_rax 4889D0
|
||||
DEFINE MOVEZX 480FB6C0
|
||||
DEFINE MOVESX 4863C0
|
||||
DEFINE MULTIPLY_rax_by_rbx_into_rax 48F7EB
|
||||
DEFINE MULTIPLYS_rax_by_rbx_into_rax 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_RAX 50
|
||||
DEFINE PUSH_RBP 55
|
||||
DEFINE PUSH_RBX 53
|
||||
DEFINE PUSH_RDI 57
|
||||
DEFINE RETURN C3
|
||||
DEFINE SAL_rax_Immediate8 48C1E0
|
||||
DEFINE SAL_rax_cl 48D3E0
|
||||
DEFINE SAR_rax_cl 48D3E8
|
||||
DEFINE SETE 0F94C0
|
||||
DEFINE SETG 0F9FC0
|
||||
DEFINE SETGE 0F9DC0
|
||||
DEFINE SETL 0F9CC0
|
||||
DEFINE SETLE 0F9EC0
|
||||
DEFINE SETNE 0F95C0
|
||||
DEFINE STORE_CHAR 8803
|
||||
DEFINE STORE_INTEGER 488903
|
||||
DEFINE SUBTRACT_rax_from_rbx_into_rbx 4829C3
|
||||
DEFINE SYSCALL 0F05
|
||||
DEFINE TEST 4885C0
|
||||
DEFINE XCHG_rax_rbx 4893
|
||||
DEFINE XOR_rbx_rax_into_rax 4831D8
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int access(char* pathname, int mode)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %16"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %8"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_IMMEDIATE_rax %21"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int chdir(char* path)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %8"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_IMMEDIATE_rax %80"
|
||||
"SYSCALL");
|
||||
}
|
||||
|
||||
int fchdir(int fd)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %8"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_IMMEDIATE_rax %81"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void exit(int value);
|
||||
|
||||
void _exit(int value)
|
||||
{
|
||||
exit(value);
|
||||
}
|
||||
|
||||
int waitpid (int pid, int* status_ptr, int options)
|
||||
{
|
||||
/* Uses wait4 with struct rusage *ru set to NULL */
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %24"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %16"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rdx %8"
|
||||
"LOAD_INTEGER_rdx"
|
||||
"LOAD_IMMEDIATE_r10 %0"
|
||||
"LOAD_IMMEDIATE_rax %61"
|
||||
"SYSCALL");
|
||||
}
|
||||
|
||||
|
||||
int execve(char* file_name, char** argv, char** envp)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %24"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %16"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rdx %8"
|
||||
"LOAD_INTEGER_rdx"
|
||||
"LOAD_IMMEDIATE_rax %59"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,136 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0
|
||||
// CONSTANT stdout 1
|
||||
// CONSTANT stderr 2
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
int fgetc(FILE* f)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %8"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_IMMEDIATE_rax %0"
|
||||
"PUSH_RAX"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %0"
|
||||
"LOAD_IMMEDIATE_rdx %1"
|
||||
"SYSCALL"
|
||||
"LOAD_IMMEDIATE_rbx %0"
|
||||
"CMP"
|
||||
"POP_RAX"
|
||||
"JUMP_NE %FUNCTION_fgetc_Done"
|
||||
"LOAD_IMMEDIATE_rax %-1"
|
||||
":FUNCTION_fgetc_Done");
|
||||
}
|
||||
|
||||
void fputc(char s, FILE* f)
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_rax %1"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rdi %8"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %16"
|
||||
"LOAD_IMMEDIATE_rdx %1"
|
||||
"SYSCALL");
|
||||
}
|
||||
|
||||
/* Important values needed for open */
|
||||
// CONSTANT O_RDONLY 0
|
||||
// CONSTANT O_WRONLY 1
|
||||
// CONSTANT O_RDWR 2
|
||||
// CONSTANT O_CREAT 64
|
||||
// CONSTANT O_TRUNC 512
|
||||
/* 00700 in octal is 448*/
|
||||
// CONSTANT S_IRWXU 448
|
||||
/* 00100 in octal is 64 */
|
||||
// CONSTANT S_IXUSR 64
|
||||
/* 00200 in octal is 128 */
|
||||
// CONSTANT S_IWUSR 128
|
||||
/* 00400 in octal is 256 */
|
||||
// CONSTANT S_IRUSR 256
|
||||
|
||||
|
||||
FILE* open(char* name, int flag, int mode)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %24"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %16"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rdx %8"
|
||||
"LOAD_INTEGER_rdx"
|
||||
"LOAD_IMMEDIATE_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("LOAD_EFFECTIVE_ADDRESS_rdi %8"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_IMMEDIATE_rax %3"
|
||||
"SYSCALL");
|
||||
}
|
||||
int fclose(FILE* stream)
|
||||
{
|
||||
int error = close(stream);
|
||||
return error;
|
||||
}
|
||||
|
||||
int fflush(FILE *stream){
|
||||
/* We don't buffer, nothing to flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CONSTANT SEEK_SET 0
|
||||
// CONSTANT SEEK_CUR 1
|
||||
// CONSTANT SEEK_END 2
|
||||
|
||||
int fseek(FILE* f, long offset, int whence)
|
||||
{
|
||||
/* Uses lseek directly */
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %24"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %16"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rdx %8"
|
||||
"LOAD_INTEGER_rdx"
|
||||
"LOAD_IMMEDIATE_rax %8"
|
||||
"SYSCALL");
|
||||
}
|
||||
|
||||
void rewind(FILE* f)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int getchar()
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_rdi %0"
|
||||
"LOAD_IMMEDIATE_rax %0"
|
||||
"PUSH_RAX"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %0"
|
||||
"LOAD_IMMEDIATE_rdx %1"
|
||||
"SYSCALL"
|
||||
"LOAD_IMMEDIATE_rbx %0"
|
||||
"CMP"
|
||||
"POP_RAX"
|
||||
"JUMP_NE %FUNCTION_getchar_Done"
|
||||
"LOAD_IMMEDIATE_rax %-1"
|
||||
":FUNCTION_getchar_Done");
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT NULL 0
|
||||
|
||||
void* malloc(int size)
|
||||
{
|
||||
asm("LOAD_RSP_IMMEDIATE_into_rax %8"
|
||||
"PUSH_RAX"
|
||||
"LOAD_IMMEDIATE_rax %12"
|
||||
"LOAD_IMMEDIATE_rdi %0"
|
||||
"SYSCALL"
|
||||
"POP_RBX"
|
||||
"ADD_rax_to_rbx"
|
||||
"COPY_rbx_to_rdi"
|
||||
"PUSH_RAX"
|
||||
"PUSH_RBX"
|
||||
"LOAD_IMMEDIATE_rax %12"
|
||||
"SYSCALL"
|
||||
"POP_RBX"
|
||||
"CMP"
|
||||
"POP_RAX"
|
||||
"JUMP_EQ %FUNCTION_malloc_Done"
|
||||
"LOAD_IMMEDIATE_rax %-1"
|
||||
":FUNCTION_malloc_Done");
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_rax %1"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %8"
|
||||
"LOAD_IMMEDIATE_rdi %1"
|
||||
"LOAD_IMMEDIATE_rdx %1"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* chmod() changes the mode of the file specified whose pathname is given in
|
||||
* pathname, which is dereferenced if it is a symbolic link.
|
||||
* fchmod() changes the mode of the file referred to by the open file
|
||||
* descriptor fd.
|
||||
* The new file mode is specified in mode, which is a bit mask created by
|
||||
* ORing together zero or more of the following:
|
||||
* S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
|
||||
* S_ISGID (02000) set-group-ID (set process effective group ID on execve(2)
|
||||
* mandatory locking, as described in fcntl(2); take a new file's group from
|
||||
* parent directory, as described in chown(2) and mkdir(2))
|
||||
* S_ISVTX (01000) sticky bit (restricted deletion flag, as described in
|
||||
* unlink(2))
|
||||
* S_IRUSR (00400) read by owner
|
||||
* S_IWUSR (00200) write by owner
|
||||
* S_IXUSR (00100) execute/search by owner ("search" applies for directories
|
||||
* , and means that entries within the directory can be accessed)
|
||||
* S_IRGRP (00040) read by group
|
||||
* S_IWGRP (00020) write by group
|
||||
* S_IXGRP (00010) execute/search by group
|
||||
* S_IROTH (00004) read by others
|
||||
* S_IWOTH (00002) write by others
|
||||
* S_IXOTH (00001) execute/search by others
|
||||
*/
|
||||
|
||||
int chmod(char *pathname, int mode)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_rdi %16"
|
||||
"LOAD_INTEGER_rdi"
|
||||
"LOAD_EFFECTIVE_ADDRESS_rsi %8"
|
||||
"LOAD_INTEGER_rsi"
|
||||
"LOAD_IMMEDIATE_rax %90"
|
||||
"SYSCALL");
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_start
|
||||
|
||||
COPY_rsp_to_rbp ; Protect rsp
|
||||
|
||||
;; Prepare argv
|
||||
LOAD_BASE_ADDRESS_rax %8 ; ARGV_address = RBP + 8
|
||||
PUSH_RAX ; Put argv on the stack
|
||||
|
||||
;; Prepare envp
|
||||
COPY_rbp_to_rax ; Address we need to load from
|
||||
LOAD_INTEGER ; Get ARGC
|
||||
ADD_IMMEDIATE_to_rax %2 ; OFFSET = ARGC + 2
|
||||
SAL_rax_Immediate8 !3 ; OFFSET = OFFSET * WORDSIZE
|
||||
ADD_rbp_to_rax ; ENVP_address = RSP + OFFSET
|
||||
PUSH_RAX ; Put envp on the stack
|
||||
|
||||
;; Stack offset
|
||||
ADD_IMMEDIATE_to_rbp %8 ; Fix rbp
|
||||
|
||||
;; Perform the main loop
|
||||
CALL_IMMEDIATE %FUNCTION_main
|
||||
|
||||
;; Exit to kernel
|
||||
COPY_rax_to_rdi ; Using the return code given by main
|
||||
LOAD_IMMEDIATE_rax %0x3C ; Syscall exit
|
||||
SYSCALL ; Exit with that code
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text # 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
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text # 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
|
|
@ -1,113 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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 MEMORY E5
|
||||
DEFINE STORE32 08
|
||||
DEFINE STORE8 0C
|
||||
DEFINE LOAD32 09
|
||||
DEFINE LOAD8 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
|
||||
|
||||
# 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
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void exit(int value);
|
||||
|
||||
void _exit(int value)
|
||||
{
|
||||
exit(value);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT EXIT_FAILURE 1
|
||||
// CONSTANT EXIT_SUCCESS 0
|
||||
|
||||
void exit(int value)
|
||||
{
|
||||
asm("!4 R0 SUB R12 ARITH_ALWAYS"
|
||||
"!0 R0 LOAD32 R0 MEMORY"
|
||||
"!1 R7 LOADI8_ALWAYS"
|
||||
"SYSCALL_ALWAYS");
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0
|
||||
// CONSTANT stdout 1
|
||||
// CONSTANT stderr 2
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Important values needed for open */
|
||||
// CONSTANT O_RDONLY 0
|
||||
// CONSTANT O_WRONLY 1
|
||||
// CONSTANT O_RDWR 2
|
||||
// CONSTANT O_CREAT 64
|
||||
// CONSTANT O_TRUNC 512
|
||||
/* 00700 in octal is 448*/
|
||||
// CONSTANT S_IRWXU 448
|
||||
/* 00100 in octal is 64 */
|
||||
// CONSTANT S_IXUSR 64
|
||||
/* 00200 in octal is 128 */
|
||||
// CONSTANT S_IWUSR 128
|
||||
/* 00400 in octal is 256 */
|
||||
// CONSTANT S_IRUSR 256
|
||||
|
||||
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 fflush(FILE *stream){
|
||||
/* We don't buffer, nothing to flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CONSTANT SEEK_SET 0
|
||||
// CONSTANT SEEK_CUR 1
|
||||
// CONSTANT SEEK_END 2
|
||||
|
||||
int fseek(FILE* f, long 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");
|
||||
}
|
||||
|
||||
void rewind(FILE* f)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int fork()
|
||||
{
|
||||
asm("!2 R7 LOADI8_ALWAYS"
|
||||
"SYSCALL_ALWAYS");
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int getchar()
|
||||
{
|
||||
asm("!0 R0 LOADI8_ALWAYS"
|
||||
"{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");
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
//CONSTANT PATH_MAX 4096
|
||||
#define PATH_MAX 4096
|
||||
|
||||
int _getcwd(char* buf, size_t 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, size_t 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);
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT NULL 0
|
||||
|
||||
void* malloc(int size)
|
||||
{
|
||||
asm("!45 R7 LOADI8_ALWAYS"
|
||||
"!0 R0 LOADI8_ALWAYS"
|
||||
"SYSCALL_ALWAYS"
|
||||
"{R0} PUSH_ALWAYS"
|
||||
"!4 R1 SUB R12 ARITH_ALWAYS"
|
||||
"!0 R1 LOAD32 R1 MEMORY"
|
||||
"'0' R0 R0 ADD R1 ARITH2_ALWAYS"
|
||||
"{R0} PUSH_ALWAYS"
|
||||
"SYSCALL_ALWAYS"
|
||||
"{R1} POP_ALWAYS"
|
||||
"'0' R0 CMP R1 AUX_ALWAYS"
|
||||
"{R0} POP_ALWAYS"
|
||||
"!-1 R0 LOADI8_NE");
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
asm("!1 R0 LOADI8_ALWAYS"
|
||||
"!1 R2 LOADI8_ALWAYS"
|
||||
"!4 R7 LOADI8_ALWAYS"
|
||||
"!4 R1 SUB R12 ARITH_ALWAYS"
|
||||
"SYSCALL_ALWAYS");
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* chmod() changes the mode of the file specified whose pathname is given in
|
||||
* pathname, which is dereferenced if it is a symbolic link.
|
||||
* fchmod() changes the mode of the file referred to by the open file
|
||||
* descriptor fd.
|
||||
* The new file mode is specified in mode, which is a bit mask created by
|
||||
* ORing together zero or more of the following:
|
||||
* S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
|
||||
* S_ISGID (02000) set-group-ID (set process effective group ID on execve(2)
|
||||
* mandatory locking, as described in fcntl(2); take a new file's group from
|
||||
* parent directory, as described in chown(2) and mkdir(2))
|
||||
* S_ISVTX (01000) sticky bit (restricted deletion flag, as described in
|
||||
* unlink(2))
|
||||
* S_IRUSR (00400) read by owner
|
||||
* S_IWUSR (00200) write by owner
|
||||
* S_IXUSR (00100) execute/search by owner ("search" applies for directories
|
||||
* , and means that entries within the directory can be accessed)
|
||||
* S_IRGRP (00040) read by group
|
||||
* S_IWGRP (00020) write by group
|
||||
* S_IXGRP (00010) execute/search by group
|
||||
* S_IROTH (00004) read by others
|
||||
* S_IWOTH (00002) write by others
|
||||
* S_IXOTH (00001) execute/search by others
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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");
|
||||
}
|
|
@ -1,128 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_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
|
||||
!1 R7 LOADI8_ALWAYS ; Setup for final exit
|
||||
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
|
|
@ -1,26 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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.
|
|
@ -1,24 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
int access(char* pathname, int mode)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOAD R1 R14 4"
|
||||
"ACCESS");
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT EXIT_FAILURE 1
|
||||
// CONSTANT EXIT_SUCCESS 0
|
||||
|
||||
void exit(int value)
|
||||
{
|
||||
/* Hardware doesn't have return codes */
|
||||
asm("HALT");
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT EXIT_FAILURE 1
|
||||
// CONSTANT EXIT_SUCCESS 0
|
||||
|
||||
void exit(int value)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"EXIT");
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0x1100
|
||||
// CONSTANT stdout 0x1101
|
||||
// CONSTANT stderr 0
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
int match(char* a, char* b);
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
FILE* open_read(int filename)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"FOPEN_READ");
|
||||
}
|
||||
|
||||
FILE* open_write(int filename)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"FOPEN_WRITE");
|
||||
}
|
||||
|
||||
int fclose(FILE* stream)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"FCLOSE");
|
||||
}
|
||||
|
||||
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])
|
||||
{ /* 577 is O_WRONLY|O_CREAT|O_TRUNC, 384 is 600 in octal */
|
||||
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;
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0
|
||||
// CONSTANT stdout 1
|
||||
// CONSTANT stderr 2
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Important values needed for open */
|
||||
// CONSTANT O_RDONLY 0
|
||||
// CONSTANT O_WRONLY 1
|
||||
// CONSTANT O_RDWR 2
|
||||
// CONSTANT O_CREAT 64
|
||||
// CONSTANT O_TRUNC 512
|
||||
/* 00700 in octal is 448*/
|
||||
// CONSTANT S_IRWXU 448
|
||||
/* 00100 in octal is 64 */
|
||||
// CONSTANT S_IXUSR 64
|
||||
/* 00200 in octal is 128 */
|
||||
// CONSTANT S_IWUSR 128
|
||||
/* 00400 in octal is 256 */
|
||||
// CONSTANT S_IRUSR 256
|
||||
|
||||
FILE* open(char* filename, int flag, int mode)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOAD R1 R14 4"
|
||||
"LOAD R2 R14 8"
|
||||
"FOPEN"
|
||||
"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 fclose(FILE* stream)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"FCLOSE");
|
||||
}
|
||||
|
||||
int fflush(FILE *stream){
|
||||
/* We don't buffer, nothing to flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CONSTANT SEEK_SET 0
|
||||
// CONSTANT SEEK_CUR 1
|
||||
// CONSTANT SEEK_END 2
|
||||
|
||||
int fseek(FILE* f, long offset, int whence)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOAD R1 R14 4"
|
||||
"LOAD R2 R14 8"
|
||||
"FSEEK"
|
||||
"FALSE R2");
|
||||
}
|
||||
|
||||
void rewind(FILE* f)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int getchar()
|
||||
{
|
||||
/* tape1 is 0x1100 */
|
||||
asm("LOADUI R1 0x1100"
|
||||
"FGETC");
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int getchar()
|
||||
{
|
||||
asm("LOADUI R1 0"
|
||||
"FGETC");
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include<stdlib.h>
|
||||
//CONSTANT PATH_MAX 4096
|
||||
#define PATH_MAX 4096
|
||||
|
||||
int _getcwd(char* buf, size_t size)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOAD R1 R14 4"
|
||||
"GETCWD");
|
||||
}
|
||||
|
||||
char* getcwd(char* buf, size_t 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);
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
CONSTANT NULL 0
|
||||
|
||||
void* malloc(int size)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"ADDU R0 R12 R0"
|
||||
"SWAP R0 R12");
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
/* Console is 0 */
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOADUI R1 0"
|
||||
"FPUTC");
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
/* tape2 is 0x1101 */
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOADUI R1 0x1101"
|
||||
"FPUTC");
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void putchar(int c)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOADUI R1 1"
|
||||
"FPUTC");
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* chmod() changes the mode of the file specified whose pathname is given in
|
||||
* pathname, which is dereferenced if it is a symbolic link.
|
||||
* fchmod() changes the mode of the file referred to by the open file
|
||||
* descriptor fd.
|
||||
* The new file mode is specified in mode, which is a bit mask created by
|
||||
* ORing together zero or more of the following:
|
||||
* S_ISUID (04000) set-user-ID (set process effective user ID on execve(2))
|
||||
* S_ISGID (02000) set-group-ID (set process effective group ID on execve(2)
|
||||
* mandatory locking, as described in fcntl(2); take a new file's group from
|
||||
* parent directory, as described in chown(2) and mkdir(2))
|
||||
* S_ISVTX (01000) sticky bit (restricted deletion flag, as described in
|
||||
* unlink(2))
|
||||
* S_IRUSR (00400) read by owner
|
||||
* S_IWUSR (00200) write by owner
|
||||
* S_IXUSR (00100) execute/search by owner ("search" applies for directories
|
||||
* , and means that entries within the directory can be accessed)
|
||||
* S_IRGRP (00040) read by group
|
||||
* S_IWGRP (00020) write by group
|
||||
* S_IXGRP (00010) execute/search by group
|
||||
* S_IROTH (00004) read by others
|
||||
* S_IWOTH (00002) write by others
|
||||
* S_IXOTH (00001) execute/search by others
|
||||
*/
|
||||
|
||||
int chmod(char *pathname, int mode)
|
||||
{
|
||||
asm("LOAD R0 R14 0"
|
||||
"LOAD R1 R14 4"
|
||||
"CHMOD");
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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"
|
||||
"UNAME");
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#Registers
|
||||
DEFINE R0 0
|
||||
DEFINE R1 1
|
||||
DEFINE R2 2
|
||||
DEFINE R3 3
|
||||
DEFINE R4 4
|
||||
DEFINE R5 5
|
||||
DEFINE R6 6
|
||||
DEFINE R7 7
|
||||
DEFINE R8 8
|
||||
DEFINE R9 9
|
||||
DEFINE R10 A
|
||||
DEFINE R11 B
|
||||
DEFINE R12 C
|
||||
DEFINE R13 D
|
||||
DEFINE R14 E
|
||||
DEFINE R15 F
|
||||
|
||||
# 4OP Integer Group
|
||||
DEFINE ADD.CI 0100
|
||||
DEFINE ADD.CO 0101
|
||||
DEFINE ADD.CIO 0102
|
||||
DEFINE ADDU.CI 0103
|
||||
DEFINE ADDU.CO 0104
|
||||
DEFINE ADDU.CIO 0105
|
||||
DEFINE SUB.BI 0106
|
||||
DEFINE SUB.BO 0107
|
||||
DEFINE SUB.BIO 0108
|
||||
DEFINE SUBU.BI 0109
|
||||
DEFINE SUBU.BO 010A
|
||||
DEFINE SUBU.BIO 010B
|
||||
DEFINE MULTIPLY 010C
|
||||
DEFINE MULTIPLYU 010D
|
||||
DEFINE DIVIDE 010E
|
||||
DEFINE DIVIDEU 010F
|
||||
DEFINE MUX 0110
|
||||
DEFINE NMUX 0111
|
||||
DEFINE SORT 0112
|
||||
DEFINE SORTU 0113
|
||||
|
||||
# 3OP Integer Group
|
||||
DEFINE ADD 05000
|
||||
DEFINE ADDU 05001
|
||||
DEFINE SUB 05002
|
||||
DEFINE SUBU 05003
|
||||
DEFINE CMP 05004
|
||||
DEFINE CMPU 05005
|
||||
DEFINE MUL 05006
|
||||
DEFINE MULH 05007
|
||||
DEFINE MULU 05008
|
||||
DEFINE MULUH 05009
|
||||
DEFINE DIV 0500A
|
||||
DEFINE MOD 0500B
|
||||
DEFINE DIVU 0500C
|
||||
DEFINE MODU 0500D
|
||||
DEFINE MAX 05010
|
||||
DEFINE MAXU 05011
|
||||
DEFINE MIN 05012
|
||||
DEFINE MINU 05013
|
||||
DEFINE AND 05020
|
||||
DEFINE OR 05021
|
||||
DEFINE XOR 05022
|
||||
DEFINE NAND 05023
|
||||
DEFINE NOR 05024
|
||||
DEFINE XNOR 05025
|
||||
DEFINE MPQ 05026
|
||||
DEFINE LPQ 05027
|
||||
DEFINE CPQ 05028
|
||||
DEFINE BPQ 05029
|
||||
DEFINE SAL 05030
|
||||
DEFINE SAR 05031
|
||||
DEFINE SL0 05032
|
||||
DEFINE SR0 05033
|
||||
DEFINE SL1 05034
|
||||
DEFINE SR1 05035
|
||||
DEFINE ROL 05036
|
||||
DEFINE ROR 05037
|
||||
DEFINE LOADX 05038
|
||||
DEFINE LOADX8 05039
|
||||
DEFINE LOADXU8 0503A
|
||||
DEFINE LOADX16 0503B
|
||||
DEFINE LOADXU16 0503C
|
||||
DEFINE LOADX32 0503D
|
||||
DEFINE LOADXU32 0503E
|
||||
DEFINE STOREX 05048
|
||||
DEFINE STOREX8 05049
|
||||
DEFINE STOREX16 0504A
|
||||
DEFINE STOREX32 0504B
|
||||
DEFINE CMPJUMP.G 05050
|
||||
DEFINE CMPJUMP.GE 05051
|
||||
DEFINE CMPJUMP.E 05052
|
||||
DEFINE CMPJUMP.NE 05053
|
||||
DEFINE CMPJUMP.LE 05054
|
||||
DEFINE CMPJUMP.L 05055
|
||||
DEFINE CMPJUMPU.G 05060
|
||||
DEFINE CMPJUMPU.GE 05061
|
||||
DEFINE CMPJUMPU.LE 05064
|
||||
DEFINE CMPJUMPU.L 05065
|
||||
|
||||
# 2OP Integer Group
|
||||
DEFINE NEG 090000
|
||||
DEFINE ABS 090001
|
||||
DEFINE NABS 090002
|
||||
DEFINE SWAP 090003
|
||||
DEFINE COPY 090004
|
||||
DEFINE MOVE 090005
|
||||
DEFINE NOT 090006
|
||||
DEFINE BRANCH 090100
|
||||
DEFINE CALL 090101
|
||||
DEFINE PUSHR 090200
|
||||
DEFINE PUSH8 090201
|
||||
DEFINE PUSH16 090202
|
||||
DEFINE PUSH32 090203
|
||||
DEFINE POPR 090280
|
||||
DEFINE POP8 090281
|
||||
DEFINE POPU8 090282
|
||||
DEFINE POP16 090283
|
||||
DEFINE POPU16 090284
|
||||
DEFINE POP32 090285
|
||||
DEFINE POPU32 090286
|
||||
DEFINE CMPSKIP.G 090300
|
||||
DEFINE CMPSKIP.GE 090301
|
||||
DEFINE CMPSKIP.E 090302
|
||||
DEFINE CMPSKIP.NE 090303
|
||||
DEFINE CMPSKIP.LE 090304
|
||||
DEFINE CMPSKIP.L 090305
|
||||
DEFINE CMPSKIPU.G 090380
|
||||
DEFINE CMPSKIPU.GE 090381
|
||||
DEFINE CMPSKIPU.LE 090384
|
||||
DEFINE CMPSKIPU.L 090385
|
||||
|
||||
# 1OP Group
|
||||
DEFINE READPC 0D00000
|
||||
DEFINE READSCID 0D00001
|
||||
DEFINE FALSE 0D00002
|
||||
DEFINE TRUE 0D00003
|
||||
DEFINE JSR_COROUTINE 0D01000
|
||||
DEFINE RET 0D01001
|
||||
DEFINE PUSHPC 0D02000
|
||||
DEFINE POPPC 0D02001
|
||||
|
||||
# 2OPI Group
|
||||
DEFINE ADDI E1000E
|
||||
DEFINE ADDUI E1000F
|
||||
DEFINE SUBI E10010
|
||||
DEFINE SUBUI E10011
|
||||
DEFINE CMPI E10012
|
||||
DEFINE LOAD E10013
|
||||
DEFINE LOAD8 E10014
|
||||
DEFINE LOADU8 E10015
|
||||
DEFINE LOAD16 E10016
|
||||
DEFINE LOADU16 E10017
|
||||
DEFINE LOAD32 E10018
|
||||
DEFINE LOADU32 E10019
|
||||
DEFINE CMPUI E1001F
|
||||
DEFINE STORE E10020
|
||||
DEFINE STORE8 E10021
|
||||
DEFINE STORE16 E10022
|
||||
DEFINE STORE32 E10023
|
||||
DEFINE ANDI E100B0
|
||||
DEFINE ORI E100B1
|
||||
DEFINE XORI E100B2
|
||||
DEFINE NANDI E100B3
|
||||
DEFINE NORI E100B4
|
||||
DEFINE XNORI E100B5
|
||||
DEFINE CMPJUMPI.G E100C0
|
||||
DEFINE CMPJUMPI.GE E100C1
|
||||
DEFINE CMPJUMPI.E E100C2
|
||||
DEFINE CMPJUMPI.NE E100C3
|
||||
DEFINE CMPJUMPI.LE E100C4
|
||||
DEFINE CMPJUMPI.L E100C5
|
||||
DEFINE CMPJUMPUI.G E100D0
|
||||
DEFINE CMPJUMPUI.GE E100D1
|
||||
DEFINE CMPJUMPUI.LE E100D4
|
||||
DEFINE CMPJUMPUI.L E100D5
|
||||
|
||||
# 1OPI Group
|
||||
DEFINE JUMP.C E0002C0
|
||||
DEFINE JUMP.B E0002C1
|
||||
DEFINE JUMP.O E0002C2
|
||||
DEFINE JUMP.G E0002C3
|
||||
DEFINE JUMP.GE E0002C4
|
||||
DEFINE JUMP.E E0002C5
|
||||
DEFINE JUMP.NE E0002C6
|
||||
DEFINE JUMP.LE E0002C7
|
||||
DEFINE JUMP.L E0002C8
|
||||
DEFINE JUMP.Z E0002C9
|
||||
DEFINE JUMP.NZ E0002CA
|
||||
DEFINE JUMP.P E0002CB
|
||||
DEFINE JUMP.NP E0002CC
|
||||
DEFINE CALLI E0002D0
|
||||
DEFINE LOADI E0002D1
|
||||
DEFINE LOADUI E0002D2
|
||||
DEFINE SALI E0002D3
|
||||
DEFINE SARI E0002D4
|
||||
DEFINE SL0I E0002D5
|
||||
DEFINE SR0I E0002D6
|
||||
DEFINE SL1I E0002D7
|
||||
DEFINE SR1I E0002D8
|
||||
DEFINE LOADR E0002E0
|
||||
DEFINE LOADR8 E0002E1
|
||||
DEFINE LOADRU8 E0002E2
|
||||
DEFINE LOADR16 E0002E3
|
||||
DEFINE LOADRU16 E0002E4
|
||||
DEFINE LOADR32 E0002E5
|
||||
DEFINE LOADRU32 E0002E6
|
||||
DEFINE STORER E0002F0
|
||||
DEFINE STORER8 E0002F1
|
||||
DEFINE STORER16 E0002F2
|
||||
DEFINE STORER32 E0002F3
|
||||
DEFINE CMPSKIPI.G E000A00
|
||||
DEFINE CMPSKIPI.GE E000A01
|
||||
DEFINE CMPSKIPI.E E000A02
|
||||
DEFINE CMPSKIPI.NE E000A03
|
||||
DEFINE CMPSKIPI.LE E000A04
|
||||
DEFINE CMPSKIPI.L E000A05
|
||||
DEFINE CMPSKIPUI.G E000A10
|
||||
DEFINE CMPSKIPUI.GE E000A11
|
||||
DEFINE CMPSKIPUI.LE E000A14
|
||||
DEFINE CMPSKIPUI.L E000A15
|
||||
|
||||
# 0OPI Group
|
||||
DEFINE JUMP 3C00
|
||||
|
||||
# HALCODE Group
|
||||
DEFINE FOPEN_READ 42100000
|
||||
DEFINE FOPEN_WRITE 42100001
|
||||
DEFINE FCLOSE 42100002
|
||||
DEFINE REWIND 42100003
|
||||
DEFINE FSEEK 42100004
|
||||
DEFINE FGETC 42100100
|
||||
DEFINE FPUTC 42100200
|
||||
DEFINE HAL_MEM 42110000
|
||||
|
||||
# 0OP Group
|
||||
DEFINE NULL 00000000
|
||||
DEFINE HALT FFFFFFFF
|
|
@ -1,260 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#Registers
|
||||
DEFINE R0 0
|
||||
DEFINE R1 1
|
||||
DEFINE R2 2
|
||||
DEFINE R3 3
|
||||
DEFINE R4 4
|
||||
DEFINE R5 5
|
||||
DEFINE R6 6
|
||||
DEFINE R7 7
|
||||
DEFINE R8 8
|
||||
DEFINE R9 9
|
||||
DEFINE R10 A
|
||||
DEFINE R11 B
|
||||
DEFINE R12 C
|
||||
DEFINE R13 D
|
||||
DEFINE R14 E
|
||||
DEFINE R15 F
|
||||
|
||||
# 4OP Integer Group
|
||||
DEFINE ADD.CI 0100
|
||||
DEFINE ADD.CO 0101
|
||||
DEFINE ADD.CIO 0102
|
||||
DEFINE ADDU.CI 0103
|
||||
DEFINE ADDU.CO 0104
|
||||
DEFINE ADDU.CIO 0105
|
||||
DEFINE SUB.BI 0106
|
||||
DEFINE SUB.BO 0107
|
||||
DEFINE SUB.BIO 0108
|
||||
DEFINE SUBU.BI 0109
|
||||
DEFINE SUBU.BO 010A
|
||||
DEFINE SUBU.BIO 010B
|
||||
DEFINE MULTIPLY 010C
|
||||
DEFINE MULTIPLYU 010D
|
||||
DEFINE DIVIDE 010E
|
||||
DEFINE DIVIDEU 010F
|
||||
DEFINE MUX 0110
|
||||
DEFINE NMUX 0111
|
||||
DEFINE SORT 0112
|
||||
DEFINE SORTU 0113
|
||||
|
||||
# 3OP Integer Group
|
||||
DEFINE ADD 05000
|
||||
DEFINE ADDU 05001
|
||||
DEFINE SUB 05002
|
||||
DEFINE SUBU 05003
|
||||
DEFINE CMP 05004
|
||||
DEFINE CMPU 05005
|
||||
DEFINE MUL 05006
|
||||
DEFINE MULH 05007
|
||||
DEFINE MULU 05008
|
||||
DEFINE MULUH 05009
|
||||
DEFINE DIV 0500A
|
||||
DEFINE MOD 0500B
|
||||
DEFINE DIVU 0500C
|
||||
DEFINE MODU 0500D
|
||||
DEFINE MAX 05010
|
||||
DEFINE MAXU 05011
|
||||
DEFINE MIN 05012
|
||||
DEFINE MINU 05013
|
||||
DEFINE AND 05020
|
||||
DEFINE OR 05021
|
||||
DEFINE XOR 05022
|
||||
DEFINE NAND 05023
|
||||
DEFINE NOR 05024
|
||||
DEFINE XNOR 05025
|
||||
DEFINE MPQ 05026
|
||||
DEFINE LPQ 05027
|
||||
DEFINE CPQ 05028
|
||||
DEFINE BPQ 05029
|
||||
DEFINE SAL 05030
|
||||
DEFINE SAR 05031
|
||||
DEFINE SL0 05032
|
||||
DEFINE SR0 05033
|
||||
DEFINE SL1 05034
|
||||
DEFINE SR1 05035
|
||||
DEFINE ROL 05036
|
||||
DEFINE ROR 05037
|
||||
DEFINE LOADX 05038
|
||||
DEFINE LOADX8 05039
|
||||
DEFINE LOADXU8 0503A
|
||||
DEFINE LOADX16 0503B
|
||||
DEFINE LOADXU16 0503C
|
||||
DEFINE LOADX32 0503D
|
||||
DEFINE LOADXU32 0503E
|
||||
DEFINE STOREX 05048
|
||||
DEFINE STOREX8 05049
|
||||
DEFINE STOREX16 0504A
|
||||
DEFINE STOREX32 0504B
|
||||
DEFINE CMPJUMP.G 05050
|
||||
DEFINE CMPJUMP.GE 05051
|
||||
DEFINE CMPJUMP.E 05052
|
||||
DEFINE CMPJUMP.NE 05053
|
||||
DEFINE CMPJUMP.LE 05054
|
||||
DEFINE CMPJUMP.L 05055
|
||||
DEFINE CMPJUMPU.G 05060
|
||||
DEFINE CMPJUMPU.GE 05061
|
||||
DEFINE CMPJUMPU.LE 05064
|
||||
DEFINE CMPJUMPU.L 05065
|
||||
|
||||
# 2OP Integer Group
|
||||
DEFINE NEG 090000
|
||||
DEFINE ABS 090001
|
||||
DEFINE NABS 090002
|
||||
DEFINE SWAP 090003
|
||||
DEFINE COPY 090004
|
||||
DEFINE MOVE 090005
|
||||
DEFINE NOT 090006
|
||||
DEFINE BRANCH 090100
|
||||
DEFINE CALL 090101
|
||||
DEFINE PUSHR 090200
|
||||
DEFINE PUSH8 090201
|
||||
DEFINE PUSH16 090202
|
||||
DEFINE PUSH32 090203
|
||||
DEFINE POPR 090280
|
||||
DEFINE POP8 090281
|
||||
DEFINE POPU8 090282
|
||||
DEFINE POP16 090283
|
||||
DEFINE POPU16 090284
|
||||
DEFINE POP32 090285
|
||||
DEFINE POPU32 090286
|
||||
DEFINE CMPSKIP.G 090300
|
||||
DEFINE CMPSKIP.GE 090301
|
||||
DEFINE CMPSKIP.E 090302
|
||||
DEFINE CMPSKIP.NE 090303
|
||||
DEFINE CMPSKIP.LE 090304
|
||||
DEFINE CMPSKIP.L 090305
|
||||
DEFINE CMPSKIPU.G 090380
|
||||
DEFINE CMPSKIPU.GE 090381
|
||||
DEFINE CMPSKIPU.LE 090384
|
||||
DEFINE CMPSKIPU.L 090385
|
||||
|
||||
# 1OP Group
|
||||
DEFINE READPC 0D00000
|
||||
DEFINE READSCID 0D00001
|
||||
DEFINE FALSE 0D00002
|
||||
DEFINE TRUE 0D00003
|
||||
DEFINE JSR_COROUTINE 0D01000
|
||||
DEFINE RET 0D01001
|
||||
DEFINE PUSHPC 0D02000
|
||||
DEFINE POPPC 0D02001
|
||||
|
||||
# 2OPI Group
|
||||
DEFINE ADDI E1000E
|
||||
DEFINE ADDUI E1000F
|
||||
DEFINE SUBI E10010
|
||||
DEFINE SUBUI E10011
|
||||
DEFINE CMPI E10012
|
||||
DEFINE LOAD E10013
|
||||
DEFINE LOAD8 E10014
|
||||
DEFINE LOADU8 E10015
|
||||
DEFINE LOAD16 E10016
|
||||
DEFINE LOADU16 E10017
|
||||
DEFINE LOAD32 E10018
|
||||
DEFINE LOADU32 E10019
|
||||
DEFINE CMPUI E1001F
|
||||
DEFINE STORE E10020
|
||||
DEFINE STORE8 E10021
|
||||
DEFINE STORE16 E10022
|
||||
DEFINE STORE32 E10023
|
||||
DEFINE ANDI E100B0
|
||||
DEFINE ORI E100B1
|
||||
DEFINE XORI E100B2
|
||||
DEFINE NANDI E100B3
|
||||
DEFINE NORI E100B4
|
||||
DEFINE XNORI E100B5
|
||||
DEFINE CMPJUMPI.G E100C0
|
||||
DEFINE CMPJUMPI.GE E100C1
|
||||
DEFINE CMPJUMPI.E E100C2
|
||||
DEFINE CMPJUMPI.NE E100C3
|
||||
DEFINE CMPJUMPI.LE E100C4
|
||||
DEFINE CMPJUMPI.L E100C5
|
||||
DEFINE CMPJUMPUI.G E100D0
|
||||
DEFINE CMPJUMPUI.GE E100D1
|
||||
DEFINE CMPJUMPUI.LE E100D4
|
||||
DEFINE CMPJUMPUI.L E100D5
|
||||
|
||||
# 1OPI Group
|
||||
DEFINE JUMP.C E0002C0
|
||||
DEFINE JUMP.B E0002C1
|
||||
DEFINE JUMP.O E0002C2
|
||||
DEFINE JUMP.G E0002C3
|
||||
DEFINE JUMP.GE E0002C4
|
||||
DEFINE JUMP.E E0002C5
|
||||
DEFINE JUMP.NE E0002C6
|
||||
DEFINE JUMP.LE E0002C7
|
||||
DEFINE JUMP.L E0002C8
|
||||
DEFINE JUMP.Z E0002C9
|
||||
DEFINE JUMP.NZ E0002CA
|
||||
DEFINE JUMP.P E0002CB
|
||||
DEFINE JUMP.NP E0002CC
|
||||
DEFINE CALLI E0002D0
|
||||
DEFINE LOADI E0002D1
|
||||
DEFINE LOADUI E0002D2
|
||||
DEFINE SALI E0002D3
|
||||
DEFINE SARI E0002D4
|
||||
DEFINE SL0I E0002D5
|
||||
DEFINE SR0I E0002D6
|
||||
DEFINE SL1I E0002D7
|
||||
DEFINE SR1I E0002D8
|
||||
DEFINE LOADR E0002E0
|
||||
DEFINE LOADR8 E0002E1
|
||||
DEFINE LOADRU8 E0002E2
|
||||
DEFINE LOADR16 E0002E3
|
||||
DEFINE LOADRU16 E0002E4
|
||||
DEFINE LOADR32 E0002E5
|
||||
DEFINE LOADRU32 E0002E6
|
||||
DEFINE STORER E0002F0
|
||||
DEFINE STORER8 E0002F1
|
||||
DEFINE STORER16 E0002F2
|
||||
DEFINE STORER32 E0002F3
|
||||
DEFINE CMPSKIPI.G E000A00
|
||||
DEFINE CMPSKIPI.GE E000A01
|
||||
DEFINE CMPSKIPI.E E000A02
|
||||
DEFINE CMPSKIPI.NE E000A03
|
||||
DEFINE CMPSKIPI.LE E000A04
|
||||
DEFINE CMPSKIPI.L E000A05
|
||||
DEFINE CMPSKIPUI.G E000A10
|
||||
DEFINE CMPSKIPUI.GE E000A11
|
||||
DEFINE CMPSKIPUI.LE E000A14
|
||||
DEFINE CMPSKIPUI.L E000A15
|
||||
|
||||
# 0OPI Group
|
||||
DEFINE JUMP 3C00
|
||||
|
||||
# HALCODE Group
|
||||
DEFINE FOPEN 42000002
|
||||
DEFINE FCLOSE 42000003
|
||||
DEFINE FSEEK 42000008
|
||||
DEFINE ACCESS 42000015
|
||||
DEFINE EXIT 4200003C
|
||||
DEFINE UNAME 4200003F
|
||||
DEFINE GETCWD 4200004F
|
||||
DEFINE CHDIR 42000050
|
||||
DEFINE FCHDIR 42000051
|
||||
DEFINE CHMOD 4200005A
|
||||
DEFINE FGETC 42100100
|
||||
DEFINE FPUTC 42100200
|
||||
|
||||
# 0OP Group
|
||||
DEFINE NOP 00000000
|
||||
DEFINE HALT FFFFFFFF
|
||||
|
||||
# M2-Planet Standard
|
||||
DEFINE NULL 00000000
|
|
@ -1,37 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_start
|
||||
LOADR32 R12 @HEAP ; Setup HEAP pointer
|
||||
;; 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
|
||||
|
||||
;; Exit to kernel
|
||||
EXIT ; Return what is in R0
|
||||
|
||||
;; Our default heap pointer
|
||||
:HEAP
|
||||
'00100000'
|
|
@ -1,34 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_start
|
||||
;; Prep TAPE_02
|
||||
LOADUI R0 0x1101
|
||||
FOPEN_WRITE
|
||||
|
||||
;; Prep TAPE_01
|
||||
LOADUI R0 0x1100
|
||||
FOPEN_READ
|
||||
|
||||
LOADR32 R12 @HEAP ; Setup HEAP pointer
|
||||
LOADUI R15 $STACK ; Setup initial stack pointer
|
||||
COPY R14 R15 ; Setup initial base pointer
|
||||
CALLI R15 @FUNCTION_main ; Go to main
|
||||
HALT ; Exit to kernel
|
||||
|
||||
;; Our default heap pointer
|
||||
:HEAP
|
||||
'00100000'
|
|
@ -1,38 +0,0 @@
|
|||
## 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
:_start
|
||||
LOADR32 R12 @HEAP ; Setup HEAP pointer
|
||||
|
||||
; Setup initial stack pointer
|
||||
LOADR R15 4
|
||||
JUMP 4
|
||||
&STACK
|
||||
|
||||
; Setup initial base pointer
|
||||
COPY R14 R15
|
||||
|
||||
; Perform the main loop
|
||||
LOADR R0 4
|
||||
JUMP 4
|
||||
&FUNCTION_main
|
||||
CALL R0 R15
|
||||
|
||||
HALT ; Exit to kernel
|
||||
|
||||
;; Our default heap pointer
|
||||
:HEAP
|
||||
'00100000'
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text # 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
|
|
@ -1,74 +0,0 @@
|
|||
### Copyright (C) 2016 Jeremiah Orians
|
||||
### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
|
||||
### 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
### stage0's hex2 format
|
||||
### !<label> 1 byte relative
|
||||
### $<label> 2 byte address
|
||||
### @<label> 2 byte relative
|
||||
### &<label> 4 byte address
|
||||
### %<label> 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
|
||||
|
||||
00 # e_ident[EI_OSABI] Set at 0 because none cares
|
||||
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
|
||||
|
||||
&ELF_text # 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
|
|
@ -1,26 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int access(char* pathname, int mode)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %8"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %4"
|
||||
"LOAD_INTEGER_ecx"
|
||||
"LOAD_IMMEDIATE_eax %33"
|
||||
"INT_80");
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int chdir(char* path)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_IMMEDIATE_eax %12"
|
||||
"INT_80");
|
||||
}
|
||||
|
||||
int fchdir(int fd)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_IMMEDIATE_eax %133"
|
||||
"INT_80");
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
void exit(int value);
|
||||
|
||||
void _exit(int value)
|
||||
{
|
||||
exit(value);
|
||||
}
|
||||
|
||||
int waitpid (int pid, int* status_ptr, int options)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
||||
"LOAD_INTEGER_ecx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_edx %4"
|
||||
"LOAD_INTEGER_edx"
|
||||
"LOAD_IMMEDIATE_eax %7"
|
||||
"INT_80");
|
||||
}
|
||||
|
||||
|
||||
int execve(char* file_name, char** argv, char** envp)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
||||
"LOAD_INTEGER_ecx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_edx %4"
|
||||
"LOAD_INTEGER_edx"
|
||||
"LOAD_IMMEDIATE_eax %11"
|
||||
"INT_80");
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT EXIT_FAILURE 1
|
||||
// CONSTANT EXIT_SUCCESS 0
|
||||
|
||||
void exit(int value)
|
||||
{
|
||||
asm("POP_ebx"
|
||||
"POP_ebx"
|
||||
"LOAD_IMMEDIATE_eax %1"
|
||||
"INT_80");
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// CONSTANT stdin 0
|
||||
// CONSTANT stdout 1
|
||||
// CONSTANT stderr 2
|
||||
// CONSTANT EOF 0xFFFFFFFF
|
||||
|
||||
int fgetc(FILE* f)
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_eax %3"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"PUSH_ebx"
|
||||
"COPY_esp_to_ecx"
|
||||
"LOAD_IMMEDIATE_edx %1"
|
||||
"INT_80"
|
||||
"TEST"
|
||||
"POP_eax"
|
||||
"JUMP_NE8 !FUNCTION_fgetc_Done"
|
||||
"LOAD_IMMEDIATE_eax %-1"
|
||||
":FUNCTION_fgetc_Done");
|
||||
}
|
||||
|
||||
void fputc(char s, FILE* f)
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_eax %4"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ebx %4"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
||||
"LOAD_IMMEDIATE_edx %1"
|
||||
"INT_80");
|
||||
}
|
||||
|
||||
/* Important values needed for open */
|
||||
// CONSTANT O_RDONLY 0
|
||||
// CONSTANT O_WRONLY 1
|
||||
// CONSTANT O_RDWR 2
|
||||
// CONSTANT O_CREAT 64
|
||||
// CONSTANT O_TRUNC 512
|
||||
/* 00700 in octal is 448*/
|
||||
// CONSTANT S_IRWXU 448
|
||||
/* 00100 in octal is 64 */
|
||||
// CONSTANT S_IXUSR 64
|
||||
/* 00200 in octal is 128 */
|
||||
// CONSTANT S_IWUSR 128
|
||||
/* 00400 in octal is 256 */
|
||||
// CONSTANT S_IRUSR 256
|
||||
|
||||
FILE* open(char* name, int flag, int mode)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
||||
"LOAD_INTEGER_ecx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_edx %4"
|
||||
"LOAD_INTEGER_edx"
|
||||
"LOAD_IMMEDIATE_eax %5"
|
||||
"INT_80");
|
||||
}
|
||||
|
||||
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_EFFECTIVE_ADDRESS_ebx %4"
|
||||
"LOAD_IMMEDIATE_eax %6"
|
||||
"INT_80");
|
||||
}
|
||||
int fclose(FILE* stream)
|
||||
{
|
||||
int error = close(stream);
|
||||
return error;
|
||||
}
|
||||
|
||||
int fflush(FILE *stream){
|
||||
/* We don't buffer, nothing to flush */
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CONSTANT SEEK_SET 0
|
||||
// CONSTANT SEEK_CUR 1
|
||||
// CONSTANT SEEK_END 2
|
||||
|
||||
/* We just use lseek directly */
|
||||
int fseek(FILE* f, long offset, int whence)
|
||||
{
|
||||
asm("LOAD_EFFECTIVE_ADDRESS_ebx %12"
|
||||
"LOAD_INTEGER_ebx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_ecx %8"
|
||||
"LOAD_INTEGER_ecx"
|
||||
"LOAD_EFFECTIVE_ADDRESS_edx %4"
|
||||
"LOAD_INTEGER_edx"
|
||||
"LOAD_IMMEDIATE_eax %19"
|
||||
"INT_80");
|
||||
}
|
||||
|
||||
void rewind(FILE* f)
|
||||
{
|
||||
fseek(f, 0, SEEK_SET);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int fork()
|
||||
{
|
||||
asm("LOAD_IMMEDIATE_eax %2"
|
||||
"LOAD_IMMEDIATE_ebx %0"
|
||||
"INT_80");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue