add inttyes.h,stdint.h to 05 stdlib, musl instructions in readme

This commit is contained in:
pommicket 2023-07-03 17:50:49 -04:00
parent 3384d69133
commit 113d03741a
10 changed files with 480 additions and 13 deletions

1
05/.gitignore vendored
View file

@ -1,5 +1,6 @@
in04 in04
address_map.txt address_map.txt
*.o *.o
*.d
tcc-bootstrap tcc-bootstrap
musl-bootstrap musl-bootstrap

View file

@ -27,12 +27,13 @@ $(TCCDIR)/lib/libtcc1.a: $(TCC0) $(TCCDIR)/lib/*.[cS]
$(TCC0) -c $(TCCDIR)/lib/va_list.c -o $(TCCDIR)/lib/va_list.o $(TCC0) -c $(TCCDIR)/lib/va_list.c -o $(TCCDIR)/lib/va_list.o
$(TCC0) -c $(TCCDIR)/lib/libtcc1.c -o $(TCCDIR)/lib/libtcc1.o $(TCC0) -c $(TCCDIR)/lib/libtcc1.c -o $(TCCDIR)/lib/libtcc1.o
$(TCC0) -ar $(TCCDIR)/lib/libtcc1.a $(TCCDIR)/lib/*.o $(TCC0) -ar $(TCCDIR)/lib/libtcc1.a $(TCCDIR)/lib/*.o
install: $(TCCDIR)/lib/libtcc1.a $(TCCDIR)/include/*.h musl: tcc-files
$(MAKE) -C musl-0.6.0
$(MAKE) -C musl-0.6.0 install
tcc-files: $(TCCDIR)/lib/libtcc1.a $(TCCDIR)/include/*.h
mkdir -p $(TCCINST)/include mkdir -p $(TCCINST)/include
cp -r $(TCCDIR)/include/*.h $(TCCINST)/include/ cp -r $(TCCDIR)/include/*.h $(TCCINST)/include/
cp -r $(TCCDIR)/lib/libtcc1.a $(TCCINST)/ cp -r $(TCCDIR)/lib/libtcc1.a $(TCCINST)/
$(MAKE) -C musl-0.6.0
$(MAKE) -C musl-0.6.0 install
$(TCC)1: $(TCC0) $(TCCINST)/libtcc1.a $(TCC)1: $(TCC0) $(TCCINST)/libtcc1.a
cd $(TCCDIR) && ./tcc0 -nostdinc -nostdlib -B ../tcc-boostrap -L../musl-bootstrap/lib -lc -I ../musl-bootstrap/include tcc.c -o tcc1 cd $(TCCDIR) && ./tcc0 -nostdinc -nostdlib -B ../tcc-boostrap -L../musl-bootstrap/lib -lc -I ../musl-bootstrap/include tcc.c -o tcc1
tcc: $(TCC)1 tcc: $(TCC)1

View file

@ -11,14 +11,14 @@ $ make
to build our C compiler and tcc. This will take some time (approx. 25 seconds on my computer). to build our C compiler and tcc. This will take some time (approx. 25 seconds on my computer).
This also compiles a "Hello, world!" executable, `a.out`, with our compiler. This also compiles a "Hello, world!" executable, `a.out`, with our compiler.
We can now compile tcc with itself. But first, you'll need to install the header files and library files We can now compile tcc with itself. But first, you'll need to produce the header files and library files
which are needed to compile (almost) any program with tcc: which are needed to compile (almost) any program with tcc:
``` ```
$ sudo make install $ make tcc-files
``` ```
The files will be installed to `/usr/local/lib/tcc-bootstrap`. If you want to change this, make sure to change The files will be installed to `./tcc-bootstrap`. If you want to change this, make sure to change
both the `TCCINST` variable in the makefile, and the `CONFIG_TCCDIR` macro in `tcc-0.9.27/config.h`. both the `TCCINST` variable in the makefile, and the `CONFIG_TCCDIR` macro in `tcc-0.9.27/config.h`.
Anyways, once this installation is done, you should be able to compile any C program with `tcc-0.9.27/tcc0`, Anyways, once this installation is done, you should be able to compile any C program with `tcc-0.9.27/tcc0`,
including tcc itself: including tcc itself:
@ -406,11 +406,39 @@ Now this library file is itself compiled from C source files (typically glibc).
So, we can't really say that the self-compiled tcc was built from scratch, and there could be malicious So, we can't really say that the self-compiled tcc was built from scratch, and there could be malicious
self-replicating code in glibc. self-replicating code in glibc.
### compiling glibc I have to thank [Dawid33 for coming up with the idea to try this...](https://github.com/pommicket/bootstrap/issues/1)
You can't compile glibc with tcc, but Compiling glibc is difficult (see below), but
it's possible to build an old version of musl, an alternate libc it's possible to build an old version of musl, an alternate libc,
(you can run `CC=../tcc-0.9.27/tcc0 make` in the `musl-0.6.0` directory here). with just our `tcc0` executable. This can be done with
```
make musl
```
in this directory. Now you can run
```
./tcc0 -nostdinc -nostdlib -B ../tcc-boostrap -I ../musl-bootstrap/include tcc.c ../musl-bootstrap/lib/*.[oa] -o tcc1
```
to get a tcc executable that is fully independent of any libc installed on your system.
We can do the same with gcc
```
./tcc0a -nostdinc -nostdlib -B ../tcc-boostrap -I ../musl-bootstrap/include tcc.c ../musl-bootstrap/lib/*.[oa] -o tcc1a
```
And once more the files `tcc1a` and `tcc1` differ. But with one more round:
```
./tcc1 -nostdinc -nostdlib -B ../tcc-boostrap -I ../musl-bootstrap/include tcc.c ../musl-bootstrap/lib/*.[oa] -o tcc2
```
we find that `tcc1a` and `tcc2` do not differ.
So glibc has not betrayed us, and we now have a fully-functioning
self-compiling compiler built from nothing but human-readable source code.
But hardly anyone uses tcc to compile anything important.
For all we know the hypothetical malicious code in gcc or glibc only replicates itself if the
compiler is sufficiently advanced (e.g. gcc or clang).
Ideally we would build up to a fully bootstrapped build of gcc. Unfortunately
that turns out to be quite a challenge...
### compiling glibc
You should be able to use musl alongside tcc to build an old version of gcc. This also requires You should be able to use musl alongside tcc to build an old version of gcc. This also requires
building several tools needed to compile gcc. You should then be able to build an old version of building several tools needed to compile gcc. You should then be able to build an old version of

153
05/inttypes.h Normal file
View file

@ -0,0 +1,153 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#ifndef PRIu32
#define PRId8 "d"
#define PRIdLEAST8 "d"
#define PRIdFAST8 "d"
#define PRIi8 "i"
#define PRIiLEAST8 "i"
#define PRIiFAST8 "i"
#define PRIo8 "o"
#define PRIoLEAST8 "o"
#define PRIoFAST8 "o"
#define PRIu8 "u"
#define PRIuLEAST8 "u"
#define PRIuFAST8 "u"
#define PRIx8 "x"
#define PRIxLEAST8 "x"
#define PRIxFAST8 "x"
#define PRIX8 "X"
#define PRIXLEAST8 "X"
#define PRIXFAST8 "X"
#define PRId16 "d"
#define PRIdLEAST16 "d"
#define PRIdFAST16 "d"
#define PRIi16 "i"
#define PRIiLEAST16 "i"
#define PRIiFAST16 "i"
#define PRIo16 "o"
#define PRIoLEAST16 "o"
#define PRIoFAST16 "o"
#define PRIu16 "u"
#define PRIuLEAST16 "u"
#define PRIuFAST16 "u"
#define PRIx16 "x"
#define PRIxLEAST16 "x"
#define PRIxFAST16 "x"
#define PRIX16 "X"
#define PRIXLEAST16 "X"
#define PRIXFAST16 "X"
#define PRId32 "d"
#define PRIdLEAST32 "d"
#define PRIdFAST32 "d"
#define PRIi32 "i"
#define PRIiLEAST32 "i"
#define PRIiFAST32 "i"
#define PRIo32 "o"
#define PRIoLEAST32 "o"
#define PRIoFAST32 "o"
#define PRIu32 "u"
#define PRIuLEAST32 "u"
#define PRIuFAST32 "u"
#define PRIx32 "x"
#define PRIxLEAST32 "x"
#define PRIxFAST32 "x"
#define PRIX32 "X"
#define PRIXLEAST32 "X"
#define PRIXFAST32 "X"
#define PRId64 "ld"
#define PRIdLEAST64 "ld"
#define PRIdFAST64 "ld"
#define PRIi64 "li"
#define PRIiLEAST64 "li"
#define PRIiFAST64 "li"
#define PRIo64 "lo"
#define PRIoLEAST64 "lo"
#define PRIoFAST64 "lo"
#define PRIu64 "lu"
#define PRIuLEAST64 "lu"
#define PRIuFAST64 "lu"
#define PRIx64 "lx"
#define PRIxLEAST64 "lx"
#define PRIxFAST64 "lx"
#define PRIX64 "lX"
#define PRIXLEAST64 "lX"
#define PRIXFAST64 "lX"
#define SCNd8 "hhd"
#define SCNdLEAST8 "hhd"
#define SCNdFAST8 "hhd"
#define SCNi8 "hhi"
#define SCNiLEAST8 "hhi"
#define SCNiFAST8 "hhi"
#define SCNo8 "hho"
#define SCNoLEAST8 "hho"
#define SCNoFAST8 "hho"
#define SCNu8 "hhu"
#define SCNuLEAST8 "hhu"
#define SCNuFAST8 "hhu"
#define SCNx8 "hhx"
#define SCNxLEAST8 "hhx"
#define SCNxFAST8 "hhx"
#define SCNd16 "hd"
#define SCNdLEAST16 "hd"
#define SCNdFAST16 "hd"
#define SCNi16 "hi"
#define SCNiLEAST16 "hi"
#define SCNiFAST16 "hi"
#define SCNo16 "ho"
#define SCNoLEAST16 "ho"
#define SCNoFAST16 "ho"
#define SCNu16 "hu"
#define SCNuLEAST16 "hu"
#define SCNuFAST16 "hu"
#define SCNx16 "hx"
#define SCNxLEAST16 "hx"
#define SCNxFAST16 "hx"
#define SCNd32 "d"
#define SCNdLEAST32 "d"
#define SCNdFAST32 "d"
#define SCNi32 "i"
#define SCNiLEAST32 "i"
#define SCNiFAST32 "i"
#define SCNo32 "o"
#define SCNoLEAST32 "o"
#define SCNoFAST32 "o"
#define SCNu32 "u"
#define SCNuLEAST32 "u"
#define SCNuFAST32 "u"
#define SCNx32 "x"
#define SCNxLEAST32 "x"
#define SCNxFAST32 "x"
#define SCNd64 "ld"
#define SCNdLEAST64 "ld"
#define SCNdFAST64 "ld"
#define SCNi64 "li"
#define SCNiLEAST64 "li"
#define SCNiFAST64 "li"
#define SCNo64 "lo"
#define SCNoLEAST64 "lo"
#define SCNoFAST64 "lo"
#define SCNu64 "lu"
#define SCNuLEAST64 "lu"
#define SCNuFAST64 "lu"
#define SCNx64 "lx"
#define SCNxLEAST64 "lx"
#define SCNxFAST64 "lx"
#define SCNX64 "lX"
#define SCNXLEAST64 "lX"
#define SCNXFAST64 "lX"
#endif // PRIu32
#endif // _INTTYPES_H

View file

@ -849,9 +849,9 @@ function translation_phase_4
:pp_include_have_filename :pp_include_have_filename
local included_pptokens local included_pptokens
included_pptokens = split_into_preprocessing_tokens(inc_filename)
debug_puts(.str_including) debug_puts(.str_including)
debug_putsln(inc_filename) debug_putsln(inc_filename)
included_pptokens = split_into_preprocessing_tokens(inc_filename)
out = translation_phase_4(inc_filename, included_pptokens, out) out = translation_phase_4(inc_filename, included_pptokens, out)
free(included_pptokens) free(included_pptokens)
free(inc_filename) free(inc_filename)

View file

@ -49,6 +49,9 @@ typedef long ssize_t;
#define USHRT_MAX UINT16_MAX #define USHRT_MAX UINT16_MAX
#define UINT_MAX UINT32_MAX #define UINT_MAX UINT32_MAX
#define ULONG_MAX UINT64_MAX #define ULONG_MAX UINT64_MAX
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
static unsigned char __syscall_data[] = { static unsigned char __syscall_data[] = {
// mov rax, [rsp+24] // mov rax, [rsp+24]

64
05/stdint.h Normal file
View file

@ -0,0 +1,64 @@
#ifndef _STDINT_H
#define _STDINT_H
#include <stdc_common.h>
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef long intmax_t;
typedef unsigned long uintmax_t;
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
#endif // _STDINT_H

View file

@ -2,6 +2,6 @@
#define CONFIG_TCC_STATIC 1 #define CONFIG_TCC_STATIC 1
#define TCC_TARGET_X86_64 1 #define TCC_TARGET_X86_64 1
#define ONE_SOURCE 1 #define ONE_SOURCE 1
//#define CONFIG_LDDIR "lib/x86_64-linux-gnu"
#define CONFIG_TCCDIR "../tcc-bootstrap" #define CONFIG_TCCDIR "../tcc-bootstrap"
#define CONFIG_LDDIR "lib/x86_64-linux-gnu"
#define inline #define inline

153
05/tcc-0.9.27/inttypes.h Normal file
View file

@ -0,0 +1,153 @@
#ifndef _INTTYPES_H
#define _INTTYPES_H
#include <stdint.h>
#ifndef PRIu32
#define PRId8 "d"
#define PRIdLEAST8 "d"
#define PRIdFAST8 "d"
#define PRIi8 "i"
#define PRIiLEAST8 "i"
#define PRIiFAST8 "i"
#define PRIo8 "o"
#define PRIoLEAST8 "o"
#define PRIoFAST8 "o"
#define PRIu8 "u"
#define PRIuLEAST8 "u"
#define PRIuFAST8 "u"
#define PRIx8 "x"
#define PRIxLEAST8 "x"
#define PRIxFAST8 "x"
#define PRIX8 "X"
#define PRIXLEAST8 "X"
#define PRIXFAST8 "X"
#define PRId16 "d"
#define PRIdLEAST16 "d"
#define PRIdFAST16 "d"
#define PRIi16 "i"
#define PRIiLEAST16 "i"
#define PRIiFAST16 "i"
#define PRIo16 "o"
#define PRIoLEAST16 "o"
#define PRIoFAST16 "o"
#define PRIu16 "u"
#define PRIuLEAST16 "u"
#define PRIuFAST16 "u"
#define PRIx16 "x"
#define PRIxLEAST16 "x"
#define PRIxFAST16 "x"
#define PRIX16 "X"
#define PRIXLEAST16 "X"
#define PRIXFAST16 "X"
#define PRId32 "d"
#define PRIdLEAST32 "d"
#define PRIdFAST32 "d"
#define PRIi32 "i"
#define PRIiLEAST32 "i"
#define PRIiFAST32 "i"
#define PRIo32 "o"
#define PRIoLEAST32 "o"
#define PRIoFAST32 "o"
#define PRIu32 "u"
#define PRIuLEAST32 "u"
#define PRIuFAST32 "u"
#define PRIx32 "x"
#define PRIxLEAST32 "x"
#define PRIxFAST32 "x"
#define PRIX32 "X"
#define PRIXLEAST32 "X"
#define PRIXFAST32 "X"
#define PRId64 "ld"
#define PRIdLEAST64 "ld"
#define PRIdFAST64 "ld"
#define PRIi64 "li"
#define PRIiLEAST64 "li"
#define PRIiFAST64 "li"
#define PRIo64 "lo"
#define PRIoLEAST64 "lo"
#define PRIoFAST64 "lo"
#define PRIu64 "lu"
#define PRIuLEAST64 "lu"
#define PRIuFAST64 "lu"
#define PRIx64 "lx"
#define PRIxLEAST64 "lx"
#define PRIxFAST64 "lx"
#define PRIX64 "lX"
#define PRIXLEAST64 "lX"
#define PRIXFAST64 "lX"
#define SCNd8 "hhd"
#define SCNdLEAST8 "hhd"
#define SCNdFAST8 "hhd"
#define SCNi8 "hhi"
#define SCNiLEAST8 "hhi"
#define SCNiFAST8 "hhi"
#define SCNo8 "hho"
#define SCNoLEAST8 "hho"
#define SCNoFAST8 "hho"
#define SCNu8 "hhu"
#define SCNuLEAST8 "hhu"
#define SCNuFAST8 "hhu"
#define SCNx8 "hhx"
#define SCNxLEAST8 "hhx"
#define SCNxFAST8 "hhx"
#define SCNd16 "hd"
#define SCNdLEAST16 "hd"
#define SCNdFAST16 "hd"
#define SCNi16 "hi"
#define SCNiLEAST16 "hi"
#define SCNiFAST16 "hi"
#define SCNo16 "ho"
#define SCNoLEAST16 "ho"
#define SCNoFAST16 "ho"
#define SCNu16 "hu"
#define SCNuLEAST16 "hu"
#define SCNuFAST16 "hu"
#define SCNx16 "hx"
#define SCNxLEAST16 "hx"
#define SCNxFAST16 "hx"
#define SCNd32 "d"
#define SCNdLEAST32 "d"
#define SCNdFAST32 "d"
#define SCNi32 "i"
#define SCNiLEAST32 "i"
#define SCNiFAST32 "i"
#define SCNo32 "o"
#define SCNoLEAST32 "o"
#define SCNoFAST32 "o"
#define SCNu32 "u"
#define SCNuLEAST32 "u"
#define SCNuFAST32 "u"
#define SCNx32 "x"
#define SCNxLEAST32 "x"
#define SCNxFAST32 "x"
#define SCNd64 "ld"
#define SCNdLEAST64 "ld"
#define SCNdFAST64 "ld"
#define SCNi64 "li"
#define SCNiLEAST64 "li"
#define SCNiFAST64 "li"
#define SCNo64 "lo"
#define SCNoLEAST64 "lo"
#define SCNoFAST64 "lo"
#define SCNu64 "lu"
#define SCNuLEAST64 "lu"
#define SCNuFAST64 "lu"
#define SCNx64 "lx"
#define SCNxLEAST64 "lx"
#define SCNxFAST64 "lx"
#define SCNX64 "lX"
#define SCNXLEAST64 "lX"
#define SCNXFAST64 "lX"
#endif // PRIu32
#endif // _INTTYPES_H

64
05/tcc-0.9.27/stdint.h Normal file
View file

@ -0,0 +1,64 @@
#ifndef _STDINT_H
#define _STDINT_H
#include <stdc_common.h>
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef long intmax_t;
typedef unsigned long uintmax_t;
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
#endif // _STDINT_H