Compare commits

...

200 Commits

Author SHA1 Message Date
Jeremiah Orians 754c5de7d9
Add note about big endian architectures 2023-04-30 18:36:30 -04:00
Andrius Štikonas 85dd953b70 Add padding when loading global ints on 64-bit arches. 2023-04-30 23:18:48 +01:00
Jeremiah Orians f02aaaf67b
Update checksums to match 2023-01-08 20:23:19 -05:00
Andrius Štikonas b908dac7c5 Fix macro processing when they have brackets. 2023-01-08 00:56:57 +00:00
Andrius Štikonas a950c3088b Adapt tests to M2libc changes. 2022-12-31 20:55:50 +00:00
Jeremiah Orians 286964d5f8
Properly remove blocks that aren't executed 2022-12-10 20:55:41 -05:00
Andrius Štikonas dba5c792c0 Make sure to use signed/unsigned instructions in load_value. 2022-12-10 18:04:46 +00:00
Andrius Štikonas 4f17e046e8 Fix support for arrays of structs. 2022-12-07 23:47:17 +00:00
Andrius Štikonas 259ff86c1b Add support for . operator that is after array. 2022-12-06 21:42:30 +00:00
Andrius Štikonas 39ca206412 Fix segfault. 2022-12-04 20:57:33 +00:00
Jeremiah Orians ab8cc2dd7f
Fixed unupdated checksum 2022-12-03 21:17:29 -05:00
Andrius Štikonas 62b53a554e Implement fixed sized integers: (u)int8_t, (u)int16_t, (u)int32_t. 2022-12-04 02:04:36 +00:00
Andrius Štikonas a9a0fe670b Fix doubly indirect struct type. 2022-12-02 21:59:20 +00:00
Andrius Štikonas d310700151 Switch to new GAS style x86 defines. 2022-12-02 21:50:42 +00:00
Andrius Štikonas 12d40f6c82 Update M2libc submodule. 2022-11-06 18:16:52 +00:00
Andrius Štikonas 18a7484a99 Add support for local structs. 2022-11-06 18:15:26 +00:00
Andrius Štikonas bf66daaf4c Chage riscv stack depth sign convention to match x86 and amd64. 2022-11-06 17:11:20 +00:00
Andrius Štikonas 7e7558768a Add support for global structs. 2022-11-05 23:30:46 +00:00
Andrius Štikonas adb4fb3781 make clean should cleanup all tests. 2022-10-26 00:38:43 +01:00
Andrius Štikonas b8664784b6 Fix a typo. 2022-10-25 00:44:29 +01:00
Andrius Štikonas f7fcc0af6e Adapt to M2libc changes.
* Some test includes have changed.
* New GAS style amd64 defines.
* Make M2-Planet output position independent code on amd64.
2022-10-09 14:15:07 +01:00
Jeremiah Orians 62c6f6c80e
Catching another segfault 2022-09-21 23:53:07 -04:00
Jeremiah c064b344dd
Merge pull request #40 from stikonas/master
Fix a typo.
2022-06-30 22:21:55 -04:00
Andrius Štikonas cbd7f67e93 Fix a typo. 2022-06-22 18:23:26 +01:00
Jeremiah Orians 73b39a8981
Took 4 days to find this segfault 2022-05-23 23:51:38 -04:00
Jeremiah Orians c50dcade62
Even more segfaults 2022-05-19 19:40:19 -04:00
Jeremiah Orians 65444b33d2
Clearing out more segfaults 2022-05-18 07:37:42 -04:00
Jeremiah Orians 0a07af340b
Found new segfaults 2022-05-14 21:51:09 -04:00
Jeremiah Orians fba6dffb66
Fix checksums and add support for #warning 2022-05-09 06:55:22 -04:00
Jeremiah Orians c9b9920986
Release_1.10.0 2022-05-01 14:24:47 -04:00
Jeremiah Orians a983ffaa63
fix handling of #FILENAME statements 2022-01-22 10:22:02 -05:00
Jeremiah Orians 406d0856df
Backport macro functionality to better handle nested #if statements 2022-01-21 22:35:45 -05:00
Jeremiah Orians 7a12113e2a
You are now able to change filename within a file with #FILENAME $name $linenumber 2021-12-11 07:43:00 -05:00
Andrius Štikonas a495e6faf6 Update error message to include riscv32. 2021-12-04 18:35:00 +00:00
Andrius Štikonas 695b74e6f9 After test1000 copy the correct binary to bin/M2-Planet. 2021-12-03 21:36:38 +00:00
Andrius Štikonas 823be93875 Enable riscv32 tests. 2021-12-03 21:33:55 +00:00
Andrius Štikonas 1e784f5afb Add riscv32 port. 2021-12-02 22:41:27 +00:00
Andrius Štikonas 646bd15b19 Remove old function. 2021-11-22 00:41:06 +00:00
Jeremiah Orians 9613c28c4b
Catch segfault caused by missing C statements 2021-11-16 22:01:35 -05:00
Andrius Štikonas 185ef7a7c2 Improve handling of compound assignment operators.
Previously, compound assignment operators were replaced in preprocessor.
This only worked for simple cases where we only had 1-token variable.

This commit switches to proper implementation in the parser.
2021-11-15 00:06:08 +00:00
Andrius Štikonas 511601bcd9 Revert "Add support for pre-increment and pre-decrement operators."
This reverts commit ab49bcafa4.
2021-11-13 20:55:11 +00:00
Andrius Štikonas ab49bcafa4 Add support for pre-increment and pre-decrement operators.
At the moment there is a limitation on only one unary operator,
so things like *++p wouldn't work but ++*p would work.
2021-11-12 19:37:54 +00:00
Andrius Štikonas ba51f3dcc8 Fix a crash. 2021-11-11 23:54:44 +00:00
Andrius Štikonas b2414918cc Add support for assignment operators. 2021-11-11 21:18:14 +00:00
Andrius Štikonas 575f91cac1 Fix typos / add copyright. 2021-11-11 15:21:28 +00:00
Jeremiah Orians a025387b81
Catch walking off the end of a variable dereference 2021-11-11 09:48:26 -05:00
Andrius Štikonas 6ebe45f369 Implement variable dereferencing. 2021-11-10 00:14:30 +00:00
Jeremiah Orians 6d4d6c56ea
Catch the special case of attempting to remove a NULL macro token 2021-11-07 19:49:57 -05:00
Jeremiah Orians a09d9dcfd8
Add basic test for multi-dimensional arrays 2021-11-07 19:21:41 -05:00
Andrius Štikonas 546cb1ac95 Add support for char** arrays. 2021-11-07 21:18:59 +00:00
Jeremiah Orians cdb09b1608
Catch trying to expand nulls 2021-11-07 00:19:20 -04:00
Jeremiah Orians ff65efa99e
Catch lookup_macro being passed NULL 2021-11-06 22:49:34 -04:00
Jeremiah Orians 876ebe7c68
catch half broken #define (statements 2021-11-06 22:36:02 -04:00
Jeremiah Orians 9997d7a275
catch garbage at the end of a #define 2021-11-06 21:55:22 -04:00
Andrius Štikonas 4c310a3f6d Add a missing newline. 2021-11-02 22:04:11 +00:00
Andrius Štikonas 2da7b3f9a0 Implement #undef. 2021-11-02 22:04:11 +00:00
Andrius Štikonas e3651879a5 Define arch specific variables. 2021-11-01 20:50:11 +00:00
Andrius Štikonas de8f47fa9c Add support for evaluating macro variables. 2021-11-01 20:49:11 +00:00
Andrius Štikonas 7de9e684a6 Implement #error statement in preprocessor. 2021-10-31 23:33:00 +00:00
Andrius Štikonas 7a7bfd4529 Implement #ifdef and #ifndef. 2021-10-30 22:51:17 +01:00
Andrius Štikonas 945743e2c6 Add support for empty defines. 2021-10-30 22:16:24 +01:00
Jeremiah Orians 6c59218781
Clean up RISCV tests 2021-10-28 21:45:32 -04:00
Jeremiah Orians 54e5daace4
Update test1000 sha256sum 2021-10-28 21:35:06 -04:00
Andrius Štikonas a900bc6632 Implement C99 negation.
!a is 1 if a == 0 and 0 otherwise.
2021-10-29 00:52:29 +01:00
Jeremiah Orians d8fb878d7a
Correct #define behavior inside of #if/#elif/#else/#endif blocks 2021-10-27 22:22:49 -04:00
Jeremiah Orians 55929d4ddf
Catch segfault for half defined #defines and provide a warning for #unkowns 2021-10-21 21:27:16 -04:00
Jeremiah Orians 67786705a5
Update M2libc for more efficient RISC-V syscalls 2021-10-21 21:10:53 -04:00
Jeremiah Orians ffe4e5f66e
better validate arguments passed 2021-10-04 20:49:44 -04:00
Jeremiah Orians ae9e700592
Release_1.9.0 2021-10-03 09:34:22 -04:00
Andrius Štikonas 56ee526c4c Implement support for large immediates on RISC-V. 2021-10-03 11:37:03 +01:00
Jeremiah Orians 5e74995c13
Catch truncated function calls and truncated array statements 2021-10-02 22:02:39 -04:00
Jeremiah Orians 0577243444
Fix Problem with global arrays #18 2021-10-02 10:38:04 -04:00
Jeremiah Orians 4af9b79c1b
restore removed test checksums 2021-10-02 08:24:07 -04:00
Andrius Štikonas bbf67601e1 Add tests for riscv64. 2021-10-02 13:13:15 +01:00
Jeremiah Orians 8c3fa49936
Breaking update in blood-elf 2021-10-02 07:09:46 -04:00
Andrius Štikonas ae48dbd6cb Add riscv64 port. 2021-10-02 11:59:21 +01:00
Jeremiah Orians 7fb9d682ec
Update M2libc to enable RISC-V Development 2021-09-30 20:10:28 -04:00
Jeremiah Orians 745998ac13
Fix global array initialization to allocate the correct amount of memory 2021-06-26 11:58:13 -04:00
Jeremiah Orians 99df87bc0d
Breakup program to reduce complexity and risk of errors 2021-06-26 11:51:54 -04:00
Jeremiah Orians b37dfc7b12
Report proper error message for negative global array values. Thank you melg8 2021-06-26 10:53:45 -04:00
Jeremiah Orians 3bac25a1ac
Fix issues with HACKING document 2021-06-23 20:12:20 -04:00
Jeremiah Orians 51dfec1791
Fixed Global buffer overflow in collect_weird_string thanks to Melg8 2021-06-23 18:57:56 -04:00
Jeremiah Orians a3c14bcd1b
Fixed Memory leak, thanks melg8 2021-06-23 07:58:11 -04:00
Jeremiah Orians 8bc09f2b2e
Fixed hang on large global arrays. Thanks melg8 2021-06-23 07:32:40 -04:00
Jeremiah Orians a925f90c3b
Preparing for next release cycle 2021-06-08 23:10:22 -04:00
Jeremiah Orians 0c1c22bc2f
Release_1.8.0 2021-06-08 23:05:36 -04:00
Jeremiah Orians da542698e7
Fix all special cases where line number was wrong 2021-05-28 23:27:17 -04:00
Jeremiah Orians cece07145c
Update checksums to reflect new cc_types.c code in test1000 2021-05-02 10:52:29 -04:00
Jan (janneke) Nieuwenhuizen d223581d4e Skip "extern" in type definitions.
This makes supporting gcc >= 10 easier in GNU Mes.

* cc_types.c (type_name): Skip "extern".
2021-05-02 16:14:53 +02:00
Jeremiah Orians d80d8a652b
Move more functionality into M2libc 2021-04-03 22:41:52 -04:00
Jeremiah Orians 46cf81af83
Replace file_print with fputs 2021-04-03 18:56:55 -04:00
Jeremiah Orians b0b440c2df
Update M2libc to fix fflushing of buffers at exit or return from main 2021-02-21 21:00:34 -05:00
Jeremiah Orians 163dab268c
Merge remote-tracking branch 'deesix/TMP' 2021-02-17 23:01:23 -05:00
Jeremiah Orians 37ca8e3df9
Remove test/common_x86 files and switch x86 to M2libc 2021-02-17 22:01:28 -05:00
Jeremiah Orians 5f8484e683
Move self-hosting test to use M2libc 2021-02-17 21:40:59 -05:00
Jeremiah Orians 32ef09f964
Update M2libc and update known_issues.org 2021-02-06 13:40:28 -05:00
Jeremiah Orians fc4c1998aa
Remove test/common_knight/ files and switch knight-posix to M2libc 2021-02-06 00:45:32 -05:00
Jeremiah Orians a9d88e8e6c
Add support for -D variable and -D variable=value 2021-02-05 21:34:00 -05:00
Jeremiah Orians 8007ae9ce6
Add support for #if defined(__M2__) to enable M2-Planet specific functionality 2021-02-05 20:39:54 -05:00
Jeremiah Orians 62eedce858
Remove test/common_aarch64 files and switch AArch64 to M2libc 2021-02-05 15:54:38 -05:00
Jeremiah Orians a65619dbf4
Remove test/common_knight/*native files and switch knight-native to M2libc 2021-02-03 19:47:18 -05:00
Jeremiah Orians ba1fc44f29
Remove test/common_armv7l files and switch armv7l to M2libc 2021-02-03 07:30:15 -05:00
Jeremiah Orians 695672985e
Remove test/common_amd64 files and switch amd64 to M2libc 2021-02-03 00:32:47 -05:00
Jeremiah Orians 6f8e2eb905
Removed need for fixup 2021-02-02 23:39:27 -05:00
deesix 17c4c6b977 @@@ tests: -e (errexit) shell option in scripts, where possible
Some test scripts run programs that return non-zero values for correct
outcome; those would fail the shell -e checks.

But some scripts not using -e are fine with it because we expect zero or
the error condition is handled otherwise. So, for robustness, the option is
added into them.
2021-01-31 00:00:00 +01:00
deesix cb27e5314a @@@ remove scripts 2021-01-31 00:00:00 +01:00
deesix dd67ccddce @@@ ARCH_IS_64_BITS
In three scripts, we need to adjust the expected value check depending on
the word size of the arch.

We do it based on a this new var.
2021-01-31 00:00:00 +01:00
deesix 3400296b9b @@@ BLOOD_ELF_WORD_SIZE_FLAG 2021-01-31 00:00:00 +01:00
deesix 05d962fcfc @@@ unify 64 bits archs (run_test.sh) 2021-01-31 00:00:00 +01:00
deesix fb5bae96ab @@@ tests: source new test/env.inc.sh
... which sets, given the ARCH, the following vars:

 BASE_ADDRESS
 ENDIANNESS_FLAG
2021-01-31 00:00:00 +01:00
deesix ab055a8823 @@@ tests: ARCH var in non-Knight scripts 2021-01-31 00:00:00 +01:00
deesix 6bb784eae5 tests: minor tweaks in comments 2021-01-31 00:00:00 +01:00
deesix f865e47646 @@@ tests: aarch64 test0100 using debug ELF header
It was using the non-debug one but the rest of the compilation chain is
done with debug in mind.
2021-01-31 00:00:00 +01:00
deesix 1a9bbe6e63 @@@ tests: same --debug behaviour for all scripts of the same test
Until now, a few scripts compiled the test program with/without debug,
differently to the rest.
2021-01-31 00:00:00 +01:00
Jeremiah Orians c5068b227a
Add support for &global_variable 2021-01-28 22:22:08 -05:00
Jeremiah Orians 2043a574c9
Enable virtualization of bare metal binaries 2021-01-27 20:42:42 -05:00
deesix 548993a884 tests: use new-style mescc-tools flags
This completes the transition started in Knight scripts during their M2libc
migration at f2094a9e5b

from           : to

--BaseAddress  : --base-address
--BigEndian    : --big-endian
--LittleEndian : --little-endian

The plan for mescc-tools is to deprecate the old (pre-1.0.0) flags.

Note that test0101 compiles "hex2 0.3" and verifies that it works by
linking an example. This 0.3 version requires the old-style flags, so the
calls to test/results/test0101-*-binary are left unchanged.
2021-01-23 00:00:00 +01:00
deesix ae897dcfdb tests: no --exec_enable in hex2 calls because it's "Effectively a NOP"
hex2 in mescc-tools defaults to executable output file since 1.0.0.

See 0a553f720d39dae4231611671e4163a2d2422e0a there.

This completes the removal started in Knight scripts during their M2libc
migration at f2094a9e5b

Note that test0101 compiles "hex2 0.3" and verifies that it works by
linking an example. Calls to test/results/test0101-*-binary never used the
flag because we don't call the linked example (we just check its SHA-256).
2021-01-23 00:00:00 +01:00
deesix 52b638f48f tests: prettier scripts
One line per flag for multi-line "Verify that the resulting file works"
calls; for coherency with 3aa8327334
2021-01-23 00:00:00 +01:00
Jeremiah Orians f2094a9e5b
Migrate knight-posix to M2libc 2021-01-22 00:35:43 -05:00
Jeremiah Orians 3c6b23f734
Update M2libc to remove duplicate opens 2021-01-21 22:41:23 -05:00
Jeremiah Orians 5dd81d871e
Updated Documentation to reflect new M2libc changes 2021-01-21 18:37:59 -05:00
deesix 818784228c Use M2libc in all x86 tests < test1000 2021-01-21 00:00:00 +01:00
deesix e660caca73 Use M2libc in all armv7l tests < test1000 2021-01-21 00:00:00 +01:00
deesix 7860378b75 Use M2libc in all amd64 tests < test1000 2021-01-21 00:00:00 +01:00
deesix 55db771e29 tests: get proof from test0025 stderr (and other minor fixes)
We were checking an empty proof because the test writes to stderr and we
were redirecting stdout to the file. With the correct redirection the hash
is different, so proof.answer is also adjusted.

The x86 test was calling blood-elf with the 64bits flag. Removed to ask for
32bits behaviour.

For consistency, --BaseAddress is now using the usual value for the arch.

Also, unused input file is removed here.
2021-01-17 00:00:00 +01:00
deesix e9553d5f13 M2libc with standard architecture naming
Every AArch64 test script is affected because AArch64 -> aarch64. test0101
needs i386 -> x86 because it verifies the resulting AArch64 binary (hex2)
creating some x86 proof.

Also, a couple of x86 tests (test0000 and test0025) that are M2libc aware,
again because i386 -> x86 (hex2 ELF parts).
2021-01-16 00:00:00 +01:00
deesix bcd0f49859 Use M2libc in all AArch64 tests < test1000
Finally test0021, now that M2libc has getcwd.

See b83086642e
2021-01-15 00:00:00 +01:00
Jeremiah Orians 204d2612d7 whitespace 2021-01-12 02:57:35 +01:00
Jeremiah Orians f5f996626a tests: --output-sync for readability 2021-01-12 02:57:35 +01:00
Jeremiah Orians d34bb92b0d tests: workaround parallel clean/test make error
Something weird happens if one tries to clean and test at the same time
with a command like:

make clean test -j2

See https://lists.gnu.org/archive/html/help-make/2021-01/msg00000.html

To be safe until further investigation, we breakup the makefile into 2
files and serialize the first where M2-Planet is built.
2021-01-12 02:57:35 +01:00
deesix 9f26dbcc68 tests: support for make -j
For any test there's a directory with a script for each architecture.

These scripts generate intermediate files in the dir during compilation,
with the same names no matter the arch. So if one tries to execute the
scripts in parallel they all fight for the files.

To allow for parallel testing, now we create a temporal dir named after
the arch to isolate the intermediate files. Scripts are patched
accordingly.

This also allows easier clean-up: now, removing the temporal dirs is
almost all that we need (and the per-test .gitignore files are replaced
with a couple of lines in test/.gitignore). A common script replaces
the per-test cleanup.sh. It gets the number of the test as an argument
and takes care of some minor special cases. The makefile is adapted to
use this new test/cleanup_test.sh script.

Those special files are created during the last stage of each test, but
only if the host arch matches the test. They're _not_ isolated here
because it's harder (due to how we do the checksum) and they cannot
collide unless emulation is used and several calls to make are made at
the same time.
2021-01-12 00:00:00 +01:00
deesix 3aa8327334 tests: prettier scripts
One line per flag for the major calls. This simplifies a bit the automated
patching for parallel testing that comes next.
2021-01-12 00:00:00 +01:00
Jeremiah Orians 4def464475
Merge remote-tracking branch 'yt/array' 2021-01-10 20:07:38 -05:00
Jeremiah Orians 768f229c1d
Updated M2libc 2021-01-10 18:29:28 -05:00
Sanne Wouda 0e3d5b609a Add support for global char foo[12]; definitions
- only enabled in --bootstrap-mode

- allocates space for both the char array and the pointer to the start of
  the array
2021-01-10 23:01:08 +00:00
Sanne Wouda b83086642e Use M2libc in nearly all AArch64 tests
- disables --bootstrap-mode where it was enabled, except for test1000
  which needs to build in bootstrap-mode to check that M2-Planet can be
  compiled by cc_*

- the only hold-out is test0021 which needs getcwd which is missing in
  M2libc

- note that test0106 needs a fix to fgetc or it will never notice it has
  reached the end of stdin
2021-01-10 22:02:29 +00:00
Jeremiah Orians 674a6f5569
Update M2libc to working standard 2021-01-10 12:55:51 -05:00
Sanne Wouda dd1f5db9f1 Port AArch64 test0008 to M2libc 2021-01-10 17:50:04 +00:00
Jeremiah Orians bb3b4eebd8
Upgrade M2libc to include armv7l and prototype AArch64 2021-01-10 12:16:22 -05:00
Sanne Wouda c4d329b6cc Fixup libc-core -> libc-full
Causes a segfault due to uninitialised pointer in the FILE struct
2021-01-10 17:00:12 +00:00
Sanne Wouda 45685d0c30 Update first few tests to use M2libc 2021-01-10 16:47:13 +00:00
Jeremiah Orians 810d7da9fc
Update M2libc to add support for AMD64 2021-01-10 11:21:31 -05:00
Jeremiah Orians bc2f0e164d
Starting to prepare for the use of the M2libc standard 2021-01-10 10:02:58 -05:00
Sanne Wouda 09acd6253d Implement simple macro expansion
- no longer generate CONSTANT lines for #defined constants

- "#define FOO 1" turns "return FOO;" into "return 1;"

- Macros expanding into a macro is not supported:
  #define FOO 1
  #define BAR FOO
  will expand BAR to FOO, not to 1

- Expansion inside #if conditions is not supported.

- Function-like macros are not supported.
2021-01-09 17:39:48 +00:00
Sanne Wouda a8551f2fcd Implement --bootstrap-mode for preprocessor
- // and # lines always appear in the result of read_all_tokens

- in bootstrap mode, // tokens (but not the subsequent lines) and #
  lines are stripped. no preprocessing happens.

- in non-bootstrap mode, // lines are stripped and # lines stay for the
  preprocessing phase

- updates tests to pass --bootstrap-mode when necessary
2021-01-09 17:38:50 +00:00
Sanne Wouda 6f2cebc4ca Add a test for supported preprocessor features 2021-01-08 21:32:03 +00:00
Sanne Wouda 4550eec19e Extend macro #define support
- now supports #if defined(FOO)
- translation of #define FOO 1 to CONSTANT FOO 1 is still supported
2021-01-08 21:31:43 +00:00
Jeremiah Orians 3c4c09b95e
Added hacky version of #define support 2021-01-06 19:24:16 -05:00
Jeremiah Orians 25fd5e66c9
Another set of segfaults cleared out 2021-01-05 23:22:26 -05:00
Jeremiah Orians bdd4e65580
Catch some basic segfaults 2021-01-05 23:00:58 -05:00
Jeremiah Orians 0ab7cb78eb
Adjusted cc_macro.c formatting with astyle -A1tSxejz2fpUxV 2021-01-05 22:22:33 -05:00
Sanne Wouda 63bb59404d Improve error reporting for unexpected non-newline 2021-01-05 22:56:30 +00:00
Sanne Wouda 49fbe8942f Add error checking for unexpected #endif 2021-01-05 22:56:30 +00:00
Sanne Wouda 89c6513cd8 Add support for conditional inclusion
- support for #if, #elif, #else, #endif, but no macro expansion just
  yet. Any macro is treated as undefined and expands to 0.

for example:
./bin/M2-Planet -E test.c

 #if 1 == FOO
foo
 #else
bar
 #endif

results in

bar
2021-01-05 22:54:30 +00:00
Sanne Wouda cd96f65a23 Add macro directives to token_list
- change the lexer to not remove preprocessor directives
- preprocess() removes any lines starting with a macro directive that it
  doesn't understand (which is currently all of them)
2021-01-05 22:53:39 +00:00
Sanne Wouda 7b8a99db3c Add a preprocessor-only mode
- Very useful for testing and debugging
- Add preprocess() stub and skip compilation in preprocessor mode
2021-01-05 22:53:04 +00:00
Sanne Wouda a18e0c1782 Add newline tokens to parse stream
- needed to determine start and end of macro directives
- the main parser doesn't need them, so strip out the newline tokens
  before parsing to avoid changing it
2021-01-05 22:23:15 +00:00
Sanne Wouda fa0f135ebb Fix typo 2021-01-03 13:16:55 +00:00
Jeremiah Orians 921cc86ce6
First generation implemention of typedef 2021-01-02 22:00:02 -05:00
Jeremiah Orians 358b6cfb96
Fix modulus behavior that is wrong.
Thank you janneke
2021-01-01 16:39:27 -05:00
Jeremiah Orians e451abd667
Fix e25c1995aa SCM MES regression 2021-01-01 15:55:34 -05:00
Jeremiah Orians cc1a17a040
Revert "file.c: introduce output buffering for x86"
This reverts commit 5afeb0743e.
2021-01-01 15:28:30 -05:00
Jeremiah Orians 07baf02efe
Looks like I got x86/AMD64 signed and unsigned division backwards.
Thanks for finding that janneke
2021-01-01 10:52:23 -05:00
Jeremiah Orians c220d14928
Catching some segfaults 2020-12-31 09:53:05 -05:00
Jeremiah Orians e25c1995aa
Make types more proper 2020-12-27 21:51:46 -05:00
Jeremiah Orians 6a3d3e78e0
expand the known issues list 2020-12-24 14:41:14 -05:00
Jeremiah Orians 44e14bb662
Make known issues public 2020-12-24 12:12:52 -05:00
Jeremiah Orians 0ed81de9e1
Merge remote-tracking branch 'mihi/io-buffering-x86' 2020-12-22 22:19:44 -05:00
Jeremiah Orians 4de11b1bc6
Update checksums to reflect new fclose 2020-12-21 22:26:22 -05:00
Michael Schierl 5afeb0743e file.c: introduce output buffering for x86
Note that this is a backwards incompatible change: Unlike POSIX, exit()
will not flush all open streams, so you are responsible for flushing or
closing all your streams before successful exit.

Also, file.c will now also require calloc.c (and malloc.c).

Updated the test cases accordingly.

Only implemented and tested for x86.
2020-12-21 16:57:17 +01:00
Michael Schierl 608fba306f Fix x86 close syscall and test 0104
The close syscall was missing an indirection and therefore closed random
file descriptors (very visible in strace output).

Test 0104 did not properly null terminate the envp, resulting in -EFAULT
on execve syscall in case the next value in memory does not happen to be
0 (which it seems to be right now).
2020-12-21 16:57:17 +01:00
Michael Schierl 91bab2ef98 Close files that were fopen:ed 2020-12-21 16:57:17 +01:00
Jeremiah Orians 6fe6f44a29
Make type information localized to the inside of statements 2020-12-19 16:35:33 -05:00
Jeremiah Orians e7a0ecd244
Cleared out non-essential string primitives and added support for --max-string 2020-12-19 09:46:22 -05:00
Jeremiah Orians d9504e3872
Allow M2-Planet to support larger outputs without hitting a segfault 2020-12-19 06:50:11 -05:00
Sanne Wouda 968fdfea65 AArch64 support for unsigned comparison 2020-12-17 00:01:17 +00:00
Jeremiah Orians e5befc4fee
armv7l support for unsigned comparisons 2020-12-15 21:09:26 -05:00
Jeremiah Orians f2cae3d501
AMD64 support for unsigned comparisons 2020-12-15 20:28:04 -05:00
Jeremiah Orians eaf3861954
Fix failing tests on x86 2020-12-15 19:02:32 -05:00
Jeremiah Orians 132e685f97
Fix x86 behavior on unsigned compares 2020-12-15 17:46:45 -05:00
Jeremiah Orians 9da48c5ece
match gcc behavior in regards to if(-1 > 0) 2020-12-15 07:24:07 -05:00
Jeremiah Orians 5c22aac02d
Change knight-posix HEAP behavior and leverage better relational choices for knight-posix 2020-12-15 06:02:38 -05:00
Jeremiah 196c66d19e
Merge pull request #7 from snnw/aarch64-fix
[AArch64] Use arithmetic right shift for signed
2020-12-05 10:09:50 -05:00
Sanne Wouda a63b8837c0 [AArch64] Use arithmetic right shift for signed
- as discussed with deesix, this is the proper fix
- the test1000 checksum changes as it uses the M2-Planet source as input
2020-12-05 14:59:16 +00:00
Jeremiah d34ea502cc
Merge pull request #6 from snnw/aarch64-fix
[AArch64] Fix LSEEK syscall number
2020-12-04 21:29:02 -05:00
Sanne Wouda 58b563435b [AArch64] Use arithmetic right shift
- fixes a test failure if hex2 was compiled with M2-Planet
2020-12-04 19:37:29 +00:00
Sanne Wouda 624a5ac92d [AArch64] Fix LSEEK syscall number 2020-12-04 15:45:06 +00:00
Jeremiah Orians 0615223052
Broke tests into processor specific sets and updated the M1 test 2020-12-01 22:24:36 -05:00
Jeremiah Orians 93e8b0c0a4
Removed obsolete reference to bootstrap directory 2020-11-20 05:34:11 -05:00
Jeremiah Orians e3ca15c731
Preparing for next release 2020-11-15 20:46:26 -05:00
Jeremiah Orians a5bc08b23f
Release 1.7.0 2020-11-15 20:43:58 -05:00
Jeremiah Orians 1975d88581
Fix GCC 10 compatibility issue 2020-11-15 20:28:33 -05:00
Jeremiah Orians 67dbbbdcfc
Enable support for C multi-strings 2020-11-15 18:58:25 -05:00
Jeremiah Orians 57264eb157
Catch potential segfaulting behavior in generated binaries 2020-11-08 21:13:12 -05:00
Jeremiah Orians 39915de931
harmonize integer behavior when reading strings 2020-10-17 13:50:25 -04:00
Jeremiah Orians c4a636c99d
Fix shift behavior to better match C standard 2020-10-16 22:07:06 -04:00
Jeremiah Orians e9da9c802e
make cc_* compatible 2020-10-16 19:29:38 -04:00
nimaje 52114585bf
fix malloc to accept FreeBSD's behavior and fix failing binaries 2020-10-16 17:26:39 -04:00
nimaje 028bdaf951
Update ELF headers and sha256 function to better support FreeBSD 2020-10-16 12:00:42 -04:00
406 changed files with 11960 additions and 16063 deletions

1
.gitignore vendored
View File

@ -23,4 +23,3 @@ bin/
temp/
test/scratch/
scratch/

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "M2libc"]
path = M2libc
url = https://github.com/oriansj/M2libc.git

View File

@ -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
View File

@ -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

1
M2libc Submodule

@ -0,0 +1 @@
Subproject commit 1f4ac53d050bbd976deb40de3c9b4bd1de2782e3

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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"

1845
cc_core.c

File diff suppressed because it is too large Load Diff

View File

@ -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;

49
cc_globals.h Normal file
View File

@ -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;

835
cc_macro.c Normal file
View File

@ -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);
}
}
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}

191
known_issues.org Normal file
View File

@ -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
View File

@ -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)

1196
makefile-tests Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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

9
test/.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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. */
);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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

View File

@ -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.

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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");
}

View File

@ -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);
}

View File

@ -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