satrt readme

This commit is contained in:
pommicket 2022-02-18 14:15:09 -05:00
parent 826d1afd58
commit 06def8fb86
8 changed files with 65 additions and 8 deletions

View file

@ -1,4 +1,6 @@
all: out04 a.out TCCDIR=tcc-0.9.27
TCC=$(TCCDIR)/tcc
all: out04 a.out test.out README.html
in04: *.b ../04a/out04 in04: *.b ../04a/out04
../04a/out04 main.b in04 ../04a/out04 main.b in04
out04: in04 ../04/out03 out04: in04 ../04/out03
@ -9,5 +11,13 @@ out04: in04 ../04/out03
./out04 $< $@ ./out04 $< $@
a.out: main.c *.h out04 a.out: main.c *.h out04
./out04 ./out04
test.out: $(TCC) test.s.o test.c.o
$(TCC) -static -nostdlib test.s.o test.c.o -o test.out
test.s.o: $(TCC) test.s
$(TCC) -static -nostdlib -c test.s -o test.s.o
test.c.o: $(TCC) test.c
$(TCC) -static -nostdlib -c test.c -o test.c.o
$(TCC): $(TCCDIR)/*.c $(TCCDIR)/*.h out04
cd $(TCCDIR) && ../out04 tcc.c tcc
clean: clean:
rm -f out* README.html *.out rm -f out* README.html *.out *.o $(TCC)

42
05/README.md Normal file
View file

@ -0,0 +1,42 @@
# [bootstrap](../README.md) stage 05
This stage consists of a C compiler capable of compiling TCC (after some modifications
to TCC's source code).
Run
```
make
```
to build our C compiler and TCC. This will take some time (approx. 25 seconds on my computer).
A test program, `test.out` will be compiled using `tcc`. If you run
it, you should get the output
```
Hello, world!
```
So now we just compile TCC with itself, and we're done, right?
Well, not quite...
## the nightmare begins
The issue here is that to compile TCC/GCC with TCC, we need libc, the C standard library functions.
Our C compiler just includes these functions in the standard header files, but normally
the code for them is located in a separate library file (called something like
`/usr/lib/x86_64-linux-gnu/libc-2.31.so`).
This library file is itself compiled from C source files (typically glibc).
So, can't we just compile glibc with TCC, then compile TCC with itself?
Well, no. Compiling glibc with TCC is basically impossible; you need to compile
it with GCC.
Other libc implementations aren't too happy about TCC either -- I tried to compile
[musl](http://www.musl-libc.org/) for several hours, and had to give up in the end.
It seems that the one option left is to make our own libc, and try to use it along with
TCC to compile GCC.
From there, we should be able to compile glibc with GCC. Then, we can compile GCC with GCC and glibc.
If we do all this, we should get the same libc.so and gcc files as if we had started
with any GCC and glibc builds. It's all very confusing.

View file

@ -19,7 +19,6 @@ tcc
*-tcc *-tcc
libtcc*.def libtcc*.def
config*.h
config*.mak config*.mak
config.texi config.texi
conftest* conftest*

8
05/tcc-0.9.27/config.h Normal file
View file

@ -0,0 +1,8 @@
#define TCC_VERSION "0.9.27"
#define CONFIG_TCC_STATIC 1
#define CONFIG_TCC_ELFINTERP "/XXX"
#define CONFIG_TCC_CRT_PREFIX "/XXX"
#define CONFIG_SYSROOT "/XXX"
#define inline
#define TCC_TARGET_X86_64 1
#define ONE_SOURCE 1

View file

@ -599,7 +599,7 @@ static void gcall_or_jmp(int is_jmp)
#ifdef TCC_TARGET_PE #ifdef TCC_TARGET_PE
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4)); greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4));
#else #else
greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PLT32, (int)(vtop->c.i-4)); greloca(cur_text_section, vtop->sym, ind + 1, R_X86_64_PC32, (int)(vtop->c.i-4)); // tcc's PLT code doesn't seem to work with static builds
#endif #endif
} else { } else {
/* put an empty PC32 relocation */ /* put an empty PC32 relocation */

View file

@ -1,6 +1,5 @@
// calling assembly functions from C is not working for some reason.
extern unsigned long __syscall(int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); extern unsigned long __syscall(int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int main(unsigned long (*_syscall)(int, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)) { int main(void) {
__syscall(1, 1, (unsigned long)"Hello, world!\n", 14, 0, 0, 0); __syscall(1, 1, (unsigned long)"Hello, world!\n", 14, 0, 0, 0);
return 42; return 42;
} }

View file

@ -15,7 +15,6 @@ __syscall:
ret ret
_start: _start:
lea __syscall, %rdi
call main call main
mov $60, %eax mov $60, %eax
syscall syscall

View file

@ -60,7 +60,7 @@ If you're unfamiliar with x86-64 assembly, you should check out the instruction
Bootstrapping a compiler is not an easy task, so we're trying to make it as easy Bootstrapping a compiler is not an easy task, so we're trying to make it as easy
as possible. We don't even necessarily need a standard-compliant C compiler, we as possible. We don't even necessarily need a standard-compliant C compiler, we
only need enough to compile someone else's C compiler, specifically we'll be only need enough to compile someone else's C compiler, specifically we'll be
using [TCC](https://bellard.org/tcc/) since it's written in standard C89. using [TCC](https://bellard.org/tcc/) since it's written (mostly) in standard C89.
- efficiency is not a concern - efficiency is not a concern