Compare commits
56 Commits
Author | SHA1 | Date |
---|---|---|
Jan Nieuwenhuizen | c8f509e8cd | |
Jan Nieuwenhuizen | 3bafbef287 | |
Jan Nieuwenhuizen | d59b1dd5e4 | |
Jan Nieuwenhuizen | 0ab168cf14 | |
Jan Nieuwenhuizen | 0c5cf429bb | |
Jan Nieuwenhuizen | ddea739c89 | |
Jan Nieuwenhuizen | 1f7bc1165b | |
Jan Nieuwenhuizen | 28747bb84f | |
Jan Nieuwenhuizen | 2c8917e8cf | |
Jan Nieuwenhuizen | 76bd3939bf | |
Jan Nieuwenhuizen | 697e120636 | |
Jan Nieuwenhuizen | bc1cfcf4ea | |
Jan Nieuwenhuizen | 21325fea44 | |
Jan Nieuwenhuizen | 6dd93b65b7 | |
Jan Nieuwenhuizen | 7062d846dc | |
Jan Nieuwenhuizen | 489bbbccd9 | |
Jan Nieuwenhuizen | 581891fbd7 | |
Jan Nieuwenhuizen | dbdc4f2c49 | |
Jan Nieuwenhuizen | e3833ff80b | |
Jan Nieuwenhuizen | adeecfe3fc | |
Jan Nieuwenhuizen | 0d45b9da6b | |
Jan Nieuwenhuizen | 5df456f020 | |
Jan Nieuwenhuizen | 3e09b10573 | |
Jan Nieuwenhuizen | add4158cfe | |
Jan Nieuwenhuizen | 62a7f8ffb7 | |
Jan Nieuwenhuizen | c12d36a831 | |
Jan Nieuwenhuizen | aef45d3b2f | |
Jan Nieuwenhuizen | 84834f2793 | |
Jan Nieuwenhuizen | f8747a9f08 | |
Jan Nieuwenhuizen | 047ce2fb42 | |
Jan Nieuwenhuizen | 0c66456b1f | |
Jan Nieuwenhuizen | 28e321133a | |
Jan Nieuwenhuizen | 58d69e6296 | |
Jan Nieuwenhuizen | 4bd24bc145 | |
Jan Nieuwenhuizen | 0be9207e56 | |
Jan Nieuwenhuizen | bd04408eff | |
Jan Nieuwenhuizen | 1770c2f008 | |
Jan Nieuwenhuizen | 0edcab5c2f | |
Jan Nieuwenhuizen | aabfd45a22 | |
Jan Nieuwenhuizen | e9979b51d4 | |
Jan Nieuwenhuizen | 7823336295 | |
Jan Nieuwenhuizen | 72d79bbaf1 | |
Jan Nieuwenhuizen | a958c2cbf9 | |
Jan Nieuwenhuizen | 2df994edbb | |
Jan Nieuwenhuizen | 7bba51cd10 | |
Jan Nieuwenhuizen | c6fca09c2f | |
Jan Nieuwenhuizen | 67ab8df0bd | |
Jan Nieuwenhuizen | 467d33f83a | |
Jan Nieuwenhuizen | b28cc512db | |
Jan Nieuwenhuizen | 101060edb3 | |
Jan Nieuwenhuizen | c8f472fac0 | |
Jan Nieuwenhuizen | eec6bb2c50 | |
Jan Nieuwenhuizen | c01e774244 | |
Jan Nieuwenhuizen | be3819a932 | |
Jan Nieuwenhuizen | 927a7ae5b4 | |
Jan Nieuwenhuizen | 7e559a3c21 |
|
@ -2,6 +2,12 @@
|
|||
\#*
|
||||
.#*
|
||||
*.o
|
||||
*.E
|
||||
*.hex2
|
||||
*.M1
|
||||
*.m1
|
||||
*.i686-unknown-linux-gnu-out
|
||||
*.mes-out
|
||||
*.a
|
||||
*.exe
|
||||
*.dll
|
||||
|
|
|
@ -225,12 +225,20 @@ void o(uint32_t i)
|
|||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind++] = i&255;
|
||||
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||
i>>=8;
|
||||
cur_text_section->data[ind++] = i&255;
|
||||
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||
i>>=8;
|
||||
cur_text_section->data[ind++] = i&255;
|
||||
trace ("o "); eputs (itoa (i&255)); eputs ("\n");
|
||||
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||
i>>=8;
|
||||
cur_text_section->data[ind++] = i;
|
||||
trace ("o "); eputs (itoa (i)); eputs ("\n");
|
||||
trace ("o "); eputs (itoa (cur_text_section->data[ind-1])); eputs ("\n");
|
||||
}
|
||||
|
||||
static uint32_t stuff_const(uint32_t op, uint32_t c)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
export PREFIX=usr
|
||||
export HEX2=../mescc-tools/bin/hex2
|
||||
export M1=../mescc-tools/bin/M1
|
||||
export MESCC=../mes/guile/mescc.scm
|
||||
export MES_PREFIX=../mes
|
||||
export TINYCC_SEED=../tinycc-seed
|
||||
|
||||
sh build.sh
|
||||
sh check.sh
|
|
@ -0,0 +1,20 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f tcc
|
||||
|
||||
GUIX=${GUIX-$(command -v guix||:)}
|
||||
MES_PREFIX=${MES_PREFIX-../mes}
|
||||
|
||||
touch config.mak
|
||||
make clean
|
||||
rm -f crt*.o
|
||||
crt1=$(gcc --print-file-name=crt1.o)
|
||||
#crtdir=$(dirname $crt1)
|
||||
#crti=$(gcc --print-file-name=crti.o)
|
||||
#crtn=$(gcc --print-file-name=crtn.o)
|
||||
|
||||
unset ONE_SOURCE
|
||||
./configure --tccdir=$PWD --crtprefix=$crtdir --extra-cflags="-DHAVE_FLOAT=1 -DHAVE_BITFIELD=1"
|
||||
make ETAGS
|
||||
make PROGRAM_PREFIX=gcc- gcc-tcc
|
||||
make libtcc1.a
|
|
@ -0,0 +1,62 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f i686-unknown-linux-gnu-tcc
|
||||
|
||||
# crt1=$(i686-unknown-linux-gnu-gcc --print-file-name=crt1.o)
|
||||
# crtdir=$(dirname $crt1)
|
||||
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
|
||||
PREFIX=${PREFIX-usr}
|
||||
GUIX=${GUIX-$(command -v guix||:)}
|
||||
MES_PREFIX=${MES_PREFIX-../mes}
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}/../share/mes}
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
cp $TINYCC_SEED/x86-mes-gcc/crt1.o crt1.o
|
||||
cp $TINYCC_SEED/x86-mes-gcc/crti.o crti.o
|
||||
cp $TINYCC_SEED/x86-mes-gcc/crtn.o crtn.o
|
||||
|
||||
CC=${CC-i686-unknown-linux-gnu-gcc}
|
||||
CFLAGS="
|
||||
-nostdinc
|
||||
-nostdlib
|
||||
-fno-builtin
|
||||
--include=$MES_PREFIX/lib/linux/x86-mes-gcc/crt1.c
|
||||
--include=$MES_PREFIX/lib/libc+tcc.c
|
||||
--include=$MES_PREFIX/lib/libtcc1.c
|
||||
-Wl,-Ttext-segment=0x1000000
|
||||
"
|
||||
|
||||
if [ -z "$interpreter" -a -n "$GUIX" ]; then
|
||||
interpreter=$($GUIX environment --ad-hoc patchelf -- patchelf --print-interpreter $(guix build --system=i686-linux hello)/bin/hello)
|
||||
elif [ -x /lib/ld-linux.so.2 ]; then
|
||||
# legacy non-GuixSD support
|
||||
interpreter=/lib/ld-linux.so.2
|
||||
fi
|
||||
interpreter=${interpreter-interpreter}
|
||||
export interpreter
|
||||
|
||||
mkdir -p $PREFIX/lib
|
||||
ABSPREFIX=$(cd $PREFIX && pwd)
|
||||
cp $TINYCC_SEED/x86-mes-gcc/libc+tcc.o $ABSPREFIX/lib
|
||||
cp $TINYCC_SEED/x86-mes-gcc/libtcc1.o $ABSPREFIX/lib
|
||||
$CC -g -o i686-unknown-linux-gnu-tcc\
|
||||
$CFLAGS\
|
||||
-I.\
|
||||
-I $MES_PREFIX/lib\
|
||||
-I $MES_PREFIX/include\
|
||||
-D 'CONFIG_TCCDIR="'$PREFIX'/lib/tcc"'\
|
||||
-D 'CONFIG_TCC_CRTPREFIX="'$PREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_ELFINTERP="'$interpreter'"'\
|
||||
-D 'CONFIG_TCC_LIBPATHS="'$ABSPREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_SYSINCLUDEPATHS="'$MES_PREFIX'/include:'$PREFIX'/include:{B}/include"'\
|
||||
-D CONFIG_USE_LIBGCC=1\
|
||||
-D 'TCC_LIBGCC="'$ABSPREFIX'/lib/libc.a"'\
|
||||
-D BOOTSTRAP=1\
|
||||
-D CONFIG_TCCBOOT=1\
|
||||
-D CONFIG_TCC_STATIC=1\
|
||||
-D CONFIG_USE_LIBGCC=1\
|
||||
-D ONE_SOURCE=1\
|
||||
-D TCC_MES_LIBC=1\
|
||||
-D TCC_TARGET_I386=1\
|
||||
tcc.c
|
|
@ -0,0 +1,112 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
export BUILD_DEBUG
|
||||
export MES_DEBUG
|
||||
export MES_PREFIX
|
||||
export PREFIX
|
||||
export TINYCC_SEED
|
||||
export interpreter
|
||||
|
||||
if [ -n "$BUILD_DEBUG" ]; then
|
||||
set -x
|
||||
MESCCFLAGS="$MESCCFLAGS -v"
|
||||
fi
|
||||
|
||||
rm -f tcc.E tcc.hex2 tcc.M1 tcc.m1 mes-tcc boot?-tcc
|
||||
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
PREFIX=${PREFIX-usr}
|
||||
GUIX=${GUIX-$(command -v guix||:)}
|
||||
CC=${MESCC-mescc}
|
||||
MES=${MES-../mes/src/mes}
|
||||
MESCC=${MESCC-mescc}
|
||||
HEX2=${HEX2-hex2}
|
||||
M1=${M1-M1}
|
||||
BLOOD_ELF=${BLOOD_ELF-blood-elf}
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}/../share/mes}
|
||||
#MES_PREFIX=${MES_PREFIX-../mes}
|
||||
MES_SEED=${MES_SEED-../mes-seed}
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
cp $TINYCC_SEED/x86-mes-tcc/crt1.o crt1.o
|
||||
cp $TINYCC_SEED/x86-mes-tcc/crti.o crti.o
|
||||
cp $TINYCC_SEED/x86-mes-tcc/crtn.o crtn.o
|
||||
|
||||
if [ -z "$interpreter" -a -n "$GUIX" ]; then
|
||||
interpreter=$($GUIX environment --ad-hoc patchelf -- patchelf --print-interpreter $(guix build --system=i686-linux hello)/bin/hello)
|
||||
elif [ -x /lib/ld-linux.so.2 ]; then
|
||||
# legacy non-GuixSD support
|
||||
interpreter=/lib/ld-linux.so.2
|
||||
fi
|
||||
interpreter=${interpreter-interpreter}
|
||||
export interpreter
|
||||
|
||||
mkdir -p $PREFIX/lib
|
||||
ABSPREFIX=$(cd $PREFIX && pwd)
|
||||
cp $TINYCC_SEED/x86-mes-tcc/libc+tcc.o $ABSPREFIX/lib
|
||||
|
||||
|
||||
if [ -n "$ONE_SOURCE" ]; then
|
||||
sh cc.sh tcc
|
||||
files="tcc.S"
|
||||
else
|
||||
sh cc.sh tccpp
|
||||
sh cc.sh tccgen
|
||||
sh cc.sh tccelf
|
||||
sh cc.sh tccrun
|
||||
sh cc.sh i386-gen
|
||||
sh cc.sh i386-link
|
||||
sh cc.sh i386-asm
|
||||
sh cc.sh tccasm
|
||||
sh cc.sh libtcc
|
||||
sh cc.sh tcc
|
||||
files="
|
||||
tccpp.S
|
||||
tccgen.S
|
||||
tccelf.S
|
||||
tccrun.S
|
||||
i386-gen.S
|
||||
i386-link.S
|
||||
i386-asm.S
|
||||
tccasm.S
|
||||
libtcc.S
|
||||
tcc.S
|
||||
"
|
||||
fi
|
||||
|
||||
$MESCC\
|
||||
$MESCCFLAGS\
|
||||
-g\
|
||||
-o mes-tcc\
|
||||
-L $TINYCC_SEED\
|
||||
-L $MES_SEED\
|
||||
-l c+tcc\
|
||||
$files\
|
||||
$TINYCC_SEED/x86-mes/libc+tcc.o
|
||||
|
||||
exit 0
|
||||
|
||||
rm -f libc.a
|
||||
if false; then
|
||||
# ../mes/lib/linux-gcc.c:33: error: bad operand with opcode 'mov'
|
||||
# it works with bootx-tcc
|
||||
./mes-tcc -c -I $MES_PREFIX/include -I $MES_PREFIX/lib $MES_PREFIX/lib/libc+gnu.c
|
||||
./mes-tcc -ar rc libc.a libc+gnu.o
|
||||
else
|
||||
##./mes-tcc -ar rc libc.a $TINYCC_SEED/x86-mes-tcc/libc+gnu.o
|
||||
cp -f $TINYCC_SEED/x86-mes-gcc/libc+gnu.o .
|
||||
./mes-tcc -ar rc libc.a libc+gnu.o
|
||||
fi
|
||||
rm -f libtcc1.a
|
||||
cp -f $TINYCC_SEED/x86-mes-gcc/libtcc1.o .
|
||||
./mes-tcc -ar rc libtcc1.a libtcc1.o
|
||||
|
||||
sh boot.sh
|
||||
TCC=./boot0-tcc sh boot.sh
|
||||
TCC=./boot1-tcc sh boot.sh
|
||||
TCC=./boot2-tcc sh boot.sh
|
||||
TCC=./boot3-tcc sh boot.sh
|
||||
|
||||
ln -f boot4-tcc tcc
|
|
@ -0,0 +1,78 @@
|
|||
#! /bin/sh
|
||||
set -e
|
||||
|
||||
if [ -n "$BUILD_DEBUG" ]; then
|
||||
set -x
|
||||
MESCCFLAGS="$MESCCFLAGS -v"
|
||||
fi
|
||||
|
||||
t=$1
|
||||
|
||||
rm -f $t.E $t.M1 $t.m1
|
||||
|
||||
GUIX=${GUIX-$(command -v guix||:)}
|
||||
CC=${MESCC-mescc}
|
||||
MES=${MES-../mes/src/mes}
|
||||
MESCC=${MESCC-mescc}
|
||||
CFLAGS=${CFLAGS-}
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}}
|
||||
ABSPREFIX=$(cd $PREFIX && pwd)
|
||||
|
||||
if [ -z "$interpreter" -a -n "$GUIX" ]; then
|
||||
interpreter=$($GUIX environment --ad-hoc patchelf -- patchelf --print-interpreter $(guix build --system=i686-linux hello)/bin/hello)
|
||||
elif [ -x /lib/ld-linux.so.2 ]; then
|
||||
# legacy non-GuixSD support
|
||||
interpreter=/lib/ld-linux.so.2
|
||||
fi
|
||||
|
||||
ulimit -s 17030
|
||||
|
||||
if [ -n "$ONE_SOURCE" ]; then
|
||||
CFLAGS="$CFLAGS -D ONE_SOURCE=$ONE_SOURCE"
|
||||
fi
|
||||
|
||||
if [ -n "$PREPROCESS" ]; then
|
||||
time sh $MESCC $MESCCFLAGS -E -o $t.E\
|
||||
$CFLAGS\
|
||||
-I .\
|
||||
-I $MES_PREFIX/lib\
|
||||
-I $MES_PREFIX/include\
|
||||
-D inline=\
|
||||
-D 'CONFIG_TCCDIR="'$PREFIX'/lib/tcc"'\
|
||||
-D 'CONFIG_TCC_CRTPREFIX="'$PREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_ELFINTERP="'$interpreter'"'\
|
||||
-D 'CONFIG_TCC_LIBPATHS="'$ABSPREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_SYSINCLUDEPATHS="'$MES_PREFIX'/include:'$PREFIX'/include:{B}/include"'\
|
||||
-D 'TCC_LIBGCC="'$ABSPREFIX'/lib/libc.a"'\
|
||||
-D BOOTSTRAP=1\
|
||||
-D CONFIG_TCCBOOT=1\
|
||||
-D CONFIG_TCC_STATIC=1\
|
||||
-D CONFIG_USE_LIBGCC=1\
|
||||
-D TCC_MES_LIBC=1\
|
||||
-D TCC_TARGET_I386=1\
|
||||
$t.c
|
||||
time sh $MESCC $MESCCFLAGS -S -o $t.M1 $t.E
|
||||
else
|
||||
time sh $MESCC $MESCCFLAGS -S -o $t.M1\
|
||||
$CFLAGS\
|
||||
-I .\
|
||||
-I $MES_PREFIX/lib\
|
||||
-I $MES_PREFIX/include\
|
||||
-D inline=\
|
||||
-D 'CONFIG_TCCDIR="'$PREFIX'/lib/tcc"'\
|
||||
-D 'CONFIG_TCC_CRTPREFIX="'$PREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_ELFINTERP="'$interpreter'"'\
|
||||
-D 'CONFIG_TCC_LIBPATHS="'$ABSPREFIX'/lib:{B}/lib:."'\
|
||||
-D 'CONFIG_TCC_SYSINCLUDEPATHS="'$MES_PREFIX'/include:'$PREFIX'/include:{B}/include"'\
|
||||
-D CONFIG_USE_LIBGCC=1\
|
||||
-D 'TCC_LIBGCC="'$ABSPREFIX'/lib/libc.a"'\
|
||||
-D BOOTSTRAP=1\
|
||||
-D CONFIG_TCCBOOT=1\
|
||||
-D CONFIG_TCC_STATIC=1\
|
||||
-D CONFIG_USE_LIBGCC=1\
|
||||
-D TCC_MES_LIBC=1\
|
||||
-D TCC_TARGET_I386=1\
|
||||
$t.c
|
||||
fi
|
||||
|
||||
tr -d '\r' < $t.M1 > $t.S
|
|
@ -0,0 +1,265 @@
|
|||
#! /bin/sh
|
||||
|
||||
###MESCC=${MESCC-mescc}
|
||||
MES_ARENA=70000000
|
||||
MES_MAX_ARENA=70000000
|
||||
export MES_ARENA MES_MAX_ARENA
|
||||
MES=guile
|
||||
MESCC=${MESCC-../mes/pre-inst-env mescc}
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-../mes}
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}}
|
||||
|
||||
tests="
|
||||
t
|
||||
00-exit-0
|
||||
01-return-0
|
||||
02-return-1
|
||||
03-call
|
||||
04-call-0
|
||||
05-call-1
|
||||
06-call-!1
|
||||
10-if-0
|
||||
11-if-1
|
||||
12-if-==
|
||||
13-if-!=
|
||||
14-if-goto
|
||||
15-if-!f
|
||||
16-if-t
|
||||
20-while
|
||||
21-char[]
|
||||
22-while-char[]
|
||||
23-pointer
|
||||
30-strlen
|
||||
31-eputs
|
||||
32-compare
|
||||
33-and-or
|
||||
34-pre-post
|
||||
35-compare-char
|
||||
36-compare-arithmetic
|
||||
37-compare-assign
|
||||
38-compare-call
|
||||
40-if-else
|
||||
41-?
|
||||
42-goto-label
|
||||
43-for-do-while
|
||||
44-switch
|
||||
45-void-call
|
||||
46-function-static
|
||||
47-function-expression
|
||||
48-function-destruct
|
||||
49-global-static
|
||||
4a-char-array
|
||||
50-assert
|
||||
51-strcmp
|
||||
52-itoa
|
||||
53-strcpy
|
||||
54-argv
|
||||
60-math
|
||||
61-array
|
||||
62-array
|
||||
63-struct-cell
|
||||
64-make-cell
|
||||
65-read
|
||||
70-printf
|
||||
71-struct-array
|
||||
72-typedef-struct-def
|
||||
73-union
|
||||
74-multi-line-string
|
||||
75-struct-union
|
||||
76-pointer-arithmetic
|
||||
77-pointer-assign
|
||||
78-union-struct
|
||||
79-int-array
|
||||
7a-struct-char-array
|
||||
7b-struct-int-array
|
||||
7c-dynarray
|
||||
7d-cast-char
|
||||
7e-struct-array-access
|
||||
7f-struct-pointer-arithmetic
|
||||
7g-struct-byte-word-field
|
||||
7h-struct-assign
|
||||
7i-struct-struct
|
||||
7j-strtoull
|
||||
7k-for-each-elem
|
||||
7l-struct-any-size-array
|
||||
7m-struct-char-array-assign
|
||||
7n-struct-struct-array
|
||||
7o-struct-pre-post
|
||||
7p-struct-cast
|
||||
7q-bit-field
|
||||
80-setjmp
|
||||
81-qsort
|
||||
82-define
|
||||
83-heterogenoous-init
|
||||
84-struct-field-list
|
||||
86-strncpy
|
||||
87-sscanf
|
||||
90-strpbrk
|
||||
91-fseek
|
||||
"
|
||||
|
||||
broken="
|
||||
t
|
||||
00-exit-0
|
||||
01-return-0
|
||||
02-return-1
|
||||
03-call
|
||||
04-call-0
|
||||
05-call-1
|
||||
06-call-!1
|
||||
10-if-0
|
||||
11-if-1
|
||||
12-if-==
|
||||
13-if-!=
|
||||
14-if-goto
|
||||
15-if-!f
|
||||
16-if-t
|
||||
20-while
|
||||
21-char[]
|
||||
22-while-char[]
|
||||
23-pointer
|
||||
"
|
||||
|
||||
if [ ! -x ./i686-unknown-linux-gnu-tcc ]; then
|
||||
broken="$broken
|
||||
02-return-1
|
||||
05-call-1
|
||||
"
|
||||
fi
|
||||
|
||||
expect=$(echo $broken | wc -w)
|
||||
mkdir -p scaffold/tests
|
||||
|
||||
set +e
|
||||
pass=0
|
||||
fail=0
|
||||
total=0
|
||||
for t in $tests; do
|
||||
sh test.sh "$MES_PREFIX/scaffold/tests/$t" &> "scaffold/tests/$t".log
|
||||
r=$?
|
||||
total=$((total+1))
|
||||
if [ $r = 0 ]; then
|
||||
echo $t: [OK]
|
||||
pass=$((pass+1))
|
||||
else
|
||||
echo $t: [FAIL]
|
||||
fail=$((fail+1))
|
||||
fi
|
||||
done
|
||||
|
||||
tests="
|
||||
00_assignment
|
||||
01_comment
|
||||
02_printf
|
||||
03_struct
|
||||
04_for
|
||||
05_array
|
||||
06_case
|
||||
07_function
|
||||
08_while
|
||||
09_do_while
|
||||
|
||||
10_pointer
|
||||
11_precedence
|
||||
12_hashdefine
|
||||
13_integer_literals
|
||||
14_if
|
||||
15_recursion
|
||||
16_nesting
|
||||
17_enum
|
||||
18_include
|
||||
19_pointer_arithmetic
|
||||
|
||||
20_pointer_comparison
|
||||
21_char_array
|
||||
22_floating_point
|
||||
23_type_coercion
|
||||
24_math_library
|
||||
25_quicksort
|
||||
26_character_constants
|
||||
27_sizeof
|
||||
28_strings
|
||||
29_array_address
|
||||
|
||||
30_hanoi
|
||||
31_args
|
||||
32_led
|
||||
33_ternary_op
|
||||
34_array_assignment
|
||||
35_sizeof
|
||||
36_array_initialisers
|
||||
37_sprintf
|
||||
38_multiple_array_index
|
||||
39_typedef
|
||||
|
||||
40_stdio
|
||||
41_hashif
|
||||
42_function_pointer
|
||||
43_void_param
|
||||
44_scoped_declarations
|
||||
45_empty_for
|
||||
47_switch_return
|
||||
48_nested_break
|
||||
49_bracket_evaluation
|
||||
|
||||
50_logical_second_arg
|
||||
51_static
|
||||
52_unnamed_enum
|
||||
54_goto
|
||||
55_lshift_type
|
||||
"
|
||||
|
||||
broken="$broken
|
||||
22_floating_point
|
||||
23_type_coercion
|
||||
24_math_library
|
||||
34_array_assignment
|
||||
37_sprintf
|
||||
40_stdio
|
||||
49_bracket_evaluation
|
||||
55_lshift_type
|
||||
"
|
||||
|
||||
#22_floating_point ; float
|
||||
#23_type_coercion ; float
|
||||
#24_math_library ; float
|
||||
#27_sizeof ; float
|
||||
#34_array_assignment ; fails with GCC
|
||||
#37_sprintf ; integer formatting unsupported
|
||||
|
||||
#49_bracket_evaluation ; float
|
||||
|
||||
|
||||
mkdir -p scaffold/tinycc
|
||||
|
||||
expect=$(echo $broken | wc -w)
|
||||
for t in $tests; do
|
||||
if [ ! -f $MES_PREFIX/scaffold/tinycc/"$t.c" ]; then
|
||||
echo ' [SKIP]'
|
||||
continue;
|
||||
fi
|
||||
sh test.sh "$MES_PREFIX/scaffold/tinycc/$t" &> scaffold/tinycc/"$t".log
|
||||
r=$?
|
||||
total=$((total+1))
|
||||
if [ $r = 0 ]; then
|
||||
echo $t: [OK]
|
||||
pass=$((pass+1))
|
||||
else
|
||||
echo $t: [FAIL]
|
||||
fail=$((fail+1))
|
||||
fi
|
||||
done
|
||||
[ $expect != 0 ] && echo "expect: $expect"
|
||||
[ $fail != 0 ] && echo "failed: $fail"
|
||||
echo "passed: $pass"
|
||||
[ $fail -lt $expect ] && echo "solved: $(($expect - $fail))"
|
||||
echo "total: $total"
|
||||
if [ $fail != 0 -a $fail -gt $expect ]; then
|
||||
echo FAILED: $fail/$total
|
||||
exit 1
|
||||
elif [ $fail != 0 ]; then
|
||||
echo PASS: $pass/$total
|
||||
else
|
||||
echo PASS: $total
|
||||
fi
|
|
@ -0,0 +1,15 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f *.i686-unknown-linux-gnu-o *.mes-o
|
||||
rm -f 1 2 1.elf 2.elf 1.a 2.a
|
||||
|
||||
# trivial object
|
||||
./tcc -c -I ../mes/include ../mes/scaffold/main.c 2>/dev/null
|
||||
./i686-unknown-linux-gnu-tcc -o main.i686-unknown-linux-gnu-o -c -I ../mes/include ../mes/scaffold/main.c 2> 1
|
||||
set +e
|
||||
./mes-tcc -o main.mes-o -c -I ../mes/include ../mes/scaffold/main.c &> 2
|
||||
diff -y 1 2
|
||||
readelf -a main.i686-unknown-linux-gnu-o > 1.elf
|
||||
readelf -a main.mes-o > 2.elf
|
||||
diff -y 1.elf 2.elf || :
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f *.o *.a *.E *.hex2 *.mesc-o *.i686-unknown-linux-gnu-o *.M1
|
||||
rm -f 1 2 1.elf 2.elf
|
||||
|
||||
# trivial object
|
||||
set +e
|
||||
./tcc -c -I ../mes/mlibc/include ../mes/scaffold/main.c 2>/dev/null
|
||||
./i686-unknown-linux-gnu-tcc -o main.i686-unknown-linux-gnu-o -c -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 1
|
||||
./tcc.mes -o main.mesc-o -c -I ../mes/mlibc/include ../mes/scaffold/main.c &> 2
|
||||
diff -y 1 2
|
||||
|
||||
readelf -a main.i686-unknown-linux-gnu-o > 1.elf
|
||||
readelf -a main.mesc-o > 2.elf
|
||||
diff -y 1.elf 2.elf
|
||||
|
||||
# trivial bin
|
||||
./tcc ../mes/scaffold/main.c
|
||||
./i686-unknown-linux-gnu-tcc -o a.i686-unknown-linux-gnu-out -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 1.a
|
||||
./tcc.mes -o a.mes-out -I ../mes/mlibc/include ../mes/scaffold/main.c 2> 2.a
|
||||
diff -y 1.a 2.a
|
|
@ -0,0 +1,59 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
export BLOOD_ELF
|
||||
export BUILD_DEBUG
|
||||
export GUILE_LOAD_PATH
|
||||
export HEX2
|
||||
export M1
|
||||
export MES
|
||||
export MESCC
|
||||
export MES_DEBUG
|
||||
export MES_PREFIX
|
||||
export ONE_SOURCE
|
||||
export PREFIX
|
||||
export PREPROCESS
|
||||
export TINYCC_SEED
|
||||
|
||||
PREFIX=usr
|
||||
HEX2=../mescc-tools/bin/hex2
|
||||
M1=../mescc-tools/bin/M1
|
||||
BLOOD_ELF=../mescc-tools/bin/blood-elf
|
||||
MES=${MES-../mes/src/mes}
|
||||
MES_ARENA=70000000
|
||||
MES_MAX_ARENA=70000000
|
||||
export MES_ARENA MES_MAX_ARENA
|
||||
|
||||
MES=guile
|
||||
#MES=${MES-../mes/src/mes.gcc}
|
||||
#MES=${MES-../mes/src/mes.mlibc-gcc}
|
||||
MESCC=${MESCC-../mes/pre-inst-env mescc}
|
||||
|
||||
#GUILE_LOAD_PATH=/home/janneke/src/nyacc/module:$GUILE_LOAD_PATH
|
||||
GUILE_LOAD_PATH=nyacc
|
||||
|
||||
MES_DEBUG=2
|
||||
MES_PREFIX=../mes
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
|
||||
if [ -z "$interpreter" -a -n "$GUIX" ]; then
|
||||
interpreter=$($GUIX environment --ad-hoc patchelf -- patchelf --print-interpreter $(guix build --system=i686-linux hello)/bin/hello)
|
||||
elif [ -x /lib/ld-linux.so.2 ]; then
|
||||
# legacy non-GuixSD support
|
||||
interpreter=/lib/ld-linux.so.2
|
||||
fi
|
||||
interpreter=${interpreter-interpreter}
|
||||
export interpreter
|
||||
|
||||
sh build-gcc.sh
|
||||
|
||||
PREPROCESS=1
|
||||
ONE_SOURCE=1
|
||||
|
||||
sh build-x86.sh
|
||||
sh build.sh
|
||||
sh compile.sh
|
||||
sh link.sh ||:
|
||||
sh check.sh
|
||||
rm -rf usr
|
||||
sh install.sh
|
80
elf.h
80
elf.h
|
@ -655,24 +655,28 @@ typedef struct
|
|||
|
||||
/* Dynamic section entry. */
|
||||
|
||||
union Elf32_Dyn_un
|
||||
{
|
||||
Elf32_Word d_val; /* Integer value */
|
||||
Elf32_Addr d_ptr; /* Address value */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag; /* Dynamic entry type */
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val; /* Integer value */
|
||||
Elf32_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
union Elf32_Dyn_un d_un;
|
||||
} Elf32_Dyn;
|
||||
|
||||
union Elf64_Dyn_un
|
||||
{
|
||||
Elf64_Xword d_val; /* Integer value */
|
||||
Elf64_Addr d_ptr; /* Address value */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Dynamic entry type */
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val; /* Integer value */
|
||||
Elf64_Addr d_ptr; /* Address value */
|
||||
} d_un;
|
||||
union Elf64_Dyn_un d_un;
|
||||
} Elf64_Dyn;
|
||||
|
||||
/* Legal values for d_tag (dynamic entry type). */
|
||||
|
@ -954,28 +958,32 @@ typedef struct
|
|||
types are an arrangement between the exec server and the program
|
||||
interpreter, so we don't fully specify them here. */
|
||||
|
||||
union Elf32_auxv_t_a_un
|
||||
{
|
||||
uint32_t a_val; /* Integer value */
|
||||
/* We use to have pointer elements added here. We cannot do that,
|
||||
though, since it does not work when using 32-bit definitions
|
||||
on 64-bit platforms and vice versa. */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t a_type; /* Entry type */
|
||||
union
|
||||
{
|
||||
uint32_t a_val; /* Integer value */
|
||||
/* We use to have pointer elements added here. We cannot do that,
|
||||
though, since it does not work when using 32-bit definitions
|
||||
on 64-bit platforms and vice versa. */
|
||||
} a_un;
|
||||
union Elf32_auxv_t_a_un a_un;
|
||||
} Elf32_auxv_t;
|
||||
|
||||
union Elf64_auxv_t_a_un
|
||||
{
|
||||
uint64_t a_val; /* Integer value */
|
||||
/* We use to have pointer elements added here. We cannot do that,
|
||||
though, since it does not work when using 32-bit definitions
|
||||
on 64-bit platforms and vice versa. */
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t a_type; /* Entry type */
|
||||
union
|
||||
{
|
||||
uint64_t a_val; /* Integer value */
|
||||
/* We use to have pointer elements added here. We cannot do that,
|
||||
though, since it does not work when using 32-bit definitions
|
||||
on 64-bit platforms and vice versa. */
|
||||
} a_un;
|
||||
union Elf64_auxv_t_a_un a_un;
|
||||
} Elf64_auxv_t;
|
||||
|
||||
/* Legal values for a_type (entry type). */
|
||||
|
@ -1486,18 +1494,22 @@ typedef struct
|
|||
|
||||
/* Entries found in sections of type SHT_MIPS_GPTAB. */
|
||||
|
||||
struct Elf32_gptab_header
|
||||
{
|
||||
Elf32_Word gt_current_g_value; /* -G value used for compilation */
|
||||
Elf32_Word gt_unused; /* Not used */
|
||||
};
|
||||
|
||||
struct Elf32_gptab_entry
|
||||
{
|
||||
Elf32_Word gt_g_value; /* If this value were used for -G */
|
||||
Elf32_Word gt_bytes; /* This many bytes would be used */
|
||||
};
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
Elf32_Word gt_current_g_value; /* -G value used for compilation */
|
||||
Elf32_Word gt_unused; /* Not used */
|
||||
} gt_header; /* First entry in section */
|
||||
struct
|
||||
{
|
||||
Elf32_Word gt_g_value; /* If this value were used for -G */
|
||||
Elf32_Word gt_bytes; /* This many bytes would be used */
|
||||
} gt_entry; /* Subsequent entries in section */
|
||||
struct Elf32_gptab_header gt_header;
|
||||
struct Elf32_gptab_entry gt_entry;
|
||||
} Elf32_gptab;
|
||||
|
||||
/* Entry found in sections of type SHT_MIPS_REGINFO. */
|
||||
|
|
17
i386-asm.c
17
i386-asm.c
|
@ -19,7 +19,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define MAX_OPERANDS 3
|
||||
|
||||
|
@ -680,7 +682,8 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
|||
const ASMInstr *pa;
|
||||
int i, modrm_index, modreg_index, reg, v, op1, seg_prefix, pc;
|
||||
int nb_ops, s;
|
||||
Operand ops[MAX_OPERANDS], *pop;
|
||||
Operand ops[MAX_OPERANDS];
|
||||
Operand *pop;
|
||||
int op_type[3]; /* decoded op type */
|
||||
int alltypes; /* OR of all operand types */
|
||||
int autosize;
|
||||
|
@ -1197,7 +1200,8 @@ ST_FUNC int asm_parse_regvar (int t)
|
|||
s = table_ident[t - TOK_IDENT]->str;
|
||||
if (s[0] != '%')
|
||||
return -1;
|
||||
t = tok_alloc(s+1, strlen(s)-1)->tok;
|
||||
TokenSym *tok = tok_alloc(s+1, strlen(s)-1);
|
||||
t = tok->tok;
|
||||
unget_tok(t);
|
||||
unget_tok('%');
|
||||
parse_operand(tcc_state, &op);
|
||||
|
@ -1478,7 +1482,8 @@ ST_FUNC void subst_asm_operand(CString *add_str,
|
|||
in the C symbol table when later looking up
|
||||
this name. So enter them now into the asm label
|
||||
list when we still know the symbol. */
|
||||
get_asm_sym(tok_alloc(name, strlen(name))->tok, sv->sym);
|
||||
TokenSym *tok = tok_alloc(name, strlen(name));
|
||||
get_asm_sym(tok->tok, sv->sym);
|
||||
}
|
||||
cstr_cat(add_str, name, -1);
|
||||
if ((uint32_t)sv->c.i == 0)
|
||||
|
@ -1588,6 +1593,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
|||
ASMOperand *op;
|
||||
int i, reg;
|
||||
|
||||
trace_enter ("asm_gen_code");
|
||||
/* Strictly speaking %Xbp and %Xsp should be included in the
|
||||
call-preserved registers, but currently it doesn't matter. */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
|
@ -1609,7 +1615,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
|||
}
|
||||
if (!is_output) {
|
||||
/* generate reg save code */
|
||||
for(i = 0; i < sizeof(reg_saved)/sizeof(reg_saved[0]); i++) {
|
||||
for(i = 0; i < sizeof(reg_saved)/sizeof(uint8_t); i++) {
|
||||
reg = reg_saved[i];
|
||||
if (regs_allocated[reg]) {
|
||||
if (reg >= 8)
|
||||
|
@ -1672,7 +1678,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
|||
}
|
||||
}
|
||||
/* generate reg restore code */
|
||||
for(i = sizeof(reg_saved)/sizeof(reg_saved[0]) - 1; i >= 0; i--) {
|
||||
for(i = sizeof(reg_saved)/sizeof(uint8_t) - 1; i >= 0; i--) {
|
||||
reg = reg_saved[i];
|
||||
if (regs_allocated[reg]) {
|
||||
if (reg >= 8)
|
||||
|
@ -1681,6 +1687,7 @@ ST_FUNC void asm_gen_code(ASMOperand *operands, int nb_operands,
|
|||
}
|
||||
}
|
||||
}
|
||||
trace_exit ("asm_gen_code");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_clobber(uint8_t *clobber_regs, const char *str)
|
||||
|
|
60
i386-gen.c
60
i386-gen.c
|
@ -74,7 +74,9 @@ enum {
|
|||
/******************************************************/
|
||||
#else /* ! TARGET_DEFS_ONLY */
|
||||
/******************************************************/
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* define to 1/0 to [not] have EBX as 4th register */
|
||||
#define USE_EBX 0
|
||||
|
@ -97,6 +99,8 @@ static unsigned long func_bound_ind;
|
|||
/* XXX: make it faster ? */
|
||||
ST_FUNC void g(int c)
|
||||
{
|
||||
trace_enter ("g");
|
||||
trace ("gen o c="); eputs (itoa (c)); eputs ("\n");
|
||||
int ind1;
|
||||
if (nocode_wanted)
|
||||
return;
|
||||
|
@ -104,7 +108,9 @@ ST_FUNC void g(int c)
|
|||
if (ind1 > cur_text_section->data_allocated)
|
||||
section_realloc(cur_text_section, ind1);
|
||||
cur_text_section->data[ind] = c;
|
||||
trace ("gen o data="); eputs (itoa (cur_text_section->data[ind])); eputs ("\n");
|
||||
ind = ind1;
|
||||
trace_exit ("g");
|
||||
}
|
||||
|
||||
ST_FUNC void o(unsigned int c)
|
||||
|
@ -204,6 +210,7 @@ ST_FUNC void load(int r, SValue *sv)
|
|||
int v, t, ft, fc, fr;
|
||||
SValue v1;
|
||||
|
||||
trace_enter ("load");
|
||||
#ifdef TCC_TARGET_PE
|
||||
SValue v2;
|
||||
sv = pe_getimport(sv, &v2);
|
||||
|
@ -275,6 +282,7 @@ ST_FUNC void load(int r, SValue *sv)
|
|||
o(0xc0 + r + v * 8); /* mov v, r */
|
||||
}
|
||||
}
|
||||
trace_exit ("load");
|
||||
}
|
||||
|
||||
/* store register 'r' in lvalue 'v' */
|
||||
|
@ -282,6 +290,7 @@ ST_FUNC void store(int r, SValue *v)
|
|||
{
|
||||
int fr, bt, ft, fc;
|
||||
|
||||
trace_enter ("store");
|
||||
#ifdef TCC_TARGET_PE
|
||||
SValue v2;
|
||||
v = pe_getimport(v, &v2);
|
||||
|
@ -318,6 +327,7 @@ ST_FUNC void store(int r, SValue *v)
|
|||
} else if (fr != r) {
|
||||
o(0xc0 + fr + r * 8); /* mov r, fr */
|
||||
}
|
||||
trace_exit ("store");
|
||||
}
|
||||
|
||||
static void gadd_sp(int val)
|
||||
|
@ -428,6 +438,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||
int size, align, r, args_size, i, func_call;
|
||||
Sym *func_sym;
|
||||
|
||||
trace_enter ("gfunc_call");
|
||||
args_size = 0;
|
||||
for(i = 0;i < nb_args; i++) {
|
||||
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
|
@ -507,6 +518,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||
if (args_size && func_call != FUNC_STDCALL)
|
||||
gadd_sp(args_size);
|
||||
vtop--;
|
||||
trace_exit ("gfunc_call");
|
||||
}
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
|
@ -524,30 +536,40 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
|||
Sym *sym;
|
||||
CType *type;
|
||||
|
||||
trace_enter ("gfunc_prolog");
|
||||
sym = func_type->ref;
|
||||
func_call = sym->a.func_call;
|
||||
addr = 8;
|
||||
loc = 0;
|
||||
func_vc = 0;
|
||||
|
||||
trace ("gfunc_prolog 10\n");
|
||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||
trace ("gfunc_prolog 11\n");
|
||||
fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
|
||||
fastcall_regs_ptr = fastcall_regs;
|
||||
} else if (func_call == FUNC_FASTCALLW) {
|
||||
trace ("gfunc_prolog 15\n");
|
||||
fastcall_nb_regs = 2;
|
||||
fastcall_regs_ptr = fastcallw_regs;
|
||||
} else {
|
||||
trace ("gfunc_prolog 18\n");
|
||||
fastcall_nb_regs = 0;
|
||||
fastcall_regs_ptr = NULL;
|
||||
}
|
||||
param_index = 0;
|
||||
|
||||
trace ("gfunc_prolog 20\n");
|
||||
ind += FUNC_PROLOG_SIZE;
|
||||
trace ("gfunc_prolog 21\n");
|
||||
func_sub_sp_offset = ind;
|
||||
trace ("gfunc_prolog 22\n");
|
||||
/* if the function returns a structure, then add an
|
||||
implicit pointer parameter */
|
||||
func_vt = sym->type;
|
||||
trace ("gfunc_prolog 23\n");
|
||||
func_var = (sym->c == FUNC_ELLIPSIS);
|
||||
trace ("gfunc_prolog 24\n");
|
||||
#ifdef TCC_TARGET_PE
|
||||
size = type_size(&func_vt,&align);
|
||||
if (((func_vt.t & VT_BTYPE) == VT_STRUCT)
|
||||
|
@ -555,29 +577,35 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
|||
#else
|
||||
if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
|
||||
#endif
|
||||
trace ("gfunc_prolog 25\n");
|
||||
/* XXX: fastcall case ? */
|
||||
func_vc = addr;
|
||||
addr += 4;
|
||||
param_index++;
|
||||
}
|
||||
trace ("gfunc_prolog 30\n");
|
||||
/* define parameters */
|
||||
while ((sym = sym->next) != NULL) {
|
||||
trace ("gfunc_prolog 31 param_index="); eputs (itoa (param_index)); eputs ("\n");
|
||||
type = &sym->type;
|
||||
size = type_size(type, &align);
|
||||
size = (size + 3) & ~3;
|
||||
#ifdef FUNC_STRUCT_PARAM_AS_PTR
|
||||
/* structs are passed as pointer */
|
||||
if ((type->t & VT_BTYPE) == VT_STRUCT) {
|
||||
trace ("gfunc_prolog 36\n");
|
||||
size = 4;
|
||||
}
|
||||
#endif
|
||||
if (param_index < fastcall_nb_regs) {
|
||||
trace ("gfunc_prolog 38\n");
|
||||
/* save FASTCALL register */
|
||||
loc -= 4;
|
||||
o(0x89); /* movl */
|
||||
gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
|
||||
param_addr = loc;
|
||||
} else {
|
||||
trace ("gfunc_prolog 39\n");
|
||||
param_addr = addr;
|
||||
addr += size;
|
||||
}
|
||||
|
@ -586,6 +614,7 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
|||
param_index++;
|
||||
}
|
||||
func_ret_sub = 0;
|
||||
trace ("gfunc_prolog 50\n");
|
||||
/* pascal type call ? */
|
||||
if (func_call == FUNC_STDCALL)
|
||||
func_ret_sub = addr - 8;
|
||||
|
@ -594,15 +623,18 @@ ST_FUNC void gfunc_prolog(CType *func_type)
|
|||
func_ret_sub = 4;
|
||||
#endif
|
||||
|
||||
trace ("gfunc_prolog 60\n");
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
/* leave some room for bound checking code */
|
||||
if (tcc_state->do_bounds_check) {
|
||||
trace ("gfunc_prolog 61\n");
|
||||
func_bound_offset = lbounds_section->data_offset;
|
||||
func_bound_ind = ind;
|
||||
oad(0xb8, 0); /* lbound section pointer */
|
||||
oad(0xb8, 0); /* call to function */
|
||||
}
|
||||
#endif
|
||||
trace_exit ("gfunc_prolog");
|
||||
}
|
||||
|
||||
/* generate function epilog */
|
||||
|
@ -610,9 +642,11 @@ ST_FUNC void gfunc_epilog(void)
|
|||
{
|
||||
addr_t v, saved_ind;
|
||||
|
||||
trace ("gfunc_epilog\n");
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (tcc_state->do_bounds_check
|
||||
&& func_bound_offset != lbounds_section->data_offset) {
|
||||
trace ("gfunc_epilog 01\n");
|
||||
addr_t saved_ind;
|
||||
addr_t *bounds_ptr;
|
||||
Sym *sym_data;
|
||||
|
@ -641,18 +675,22 @@ ST_FUNC void gfunc_epilog(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
trace ("gfunc_epilog 20\n");
|
||||
/* align local size to word & save local variables */
|
||||
v = (-loc + 3) & -4;
|
||||
|
||||
#if USE_EBX
|
||||
trace ("gfunc_epilog 21\n");
|
||||
o(0x8b);
|
||||
gen_modrm(TREG_EBX, VT_LOCAL, NULL, -(v+4));
|
||||
#endif
|
||||
|
||||
o(0xc9); /* leave */
|
||||
if (func_ret_sub == 0) {
|
||||
trace ("gfunc_epilog 23\n");
|
||||
o(0xc3); /* ret */
|
||||
} else {
|
||||
trace ("gfunc_epilog 24\n");
|
||||
o(0xc2); /* ret n */
|
||||
g(func_ret_sub);
|
||||
g(func_ret_sub >> 8);
|
||||
|
@ -666,6 +704,7 @@ ST_FUNC void gfunc_epilog(void)
|
|||
} else
|
||||
#endif
|
||||
{
|
||||
trace ("gfunc_epilog 30\n");
|
||||
o(0xe58955); /* push %ebp, mov %esp, %ebp */
|
||||
o(0xec81); /* sub esp, stacksize */
|
||||
gen_le32(v);
|
||||
|
@ -700,7 +739,8 @@ ST_FUNC void gtst_addr(int inv, int a)
|
|||
{
|
||||
int v = vtop->r & VT_VALMASK;
|
||||
if (v == VT_CMP) {
|
||||
inv ^= (vtop--)->c.i;
|
||||
inv ^= vtop->c.i;
|
||||
vtop--;
|
||||
a -= ind + 2;
|
||||
if (a == (char)a) {
|
||||
g(inv - 32);
|
||||
|
@ -757,6 +797,8 @@ ST_FUNC void gen_opi(int op)
|
|||
{
|
||||
int r, fr, opc, c;
|
||||
|
||||
trace_enter ("gen_opi");
|
||||
trace ("gen_opi op="); eputs (itoa (op)); eputs ("\n");
|
||||
switch(op) {
|
||||
case '+':
|
||||
case TOK_ADDC1: /* add with carry generation */
|
||||
|
@ -768,7 +810,14 @@ ST_FUNC void gen_opi(int op)
|
|||
r = gv(RC_INT);
|
||||
vswap();
|
||||
c = vtop->c.i;
|
||||
trace ("gen_opi 14 c ="); eputs (itoa (c)); eputs ("\n");
|
||||
#if __MESC__
|
||||
char ch = c;
|
||||
if (c == ch && ((ch >= 0 && ch < 128) || c < 0)) {
|
||||
#else
|
||||
if (c == (char)c) {
|
||||
#endif
|
||||
trace ("gen_opi 15 c == char c\n");
|
||||
/* generate inc and dec for smaller code */
|
||||
if (c==1 && opc==0 && op != TOK_ADDC1) {
|
||||
o (0x40 | r); // inc
|
||||
|
@ -780,6 +829,7 @@ ST_FUNC void gen_opi(int op)
|
|||
g(c);
|
||||
}
|
||||
} else {
|
||||
trace ("gen_opi 20\n");
|
||||
o(0x81);
|
||||
oad(0xc0 | (opc << 3) | r, c);
|
||||
}
|
||||
|
@ -962,10 +1012,6 @@ ST_FUNC void gen_opf(int op)
|
|||
}
|
||||
|
||||
switch(op) {
|
||||
default:
|
||||
case '+':
|
||||
a = 0;
|
||||
break;
|
||||
case '-':
|
||||
a = 4;
|
||||
if (swapped)
|
||||
|
@ -979,6 +1025,10 @@ ST_FUNC void gen_opf(int op)
|
|||
if (swapped)
|
||||
a++;
|
||||
break;
|
||||
case '+':
|
||||
default:
|
||||
a = 0;
|
||||
break;
|
||||
}
|
||||
ft = vtop->type.t;
|
||||
fc = vtop->c.i;
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
|
||||
#else /* !TARGET_DEFS_ONLY */
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* Returns 1 for a code relocation, 0 for a data relocation. For unknown
|
||||
relocations, returns -1. */
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#! /bin/sh
|
||||
|
||||
if [ -n "$BUILD_DEBUG" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
PREFIX=${PREFIX-usr}
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}}
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
|
||||
mkdir -p $PREFIX/bin
|
||||
cp tcc $PREFIX/bin
|
||||
tar -C $MES_PREFIX -cf- include | tar -C $PREFIX -xf-
|
||||
|
||||
mkdir -p $PREFIX/lib
|
||||
cp crt1.o $PREFIX/lib/crt1.o
|
||||
cp crti.o $PREFIX/lib/crti.o
|
||||
cp crtn.o $PREFIX/lib/crtn.o
|
||||
|
||||
mkdir -p $PREFIX/lib/tcc
|
||||
cp libc.a $PREFIX/lib
|
||||
cp libtcc1.a $PREFIX/lib/tcc
|
||||
|
||||
tar -C $TINYCC_SEED -cf- . | tar -C $PREFIX/lib -xf-
|
|
@ -47,6 +47,7 @@ typedef union
|
|||
DWtype ll;
|
||||
} DWunion;
|
||||
|
||||
#if HAVE_FLOAT
|
||||
typedef long double XFtype;
|
||||
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
||||
#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
||||
|
@ -620,3 +621,4 @@ long long __fixxfdi (long double a1)
|
|||
return s ? ret : -ret;
|
||||
}
|
||||
#endif /* !ARM */
|
||||
#endif // HAVE_FLOAT
|
||||
|
|
239
libtcc.c
239
libtcc.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
/* global variables */
|
||||
|
@ -32,7 +34,11 @@ ST_DATA int tcc_ext = 1;
|
|||
/* XXX: get rid of this ASAP */
|
||||
ST_DATA struct TCCState *tcc_state;
|
||||
|
||||
#if __MESC__
|
||||
int nb_states;
|
||||
#else
|
||||
static int nb_states;
|
||||
#endif
|
||||
|
||||
/********************************************************/
|
||||
|
||||
|
@ -137,7 +143,8 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
|
|||
/* copy a string and truncate it. */
|
||||
ST_FUNC char *pstrcpy(char *buf, int buf_size, const char *s)
|
||||
{
|
||||
char *q, *q_end;
|
||||
char *q;
|
||||
char *q_end;
|
||||
int c;
|
||||
|
||||
if (buf_size > 0) {
|
||||
|
@ -174,7 +181,8 @@ ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)
|
|||
/* extract the basename of a file */
|
||||
PUB_FUNC char *tcc_basename(const char *name)
|
||||
{
|
||||
char *p = strchr(name, 0);
|
||||
int n = strlen (name);
|
||||
char *p = name + n - 1;
|
||||
while (p > name && !IS_DIRSEP(p[-1]))
|
||||
--p;
|
||||
return p;
|
||||
|
@ -188,7 +196,8 @@ PUB_FUNC char *tcc_fileextension (const char *name)
|
|||
{
|
||||
char *b = tcc_basename(name);
|
||||
char *e = strrchr(b, '.');
|
||||
return e ? e : strchr(b, 0);
|
||||
int n = strlen (name);
|
||||
return e ? e : b + n - 1;
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
|
@ -224,10 +233,14 @@ PUB_FUNC void *tcc_mallocz(unsigned long size)
|
|||
|
||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
||||
{
|
||||
trace_enter ("tcc_realloc");
|
||||
trace ("tcc_realloc size="); eputs (itoa (size)); eputs ("\n");
|
||||
|
||||
void *ptr1;
|
||||
ptr1 = realloc(ptr, size);
|
||||
if (!ptr1 && size)
|
||||
tcc_error("memory full (realloc)");
|
||||
trace_exit ("tcc_realloc");
|
||||
return ptr1;
|
||||
}
|
||||
|
||||
|
@ -437,11 +450,17 @@ ST_FUNC void dynarray_reset(void *pp, int *n)
|
|||
static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
|
||||
{
|
||||
const char *p;
|
||||
//eputs ("sp in="); //eputs (in); //eputs ("\n");
|
||||
do {
|
||||
int c;
|
||||
CString str;
|
||||
//eputs ("sp in="); //eputs (in); //eputs ("\n");
|
||||
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 01 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||
|
||||
|
||||
cstr_new(&str);
|
||||
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 02 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||
|
||||
for (p = in; c = *p, c != '\0' && c != PATHSEP; ++p) {
|
||||
if (c == '{' && p[1] && p[2] == '}') {
|
||||
c = p[1], p += 2;
|
||||
|
@ -453,11 +472,15 @@ static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *
|
|||
}
|
||||
if (str.size) {
|
||||
cstr_ccat(&str, '\0');
|
||||
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 14 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||
dynarray_add(p_ary, p_nb_ary, tcc_strdup(str.data));
|
||||
}
|
||||
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 15 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||
cstr_free(&str);
|
||||
//if (s->nb_files) {struct filespec *f = s->files[0]; //eputs ("sp 16 file[0]="); //eputs (f->name); //eputs ("\n");}
|
||||
in = p+1;
|
||||
} while (*p);
|
||||
//eputs ("sp 99\n");
|
||||
}
|
||||
|
||||
/********************************************************/
|
||||
|
@ -480,7 +503,8 @@ static void strcat_printf(char *buf, int buf_size, const char *fmt, ...)
|
|||
static void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[2048];
|
||||
BufferedFile **pf, *f;
|
||||
BufferedFile **pf;
|
||||
BufferedFile *f;
|
||||
|
||||
buf[0] = '\0';
|
||||
/* use upper file if inline ":asm:" or token ":paste:" */
|
||||
|
@ -573,51 +597,77 @@ PUB_FUNC void tcc_warning(const char *fmt, ...)
|
|||
|
||||
ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen)
|
||||
{
|
||||
trace_enter ("tcc_open_bf");
|
||||
BufferedFile *bf;
|
||||
int buflen = initlen ? initlen : IO_BUF_SIZE;
|
||||
|
||||
bf = tcc_mallocz(sizeof(BufferedFile) + buflen);
|
||||
trace ("tcc_open_bf buflen="); eputs (itoa (buflen)); eputs ("\n");
|
||||
//eputs ("tcc_open_bf bf size="); //eputs (itoa (sizeof (BufferedFile) + buflen)); //eputs ("\n");
|
||||
|
||||
trace ("tcc_open_bf 10\n");
|
||||
bf->buf_ptr = bf->buffer;
|
||||
trace ("tcc_open_bf 11\n");
|
||||
bf->buf_end = bf->buffer + initlen;
|
||||
trace ("tcc_open_bf 12\n");
|
||||
bf->buf_end[0] = CH_EOB; /* put eob symbol */
|
||||
trace ("tcc_open_bf 13\n");
|
||||
pstrcpy(bf->filename, sizeof(bf->filename), filename);
|
||||
trace ("tcc_open_bf 14\n");
|
||||
pstrcpy(bf->filename2, sizeof(bf->filename2), filename);
|
||||
trace ("tcc_open_bf 15\n");
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(bf->filename);
|
||||
#endif
|
||||
trace ("tcc_open_bf 20\n");
|
||||
bf->line_num = 1;
|
||||
bf->ifdef_stack_ptr = s1->ifdef_stack_ptr;
|
||||
bf->fd = -1;
|
||||
bf->prev = file;
|
||||
file = bf;
|
||||
trace_exit ("tcc_open_bf");
|
||||
}
|
||||
|
||||
ST_FUNC void tcc_close(void)
|
||||
{
|
||||
trace_enter ("tcc_close");
|
||||
BufferedFile *bf = file;
|
||||
//eputs ("tcc_close file:"); //eputs (itoa (file)); //eputs ("\n");
|
||||
//eputs ("tcc_close bf->fd:"); //eputs (itoa (bf->fd)); //eputs ("\n");
|
||||
//eputs ("tcc_close bf->prev:"); //eputs (itoa (bf->prev)); //eputs ("\n");
|
||||
if (bf->fd > 0) {
|
||||
//eputs ("tcc_close bf->filename:"); //eputs (bf->filename); //eputs ("\n");
|
||||
close(bf->fd);
|
||||
total_lines += bf->line_num;
|
||||
}
|
||||
trace ("tcc_close file->buf_ptr="); eputs (file->buf_ptr); eputs ("\n");
|
||||
file = bf->prev;
|
||||
tcc_free(bf);
|
||||
trace_exit ("tcc_close");
|
||||
}
|
||||
|
||||
ST_FUNC int tcc_open(TCCState *s1, const char *filename)
|
||||
{
|
||||
int fd;
|
||||
trace_enter ("tcc_open");
|
||||
trace ("tcc_open file-name="); eputs (filename); eputs ("\n");
|
||||
if (strcmp(filename, "-") == 0)
|
||||
fd = 0, filename = "<stdin>";
|
||||
else
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
trace ("tcc_open fd="); eputs (itoa (fd)); eputs ("\n");
|
||||
if ((s1->verbose == 2 && fd >= 0) || s1->verbose == 3)
|
||||
printf("%s %*s%s\n", fd < 0 ? "nf":"->",
|
||||
(int)(s1->include_stack_ptr - s1->include_stack), "", filename);
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
trace_exit ("tcc_open");
|
||||
return -1;
|
||||
|
||||
}
|
||||
eputs ("tcc_open 10\n");
|
||||
tcc_open_bf(s1, filename, 0);
|
||||
eputs ("tcc_open 11\n");
|
||||
file->fd = fd;
|
||||
trace_exit ("tcc_open");
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -626,30 +676,42 @@ static int tcc_compile(TCCState *s1)
|
|||
{
|
||||
Sym *define_start;
|
||||
|
||||
trace_enter ("tcc_compile");
|
||||
define_start = define_stack;
|
||||
if (setjmp(s1->error_jmp_buf) == 0) {
|
||||
s1->nb_errors = 0;
|
||||
s1->error_set_jmp_enabled = 1;
|
||||
|
||||
trace ("tcc_compile 05 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
preprocess_start(s1);
|
||||
trace ("tcc_compile 06 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
|
||||
tccgen_start(s1);
|
||||
trace ("tcc_compile 07 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
|
||||
#ifdef INC_DEBUG
|
||||
printf("%s: **** new file\n", file->filename);
|
||||
#endif
|
||||
|
||||
ch = file->buf_ptr[0];
|
||||
trace ("tcc_compile 08 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
tok_flags = TOK_FLAG_BOL | TOK_FLAG_BOF;
|
||||
parse_flags = PARSE_FLAG_PREPROCESS | PARSE_FLAG_TOK_NUM | PARSE_FLAG_TOK_STR;
|
||||
trace ("tcc_compile 10 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
next();
|
||||
trace ("tcc_compile 11 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
decl(VT_CONST);
|
||||
trace ("tcc_compile 12 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
if (tok != TOK_EOF)
|
||||
expect("declaration");
|
||||
/* free defines here already on behalf of of M.M.'s possibly existing
|
||||
experimental preprocessor implementation. The normal call below
|
||||
is still there to free after error-longjmp */
|
||||
trace ("tcc_compile 13 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
free_defines(define_start);
|
||||
trace ("tcc_compile 14 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
tccgen_end(s1);
|
||||
trace ("tcc_compile 15 nb_errors="); eputs (itoa (s1->nb_errors)); eputs ("\n");
|
||||
}
|
||||
s1->error_set_jmp_enabled = 0;
|
||||
|
||||
|
@ -658,6 +720,7 @@ static int tcc_compile(TCCState *s1)
|
|||
free_defines(define_start);
|
||||
sym_pop(&global_stack, NULL, 0);
|
||||
sym_pop(&local_stack, NULL, 0);
|
||||
trace_exit ("tcc_compile");
|
||||
return s1->nb_errors != 0 ? -1 : 0;
|
||||
}
|
||||
|
||||
|
@ -676,25 +739,37 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *str)
|
|||
/* define a preprocessor symbol. A value can also be provided with the '=' operator */
|
||||
LIBTCCAPI void tcc_define_symbol(TCCState *s1, const char *sym, const char *value)
|
||||
{
|
||||
trace_enter ("tcc_define_symbol");
|
||||
trace ("tcc_define_symbol value="); eputs (itoa (value)); eputs ("\n");
|
||||
|
||||
int len1, len2;
|
||||
/* default value */
|
||||
if (!value)
|
||||
value = "1";
|
||||
trace ("tcc_define_symbol 01\n");
|
||||
len1 = strlen(sym);
|
||||
trace ("tcc_define_symbol 02\n");
|
||||
len2 = strlen(value);
|
||||
trace ("tcc_define_symbol 03\n");
|
||||
|
||||
/* init file structure */
|
||||
tcc_open_bf(s1, "<define>", len1 + len2 + 1);
|
||||
trace ("tcc_define_symbol 04\n");
|
||||
memcpy(file->buffer, sym, len1);
|
||||
file->buffer[len1] = ' ';
|
||||
memcpy(file->buffer + len1 + 1, value, len2);
|
||||
|
||||
trace ("tcc_define_symbol X="); //eputs (file->buffer); //eputs ("\n");
|
||||
/* parse with define parser */
|
||||
ch = file->buf_ptr[0];
|
||||
trace ("tcc_define_symbol 08\n");
|
||||
next_nomacro();
|
||||
trace ("tcc_define_symbol 09\n");
|
||||
parse_define();
|
||||
trace ("tcc_define_symbol 10\n");
|
||||
|
||||
tcc_close();
|
||||
trace_exit ("tcc_define_symbol");
|
||||
}
|
||||
|
||||
/* undefine a preprocessor symbol */
|
||||
|
@ -712,12 +787,15 @@ LIBTCCAPI void tcc_undefine_symbol(TCCState *s1, const char *sym)
|
|||
/* cleanup all static data used during compilation */
|
||||
static void tcc_cleanup(void)
|
||||
{
|
||||
|
||||
if (NULL == tcc_state)
|
||||
return;
|
||||
tccpp_delete(tcc_state);
|
||||
//eputs ("tcc_cleanup01\n");
|
||||
tcc_state = NULL;
|
||||
/* free sym_pools */
|
||||
dynarray_reset(&sym_pools, &nb_sym_pools);
|
||||
//eputs ("tcc_cleanup02\n");
|
||||
/* reset symbol stack */
|
||||
sym_free_first = NULL;
|
||||
}
|
||||
|
@ -726,14 +804,25 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
{
|
||||
TCCState *s;
|
||||
|
||||
//eputs ("tcc_new\n");
|
||||
tcc_cleanup();
|
||||
//eputs ("tcc_new01\n");
|
||||
|
||||
s = tcc_mallocz(sizeof(TCCState));
|
||||
//eputs ("size:"); //eputs (itoa (sizeof(TCCState))); //eputs ("\n");
|
||||
//eputs ("tcc_new02\n");
|
||||
//eputs ("s="); //eputs (itoa (s)); //eputs ("\n");
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
tcc_state = s;
|
||||
|
||||
trace ("tccnew include_stack="); eputs (itoa (&s->include_stack[0])); eputs ("\n");
|
||||
|
||||
++nb_states;
|
||||
|
||||
//eputs ("tcc_new03\n");
|
||||
|
||||
s->alacarte_link = 1;
|
||||
s->nocommon = 1;
|
||||
s->warn_implicit_function_declaration = 1;
|
||||
|
@ -762,6 +851,9 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
|
||||
define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
|
||||
define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
|
||||
#if __MESC__
|
||||
tcc_define_symbol(s, "__TINYC__", "0");
|
||||
#else
|
||||
{
|
||||
/* define __TINYC__ 92X */
|
||||
char buffer[32]; int a,b,c;
|
||||
|
@ -769,7 +861,7 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
sprintf(buffer, "%d", a*10000 + b*100 + c);
|
||||
tcc_define_symbol(s, "__TINYC__", buffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
/* standard defines */
|
||||
tcc_define_symbol(s, "__STDC__", NULL);
|
||||
tcc_define_symbol(s, "__STDC_VERSION__", "199901L");
|
||||
|
@ -885,6 +977,8 @@ LIBTCCAPI TCCState *tcc_new(void)
|
|||
/* Some GCC builtins that are simple to express as macros. */
|
||||
tcc_define_symbol(s, "__builtin_extract_return_addr(x)", "x");
|
||||
#endif /* ndef TCC_TARGET_PE */
|
||||
//eputs ("tcc_new99\n");
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -972,7 +1066,9 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
|
|||
!s->nostdlib) {
|
||||
if (output_type != TCC_OUTPUT_DLL)
|
||||
tcc_add_crt(s, "crt1.o");
|
||||
#if !BOOTSTRAP
|
||||
tcc_add_crt(s, "crti.o");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
@ -990,10 +1086,34 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !__x86_64__
|
||||
#undef eputs
|
||||
#endif
|
||||
|
||||
#if !BOOTSTRAP // MESC
|
||||
#define for_each_elem(sec, startoff, elem, type) \
|
||||
for (elem = (type *) sec->data + startoff; \
|
||||
elem < (type *) (sec->data + sec->data_offset); elem++)
|
||||
#else
|
||||
#define for_each_elem(sec, startoff, elem, type) \
|
||||
elem = sec->data + sizeof (type) * startoff; \
|
||||
for (;elem < ((type *) (sec->data + sec->data_offset)); elem++)
|
||||
#endif
|
||||
|
||||
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
{
|
||||
int ret, filetype;
|
||||
|
||||
trace_enter ("tcc_add_file_internal");
|
||||
char *name;
|
||||
ElfW(Sym) *esym;
|
||||
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||
name = (char *) strtab_section->data + esym->st_name;
|
||||
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||
}
|
||||
|
||||
trace ("tcc_add_file_internal file-name="); eputs (filename); eputs ("\n");
|
||||
filetype = flags & 0x0F;
|
||||
if (filetype == 0) {
|
||||
/* use a file extension to detect a filetype */
|
||||
|
@ -1014,7 +1134,16 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
}
|
||||
|
||||
/* open the file */
|
||||
trace ("tcc_add_file_internal filename="); eputs (filename); eputs ("\n");
|
||||
ret = tcc_open(s1, filename);
|
||||
trace ("tcc_add_file_internal 20 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
|
||||
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||
name = (char *) strtab_section->data + esym->st_name;
|
||||
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (flags & AFF_PRINT_ERROR)
|
||||
tcc_error_noabort("file '%s' not found", filename);
|
||||
|
@ -1025,6 +1154,13 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
dynarray_add(&s1->target_deps, &s1->nb_target_deps,
|
||||
tcc_strdup(filename));
|
||||
|
||||
trace ("tcc_add_file_internal 21\n");
|
||||
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||
name = (char *) strtab_section->data + esym->st_name;
|
||||
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||
}
|
||||
|
||||
parse_flags = 0;
|
||||
/* if .S file, define __ASSEMBLER__ like gcc does */
|
||||
if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
|
||||
|
@ -1032,18 +1168,35 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
parse_flags = PARSE_FLAG_ASM_FILE;
|
||||
}
|
||||
|
||||
trace ("tcc_add_file_internal 22\n");
|
||||
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||
name = (char *) strtab_section->data + esym->st_name;
|
||||
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||
}
|
||||
|
||||
if (flags & AFF_PREPROCESS) {
|
||||
ret = tcc_preprocess(s1);
|
||||
trace ("tcc_add_file_internal 31 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
} else if (filetype == AFF_TYPE_C) {
|
||||
//eputs ("tcc_add_file_internal: compile\n");
|
||||
ret = tcc_compile(s1);
|
||||
trace ("tcc_add_file_internal 32 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
for_each_elem(symtab_section, 1, esym, ElfW(Sym)) {
|
||||
trace ("tcc_add_file_internal num="); eputs (itoa (esym->st_shndx)); eputs ("\n");
|
||||
name = (char *) strtab_section->data + esym->st_name;
|
||||
trace ("tcc_add_file_internal name="); eputs (name); eputs ("\n");
|
||||
}
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
} else if (filetype == AFF_TYPE_ASMPP) {
|
||||
/* non preprocessed assembler */
|
||||
ret = tcc_assemble(s1, 1);
|
||||
trace ("tcc_add_file_internal 33 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
} else if (filetype == AFF_TYPE_ASM) {
|
||||
/* preprocessed assembler */
|
||||
ret = tcc_assemble(s1, 0);
|
||||
#endif
|
||||
trace ("tcc_add_file_internal 34 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
} else {
|
||||
ElfW(Ehdr) ehdr;
|
||||
int fd, obj_type;
|
||||
|
@ -1062,43 +1215,60 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
|
||||
switch (obj_type) {
|
||||
case AFF_BINTYPE_REL:
|
||||
{
|
||||
ret = tcc_load_object_file(s1, fd, 0);
|
||||
trace ("tcc_add_file_internal 41 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
break;
|
||||
}
|
||||
#ifndef TCC_TARGET_PE
|
||||
case AFF_BINTYPE_DYN:
|
||||
{
|
||||
if (s1->output_type == TCC_OUTPUT_MEMORY) {
|
||||
ret = 0;
|
||||
#ifdef TCC_IS_NATIVE
|
||||
if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
|
||||
ret = -1;
|
||||
#endif
|
||||
trace ("tcc_add_file_internal 42 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
} else {
|
||||
ret = tcc_load_dll(s1, fd, filename,
|
||||
(flags & AFF_REFERENCED_DLL) != 0);
|
||||
trace ("tcc_add_file_internal 43 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
case AFF_BINTYPE_AR:
|
||||
{
|
||||
ret = tcc_load_archive(s1, fd);
|
||||
trace ("tcc_add_file_internal 51 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
break;
|
||||
}
|
||||
#ifdef TCC_TARGET_COFF
|
||||
case AFF_BINTYPE_C67:
|
||||
ret = tcc_load_coff(s1, fd);
|
||||
trace ("tcc_add_file_internal 52 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
#ifdef TCC_TARGET_PE
|
||||
ret = pe_load_file(s1, filename, fd);
|
||||
#else
|
||||
/* as GNU ld, consider it is an ld script if not recognized */
|
||||
ret = tcc_load_ldscript(s1);
|
||||
trace ("tcc_add_file_internal 61 ret="); eputs (itoa (ret));; eputs ("\n");
|
||||
#endif
|
||||
if (ret < 0)
|
||||
tcc_error_noabort("unrecognized file type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trace ("tcc_add_file_internal 90\n");
|
||||
tcc_close();
|
||||
trace_exit ("tcc_add_file_internal");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1112,7 +1282,11 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
|
|||
|
||||
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
|
||||
{
|
||||
trace ("tcc_add_library_path path="); eputs (pathname); eputs ("\n");
|
||||
tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
|
||||
for(int i = 0; i < s->nb_library_paths; i++) {
|
||||
trace ("tcc_add_library_path dir="); eputs (s->library_paths[i]); eputs ("\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1122,8 +1296,11 @@ static int tcc_add_library_internal(TCCState *s, const char *fmt,
|
|||
char buf[1024];
|
||||
int i;
|
||||
|
||||
trace ("tcc_add_library_internal file-name="); eputs (filename); eputs ("\n");
|
||||
trace ("tcc_add_library_internal nb_paths="); eputs (itoa (nb_paths)); eputs ("\n");
|
||||
for(i = 0; i < nb_paths; i++) {
|
||||
snprintf(buf, sizeof(buf), fmt, paths[i], filename);
|
||||
trace ("tcc_add_library_internal buf="); eputs (buf); eputs ("\n");
|
||||
if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
@ -1140,12 +1317,17 @@ ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
|
|||
|
||||
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
|
||||
{
|
||||
trace ("tcc_add_crt file name="); eputs (filename); eputs ("\n");
|
||||
if (-1 == tcc_add_library_internal(s, "%s/%s",
|
||||
filename, 0, s->crt_paths, s->nb_crt_paths))
|
||||
tcc_error_noabort("file '%s' not found", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __MESC__
|
||||
char *tcc_add_library_libs[3] = { "%s/lib%s+tcc-gcc.mlibc-o", "%s/lib%s+tcc-gcc.o", NULL };
|
||||
#endif
|
||||
|
||||
/* the library name is the same as the argument of the '-l' option */
|
||||
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
||||
{
|
||||
|
@ -1155,9 +1337,15 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
|||
#elif defined TCC_TARGET_MACHO
|
||||
const char *libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };
|
||||
const char **pp = s->static_link ? libs + 1 : libs;
|
||||
#elif BOOTSTRAP
|
||||
const char *libs[3] = { "%s/lib%s+tcc-gcc.mlibc-o", "%s/lib%s+tcc-gcc.o", NULL };
|
||||
const char **pp = libs;
|
||||
#else
|
||||
const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
|
||||
const char **pp = s->static_link ? libs + 1 : libs;
|
||||
#endif
|
||||
#if __MESC__
|
||||
pp = tcc_add_library_libs;
|
||||
#endif
|
||||
while (*pp) {
|
||||
if (0 == tcc_add_library_internal(s, *pp,
|
||||
|
@ -1170,6 +1358,7 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
|
|||
|
||||
PUB_FUNC int tcc_add_library_err(TCCState *s, const char *libname)
|
||||
{
|
||||
trace ("tcc_add_library_err libname="); eputs (libname); eputs ("\n");
|
||||
int ret = tcc_add_library(s, libname);
|
||||
if (ret < 0)
|
||||
tcc_error_noabort("library '%s' not found", libname);
|
||||
|
@ -1191,6 +1380,7 @@ LIBTCCAPI int tcc_add_symbol(TCCState *s, const char *name, const void *val)
|
|||
So it is handled here as if it were in a DLL. */
|
||||
pe_putimport(s, 0, name, (uintptr_t)val);
|
||||
#else
|
||||
trace ("tcc_add_symbol name="); eputs (name); eputs ("\n");
|
||||
set_elf_sym(symtab_section, (uintptr_t)val, 0,
|
||||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||
SHN_ABS, name);
|
||||
|
@ -1255,10 +1445,13 @@ ST_FUNC int set_flag(TCCState *s, const FlagDef *flags, const char *name)
|
|||
|
||||
static int strstart(const char *val, const char **str)
|
||||
{
|
||||
//eputs ("strstart val:"); //eputs (val); //eputs ("\n");
|
||||
//eputs ("strstart *str:"); //eputs (*str); //eputs ("\n");
|
||||
const char *p, *q;
|
||||
p = *str;
|
||||
q = val;
|
||||
while (*q) {
|
||||
//eputs ("*q:"); //eputc (*q); //eputs ("\n");
|
||||
if (*p != *q)
|
||||
return 0;
|
||||
p++;
|
||||
|
@ -1445,8 +1638,13 @@ static int tcc_set_linker(TCCState *s, const char *option)
|
|||
|
||||
typedef struct TCCOption {
|
||||
const char *name;
|
||||
#if !BOOTSTRAP
|
||||
uint16_t index;
|
||||
uint16_t flags;
|
||||
#else
|
||||
int index;
|
||||
int flags;
|
||||
#endif
|
||||
} TCCOption;
|
||||
|
||||
enum {
|
||||
|
@ -1612,11 +1810,17 @@ static void parse_option_D(TCCState *s1, const char *optarg)
|
|||
|
||||
static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
|
||||
{
|
||||
struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
|
||||
struct filespec *f = tcc_malloc(sizeof (struct filespec) + strlen(filename));
|
||||
trace ("arg_parser_add file name="); eputs (filename); eputs ("\n");
|
||||
f->type = filetype;
|
||||
f->alacarte = s->alacarte_link;
|
||||
strcpy(f->name, filename);
|
||||
trace ("arg_parser_add file f->name="); //eputs (f->name); //eputs ("\n");
|
||||
trace ("arg_parser_add nb_files="); //eputs (itoa (s->nb_files)); //eputs ("\n");
|
||||
dynarray_add(&s->files, &s->nb_files, f);
|
||||
//struct filespec *= s->files[s->nb_files - 1];
|
||||
struct filespec * fs = s->files[0];
|
||||
//eputs ("arg_parser_add file fs->name="); //eputs (fs->name); //eputs ("\n");
|
||||
}
|
||||
|
||||
static int args_parser_make_argv(const char *r, int *argc, char ***argv)
|
||||
|
@ -1661,6 +1865,7 @@ static void args_parser_listfile(TCCState *s,
|
|||
int argc = 0;
|
||||
char **argv = NULL;
|
||||
|
||||
trace ("arg_parser_listfile filename="); eputs (filename); eputs ("\n");
|
||||
fd = open(filename, O_RDONLY | O_BINARY);
|
||||
if (fd < 0)
|
||||
tcc_error("listfile '%s' not found", filename);
|
||||
|
@ -1682,6 +1887,8 @@ static void args_parser_listfile(TCCState *s,
|
|||
|
||||
PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
||||
{
|
||||
trace ("tcc_parse_args\n");
|
||||
|
||||
const TCCOption *popt;
|
||||
const char *optarg, *r;
|
||||
const char *run = NULL;
|
||||
|
@ -1696,7 +1903,11 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)
|
|||
cstr_new(&linker_arg);
|
||||
|
||||
while (optind < argc) {
|
||||
trace ("tcc_parse_args 02 arg:"); eputs (itoa (optind)); eputs ("\n");
|
||||
|
||||
r = argv[optind];
|
||||
trace ("tcc_parse_args 03 r:"); eputs (r); eputs ("\n");
|
||||
|
||||
if (r[0] == '@' && r[1] != '\0') {
|
||||
args_parser_listfile(s, r + 1, optind, &argc, &argv);
|
||||
continue;
|
||||
|
@ -1719,10 +1930,17 @@ reparse:
|
|||
continue;
|
||||
}
|
||||
|
||||
trace ("tcc_parse_args 20\n");
|
||||
|
||||
trace ("tcc_parse_args 20 opt0="); eputs (tcc_options[0].name); eputs ("\n");
|
||||
trace ("tcc_parse_args 20 opt1="); eputs (tcc_options[1].name); eputs ("\n");
|
||||
/* find option in table */
|
||||
for(popt = tcc_options; ; ++popt) {
|
||||
trace ("tcc_parse_args 21\n");
|
||||
trace ("tcc_parse_args 22 popt:"); eputs (popt->name); eputs ("\n");
|
||||
const char *p1 = popt->name;
|
||||
const char *r1 = r + 1;
|
||||
trace ("tcc_parse_args 23 r1:"); eputs (r1); eputs ("\n");
|
||||
if (p1 == NULL)
|
||||
tcc_error("invalid option -- '%s'", r);
|
||||
if (!strstart(p1, &r1))
|
||||
|
@ -1740,6 +1958,8 @@ reparse:
|
|||
break;
|
||||
}
|
||||
|
||||
trace ("pars_arg 2\n");
|
||||
|
||||
switch(popt->index) {
|
||||
case TCC_OPTION_HELP:
|
||||
return OPT_HELP;
|
||||
|
@ -1989,8 +2209,7 @@ PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time)
|
|||
total_time = 1;
|
||||
if (total_bytes < 1)
|
||||
total_bytes = 1;
|
||||
fprintf(stderr, "* %d idents, %d lines, %d bytes\n"
|
||||
"* %0.3f s, %u lines/s, %0.1f MB/s\n",
|
||||
fprintf(stderr, "* %d idents, %d lines, %d bytes\n* %0.3f s, %u lines/s, %0.1f MB/s\n",
|
||||
tok_ident - TOK_IDENT, total_lines, total_bytes,
|
||||
(double)total_time/1000,
|
||||
(unsigned)total_lines*1000/total_time,
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
rm -f 1.a 2.a
|
||||
|
||||
MES_PREFIX=${MES_PREFIX-../mes}
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
|
||||
# trivial bin
|
||||
###./tcc ../mes/scaffold/main.c
|
||||
c=${1-$MES_PREFIX/scaffold/main}
|
||||
b=scaffold/${c##*/}
|
||||
|
||||
rm -f "$b".mes-gcc-out
|
||||
rm -f "$b".mes-out
|
||||
|
||||
./i686-unknown-linux-gnu-tcc\
|
||||
-static -g -o "$b".mes-gcc-out -I $MES_PREFIX/include -L $TINYCC_SEED "$c".c 2> "$b".mes-gcc-stderr
|
||||
set +e
|
||||
${MES_TCC-./mes-tcc}\
|
||||
-static -g -o "$b".mes-out -I $MES_PREFIX/include -L $TINYCC_SEED "$c".c 2> "$b".mes-stderr
|
||||
objdump -d "$b".mes-gcc-out > "$b".mes-gcc-d
|
||||
objdump -d "$b".mes-out > "$b".mes-d
|
||||
#readelf -a a.i686-unknown-linux-gnu-out > 1.r
|
||||
#readelf -a a.mes-out > 2.r
|
||||
#diff -y 1.a 2.a
|
||||
echo diff -y "$b".mes-gcc-stderr "$b".mes-stderr
|
||||
echo diff -y "$b".mes-gcc-d "$b".mes-d
|
||||
"$b".mes-out
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#! /bin/sh
|
||||
set -ex
|
||||
|
||||
export PREFIX=usr
|
||||
export HEX2=../mescc-tools/bin/hex2
|
||||
export M1=../mescc-tools/bin/M1
|
||||
export BLOOD_ELF=../mescc-tools/bin/blood-elf
|
||||
export MESCC=../mes/guile/mescc.scm
|
||||
export MES_PREFIX=../mes
|
||||
export TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
|
||||
./test.sh ${1-t}
|
37
tcc.c
37
tcc.c
|
@ -185,7 +185,7 @@ static void print_search_dirs(TCCState *s)
|
|||
print_dirs("libraries", s->library_paths, s->nb_library_paths);
|
||||
#ifndef TCC_TARGET_PE
|
||||
print_dirs("crt", s->crt_paths, s->nb_crt_paths);
|
||||
printf("libtcc1:\n %s/"TCC_LIBTCC1"\n", s->tcc_lib_path);
|
||||
printf("libtcc1:\n %s/libtcc1.a\n", s->tcc_lib_path);
|
||||
printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
|
||||
#endif
|
||||
}
|
||||
|
@ -251,9 +251,25 @@ int main(int argc, char **argv)
|
|||
unsigned start_time = 0;
|
||||
const char *first_file;
|
||||
|
||||
#if BOOTSTRAP //MESC bug
|
||||
vstack = &__vstack[1];
|
||||
#endif
|
||||
|
||||
trace_enter ("main");
|
||||
redo:
|
||||
trace ("main 01\n");
|
||||
s = tcc_new();
|
||||
trace ("main 02\n");
|
||||
opt = tcc_parse_args(s, &argc, &argv, 1);
|
||||
trace ("main 03\n");
|
||||
|
||||
|
||||
if (s->nb_files) {
|
||||
struct filespec *f = s->files[0];
|
||||
trace ("main 05 file[0]="); eputs (f->name); eputs ("\n");
|
||||
}
|
||||
|
||||
trace ("main 06\n");
|
||||
|
||||
if (n == 0) {
|
||||
if (opt == OPT_HELP)
|
||||
|
@ -305,19 +321,28 @@ redo:
|
|||
start_time = getclock_ms();
|
||||
}
|
||||
|
||||
trace ("main 20\n");
|
||||
set_environment(s);
|
||||
trace ("main 21\n");
|
||||
|
||||
if (s->output_type == 0)
|
||||
s->output_type = TCC_OUTPUT_EXE;
|
||||
tcc_set_output_type(s, s->output_type);
|
||||
|
||||
trace ("main 23\n");
|
||||
|
||||
/* compile or add each files or library */
|
||||
for (first_file = NULL, ret = 0;;) {
|
||||
trace ("main 24 nb-files="); eputs (itoa (s->nb_files)); eputs ("\n");
|
||||
trace ("main 24 n="); eputs (itoa (n)); eputs ("\n");
|
||||
struct filespec *f = s->files[s->nb_files - n];
|
||||
trace ("for f->name="); eputs (f->name); eputs ("\n");
|
||||
s->filetype = f->type;
|
||||
s->alacarte_link = f->alacarte;
|
||||
if (f->type == AFF_TYPE_LIB) {
|
||||
if (tcc_add_library_err(s, f->name) < 0)
|
||||
ret = 1;
|
||||
trace ("main 32 ret="); eputs (itoa (ret)); eputs ("\n");
|
||||
} else {
|
||||
if (1 == s->verbose)
|
||||
printf("-> %s\n", f->name);
|
||||
|
@ -325,7 +350,9 @@ redo:
|
|||
first_file = f->name;
|
||||
if (tcc_add_file(s, f->name) < 0)
|
||||
ret = 1;
|
||||
trace ("main 33 ret="); eputs (itoa (ret)); eputs ("\n");
|
||||
}
|
||||
trace ("ret="); eputs (itoa (ret)); eputs ("\n");
|
||||
s->filetype = 0;
|
||||
s->alacarte_link = 1;
|
||||
if (ret || --n == 0
|
||||
|
@ -333,17 +360,24 @@ redo:
|
|||
break;
|
||||
}
|
||||
|
||||
trace ("main 40\n");
|
||||
|
||||
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
trace ("main 41\n");
|
||||
if (s->outfile)
|
||||
fclose(s->ppfp);
|
||||
} else if (0 == ret) {
|
||||
trace ("main 42 ret == 0\n");
|
||||
if (s->output_type == TCC_OUTPUT_MEMORY) {
|
||||
trace ("main RUN\n");
|
||||
#ifdef TCC_IS_NATIVE
|
||||
ret = tcc_run(s, argc, argv);
|
||||
#endif
|
||||
} else {
|
||||
trace ("main 44 gonna output_file\n");
|
||||
if (!s->outfile)
|
||||
s->outfile = default_outputfile(s, first_file);
|
||||
trace ("main 45 output_file\n");
|
||||
if (tcc_output_file(s, s->outfile))
|
||||
ret = 1;
|
||||
else if (s->gen_deps)
|
||||
|
@ -356,5 +390,6 @@ redo:
|
|||
tcc_delete(s);
|
||||
if (ret == 0 && n)
|
||||
goto redo; /* compile more files with -c */
|
||||
trace_exit ("main");
|
||||
return ret;
|
||||
}
|
||||
|
|
110
tcc.h
110
tcc.h
|
@ -24,6 +24,21 @@
|
|||
#define _GNU_SOURCE
|
||||
#include "config.h"
|
||||
|
||||
#if !BOOTSTRAP
|
||||
#define eputs(s)
|
||||
#define eputc(c)
|
||||
#define trace_enter(s)
|
||||
#define trace_exit(s)
|
||||
#define trace(s)
|
||||
#else /* BOOTSTRAP */
|
||||
#include <libmes.h>
|
||||
int trace_index = 0;
|
||||
char *trace_buffer = " ";
|
||||
#define trace_enter(s) {trace_index++;eputs (trace_buffer+40-trace_index);eputs (s);eputs (" enter{\n");}
|
||||
#define trace_exit(s) {eputs (trace_buffer+40-trace_index);eputs (s);eputs (" exit}\n");trace_index--;}
|
||||
#define trace(s) {eputs (trace_buffer+40-trace_index);eputs (s);}
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -280,6 +295,8 @@
|
|||
# define PUB_FUNC
|
||||
#endif
|
||||
|
||||
#if !__MESC__
|
||||
|
||||
#ifdef ONE_SOURCE
|
||||
#define ST_INLN static inline
|
||||
#define ST_FUNC static
|
||||
|
@ -290,6 +307,16 @@
|
|||
#define ST_DATA extern
|
||||
#endif
|
||||
|
||||
#else // __MESC__
|
||||
|
||||
#define inline
|
||||
#define static
|
||||
#define ST_INLN
|
||||
#define ST_FUNC
|
||||
#define ST_DATA
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TCC_PROFILE /* profile all functions */
|
||||
# define static
|
||||
#endif
|
||||
|
@ -385,16 +412,25 @@ typedef struct CType {
|
|||
struct Sym *ref;
|
||||
} CType;
|
||||
|
||||
|
||||
struct CValue_str {
|
||||
int size;
|
||||
const void *data;
|
||||
};
|
||||
|
||||
/* constant value */
|
||||
typedef union CValue {
|
||||
#if HAVE_FLOAT
|
||||
long double ld;
|
||||
double d;
|
||||
float f;
|
||||
#else
|
||||
int ld;
|
||||
int d;
|
||||
int f;
|
||||
#endif
|
||||
uint64_t i;
|
||||
struct {
|
||||
int size;
|
||||
const void *data;
|
||||
} str;
|
||||
struct CValue_str str;
|
||||
int tab[LDOUBLE_SIZE/4];
|
||||
} CValue;
|
||||
|
||||
|
@ -410,6 +446,7 @@ typedef struct SValue {
|
|||
} SValue;
|
||||
|
||||
struct Attribute {
|
||||
#if HAVE_BITFIELD
|
||||
unsigned
|
||||
func_call : 3, /* calling convention (0..5), see below */
|
||||
aligned : 5, /* alignment as log2+1 (0 == unspecified) */
|
||||
|
@ -423,6 +460,22 @@ struct Attribute {
|
|||
visibility : 2,
|
||||
unsigned_enum : 1,
|
||||
fill : 7; // 7 bits left to fit well in union below
|
||||
#else // !HAVE_BITFIELD
|
||||
struct {
|
||||
unsigned func_call;
|
||||
unsigned aligned;
|
||||
unsigned packed;
|
||||
unsigned func_export;
|
||||
unsigned func_import;
|
||||
unsigned func_args;
|
||||
unsigned func_body;
|
||||
unsigned mode;
|
||||
unsigned weak;
|
||||
unsigned visibility;
|
||||
unsigned unsigned_enum;
|
||||
unsigned fill;
|
||||
};
|
||||
#endif // !HAVE_BITFIELD
|
||||
};
|
||||
|
||||
/* GNUC attribute definition */
|
||||
|
@ -621,6 +674,13 @@ struct sym_attr {
|
|||
#endif
|
||||
};
|
||||
|
||||
enum TCCState_pflag {
|
||||
LINE_MACRO_OUTPUT_FORMAT_GCC,
|
||||
LINE_MACRO_OUTPUT_FORMAT_NONE,
|
||||
LINE_MACRO_OUTPUT_FORMAT_STD,
|
||||
LINE_MACRO_OUTPUT_FORMAT_P10 = 11
|
||||
};
|
||||
|
||||
struct TCCState {
|
||||
|
||||
int verbose; /* if true, display some information during compilation */
|
||||
|
@ -709,17 +769,16 @@ struct TCCState {
|
|||
void *error_opaque;
|
||||
void (*error_func)(void *opaque, const char *msg);
|
||||
int error_set_jmp_enabled;
|
||||
#if __MESC__
|
||||
__jmp_buf error_jmp_buf[1];
|
||||
#else
|
||||
jmp_buf error_jmp_buf;
|
||||
#endif
|
||||
int nb_errors;
|
||||
|
||||
/* output file for preprocessing (-E) */
|
||||
FILE *ppfp;
|
||||
enum {
|
||||
LINE_MACRO_OUTPUT_FORMAT_GCC,
|
||||
LINE_MACRO_OUTPUT_FORMAT_NONE,
|
||||
LINE_MACRO_OUTPUT_FORMAT_STD,
|
||||
LINE_MACRO_OUTPUT_FORMAT_P10 = 11
|
||||
} Pflag; /* -P switch */
|
||||
enum TCCState_pflag Pflag;
|
||||
char dflag; /* -dX value */
|
||||
|
||||
/* for -MD/-MF: collected dependencies for this compilation */
|
||||
|
@ -954,7 +1013,11 @@ struct filespec {
|
|||
#define TOK_A_SAR 0x82
|
||||
|
||||
#ifndef offsetof
|
||||
#if !BOOTSTRAP
|
||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
||||
#else
|
||||
#define offsetof(type, field) (&((type *)0)->field)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef countof
|
||||
|
@ -1097,11 +1160,14 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file
|
|||
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
|
||||
#endif
|
||||
|
||||
#if !BOOTSTRAP
|
||||
#define free(p) use_tcc_free(p)
|
||||
#define malloc(s) use_tcc_malloc(s)
|
||||
#define realloc(p, s) use_tcc_realloc(p, s)
|
||||
#undef strdup
|
||||
#define strdup(s) use_tcc_strdup(s)
|
||||
#endif
|
||||
|
||||
PUB_FUNC void tcc_memcheck(void);
|
||||
PUB_FUNC void tcc_error_noabort(const char *fmt, ...);
|
||||
PUB_FUNC NORETURN void tcc_error(const char *fmt, ...);
|
||||
|
@ -1267,8 +1333,18 @@ ST_DATA Sym *local_label_stack;
|
|||
ST_DATA Sym *global_label_stack;
|
||||
ST_DATA Sym *define_stack;
|
||||
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
|
||||
ST_DATA SValue __vstack[1+/*to make bcheck happy*/ VSTACK_SIZE], *vtop, *pvtop;
|
||||
#define vstack (__vstack + 1)
|
||||
ST_DATA SValue __vstack[1+/*to make bcheck happy*/VSTACK_SIZE];
|
||||
ST_DATA SValue *vtop;
|
||||
ST_DATA SValue *pvtop;
|
||||
#if BOOTSTRAP
|
||||
#if __MESC__
|
||||
SValue *vstack;
|
||||
#else
|
||||
extern SValue *vstack;
|
||||
#endif
|
||||
#else
|
||||
#define vstack (__vstack + 1)
|
||||
#endif
|
||||
ST_DATA int rsym, anon_sym, ind, loc;
|
||||
|
||||
ST_DATA int const_wanted; /* true if constant wanted */
|
||||
|
@ -1607,10 +1683,10 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
|
|||
#define RTLD_GLOBAL 0x100
|
||||
#define RTLD_DEFAULT NULL
|
||||
/* dummy function for profiling */
|
||||
ST_FUNC void *dlopen(const char *filename, int flag);
|
||||
ST_FUNC void dlclose(void *p);
|
||||
ST_FUNC const char *dlerror(void);
|
||||
ST_FUNC void *dlsym(void *handle, const char *symbol);
|
||||
void *dlopen(const char *filename, int flag);
|
||||
int dlclose(void *p);
|
||||
char const *dlerror(void);
|
||||
void *dlsym(void *handle, const char *symbol);
|
||||
#endif
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
ST_DATA int rt_num_callers;
|
||||
|
@ -1632,11 +1708,13 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
|
|||
#endif
|
||||
|
||||
/********************************************************/
|
||||
#if !__MESC__
|
||||
#undef ST_DATA
|
||||
#ifdef ONE_SOURCE
|
||||
#define ST_DATA static
|
||||
#else
|
||||
#define ST_DATA
|
||||
#endif
|
||||
#endif
|
||||
/********************************************************/
|
||||
#endif /* _TCC_H */
|
||||
|
|
43
tccasm.c
43
tccasm.c
|
@ -18,7 +18,10 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TCC_ASM
|
||||
|
||||
ST_FUNC int asm_get_local_label_name(TCCState *s1, unsigned int n)
|
||||
|
@ -217,8 +220,8 @@ static void asm_expr_prod(TCCState *s1, ExprValue *pe)
|
|||
case TOK_SHL:
|
||||
pe->v <<= e2.v;
|
||||
break;
|
||||
default:
|
||||
case TOK_SAR:
|
||||
default:
|
||||
pe->v >>= e2.v;
|
||||
break;
|
||||
}
|
||||
|
@ -246,8 +249,8 @@ static void asm_expr_logic(TCCState *s1, ExprValue *pe)
|
|||
case '|':
|
||||
pe->v |= e2.v;
|
||||
break;
|
||||
default:
|
||||
case '^':
|
||||
default:
|
||||
pe->v ^= e2.v;
|
||||
break;
|
||||
}
|
||||
|
@ -622,8 +625,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
g(repeat_buf[j]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_rept:
|
||||
{
|
||||
int repeat;
|
||||
|
@ -669,8 +672,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
v = 0;
|
||||
size = n - ind;
|
||||
goto zero_pad;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_set:
|
||||
next();
|
||||
tok1 = tok;
|
||||
|
@ -724,8 +727,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_text:
|
||||
case TOK_ASMDIR_data:
|
||||
case TOK_ASMDIR_bss:
|
||||
|
@ -743,8 +746,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
else
|
||||
sprintf(sname, "%s", get_tok_str(tok1, NULL));
|
||||
use_section(s1, sname);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_file:
|
||||
{
|
||||
char filename[512];
|
||||
|
@ -761,8 +764,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
tcc_warning("ignoring .file %s", filename);
|
||||
|
||||
next();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_ident:
|
||||
{
|
||||
char ident[256];
|
||||
|
@ -779,8 +782,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
tcc_warning("ignoring .ident %s", ident);
|
||||
|
||||
next();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_size:
|
||||
{
|
||||
Sym *sym;
|
||||
|
@ -800,8 +803,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
while (tok != TOK_LINEFEED && tok != ';' && tok != CH_EOF) {
|
||||
next();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_type:
|
||||
{
|
||||
Sym *sym;
|
||||
|
@ -827,8 +830,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
get_tok_str(sym->v, NULL), sym->type.t, newtype);
|
||||
|
||||
next();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_pushsection:
|
||||
case TOK_ASMDIR_section:
|
||||
{
|
||||
|
@ -869,8 +872,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
sets alignment to PTR_SIZE. The assembler behaves different. */
|
||||
if (old_nb_section != s1->nb_sections)
|
||||
cur_text_section->sh_addralign = 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_previous:
|
||||
{
|
||||
Section *sec;
|
||||
|
@ -880,8 +883,8 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
sec = cur_text_section;
|
||||
use_section1(s1, last_text_section);
|
||||
last_text_section = sec;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_popsection:
|
||||
next();
|
||||
pop_section(s1);
|
||||
|
@ -891,14 +894,14 @@ static void asm_parse_directive(TCCState *s1, int global)
|
|||
{
|
||||
next();
|
||||
s1->seg_size = 16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TOK_ASMDIR_code32:
|
||||
{
|
||||
next();
|
||||
s1->seg_size = 32;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
/* added for compatibility with GAS */
|
||||
|
@ -1152,9 +1155,12 @@ static void parse_asm_operands(ASMOperand *operands, int *nb_operands_ptr,
|
|||
next();
|
||||
skip(']');
|
||||
}
|
||||
parse_mult_str(&astr, "string constant");
|
||||
parse_mult_str(&astr, "parse_asm_operands string constant");
|
||||
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||
op->constraint = tcc_malloc(astr.size);
|
||||
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||
strcpy(op->constraint, astr.data);
|
||||
trace ("parse arm_operands tokc.str.data="); eputs (tokc.str.data); eputs ("\n");
|
||||
cstr_free(&astr);
|
||||
skip('(');
|
||||
gexpr();
|
||||
|
@ -1193,13 +1199,17 @@ ST_FUNC void asm_instr(void)
|
|||
int nb_outputs, nb_operands, i, must_subst, out_reg;
|
||||
uint8_t clobber_regs[NB_ASM_REGS];
|
||||
|
||||
trace_enter ("asm_instr");
|
||||
next();
|
||||
trace ("asm_instr 01\n");
|
||||
/* since we always generate the asm() instruction, we can ignore
|
||||
volatile */
|
||||
if (tok == TOK_VOLATILE1 || tok == TOK_VOLATILE2 || tok == TOK_VOLATILE3) {
|
||||
next();
|
||||
}
|
||||
trace ("asm_instr 02\n");
|
||||
parse_asm_str(&astr);
|
||||
trace ("asm_instr astr.data="); eputs (astr.data); eputs ("\n");
|
||||
nb_operands = 0;
|
||||
nb_outputs = 0;
|
||||
must_subst = 0;
|
||||
|
@ -1252,6 +1262,7 @@ ST_FUNC void asm_instr(void)
|
|||
#ifdef ASM_DEBUG
|
||||
printf("asm: \"%s\"\n", (char *)astr.data);
|
||||
#endif
|
||||
trace ("asm_instr asm:"); eputs (astr.data); eputs ("\n");
|
||||
if (must_subst) {
|
||||
subst_asm_operands(operands, nb_operands, &astr1, &astr);
|
||||
cstr_free(&astr);
|
||||
|
@ -1261,6 +1272,7 @@ ST_FUNC void asm_instr(void)
|
|||
#ifdef ASM_DEBUG
|
||||
printf("subst_asm: \"%s\"\n", (char *)astr1.data);
|
||||
#endif
|
||||
trace ("asm_instr subst:"); eputs (astr1.data); eputs ("\n");
|
||||
|
||||
/* generate loads */
|
||||
asm_gen_code(operands, nb_operands, nb_outputs, 0,
|
||||
|
@ -1284,6 +1296,7 @@ ST_FUNC void asm_instr(void)
|
|||
vpop();
|
||||
}
|
||||
cstr_free(&astr1);
|
||||
trace_exit ("asm_instr");
|
||||
}
|
||||
|
||||
ST_FUNC void asm_global_instr(void)
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define MAXNSCNS 255 /* MAXIMUM NUMBER OF SECTIONS */
|
||||
#define MAX_STR_TABLE 1000000
|
||||
|
|
2
tccpe.c
2
tccpe.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
#define PE_MERGE_DATA
|
||||
/* #define PE_PRINT_SECTIONS */
|
||||
|
|
21
tccrun.c
21
tccrun.c
|
@ -18,7 +18,9 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
/* only native compiler supports -run */
|
||||
#ifdef TCC_IS_NATIVE
|
||||
|
@ -139,7 +141,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||
|
||||
bound_init();
|
||||
/* mark argv area as valid */
|
||||
bound_new_region(argv, argc*sizeof(argv[0]));
|
||||
bound_new_region(argv, argc*sizeof(char *));
|
||||
for (i=0; i<argc; ++i)
|
||||
bound_new_region(argv[i], strlen(argv[i]) + 1);
|
||||
|
||||
|
@ -312,7 +314,8 @@ ST_FUNC void tcc_set_num_callers(int n)
|
|||
the stabs debug information */
|
||||
static addr_t rt_printline(addr_t wanted_pc, const char *msg)
|
||||
{
|
||||
char func_name[128], last_func_name[128];
|
||||
char func_name[128];
|
||||
char last_func_name[128];
|
||||
addr_t func_addr, last_pc, pc;
|
||||
const char *incl_files[INCLUDE_STACK_SIZE];
|
||||
int incl_index, len, last_line_num, i;
|
||||
|
@ -520,6 +523,7 @@ static void sig_error(int signum, siginfo_t *siginf, void *puc)
|
|||
/* Generate a stack backtrace when a CPU exception occurs. */
|
||||
static void set_exception_handler(void)
|
||||
{
|
||||
#if !__MESC__
|
||||
struct sigaction sigact;
|
||||
/* install TCC signal handlers to print debug info on fatal
|
||||
runtime errors */
|
||||
|
@ -531,6 +535,7 @@ static void set_exception_handler(void)
|
|||
sigaction(SIGSEGV, &sigact, NULL);
|
||||
sigaction(SIGBUS, &sigact, NULL);
|
||||
sigaction(SIGABRT, &sigact, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -768,17 +773,21 @@ static int rt_get_caller_pc(addr_t *paddr, CONTEXT *uc, int level)
|
|||
/* ------------------------------------------------------------- */
|
||||
#ifdef CONFIG_TCC_STATIC
|
||||
|
||||
#if 1 //!BOOTSTRAP
|
||||
/* dummy function for profiling */
|
||||
ST_FUNC void *dlopen(const char *filename, int flag)
|
||||
void *dlopen(const char *filename, int flag)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ST_FUNC void dlclose(void *p)
|
||||
int
|
||||
dlclose(void *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
ST_FUNC const char *dlerror(void)
|
||||
char const *dlerror(void)
|
||||
{
|
||||
return "error";
|
||||
}
|
||||
|
@ -802,7 +811,7 @@ static TCCSyms tcc_syms[] = {
|
|||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
ST_FUNC void *dlsym(void *handle, const char *symbol)
|
||||
void *dlsym(void *handle, const char *symbol)
|
||||
{
|
||||
TCCSyms *p;
|
||||
p = tcc_syms;
|
||||
|
|
30
tcctools.c
30
tcctools.c
|
@ -28,7 +28,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _TCC_H
|
||||
#include "tcc.h"
|
||||
#endif
|
||||
|
||||
//#define ARMAG "!<arch>\n"
|
||||
#define ARFMAG "`\n"
|
||||
|
@ -88,20 +90,27 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
|
|||
ARFMAG
|
||||
};
|
||||
|
||||
FILE *fi, *fh = NULL, *fo = NULL;
|
||||
int ret = 2;
|
||||
FILE *fi;
|
||||
FILE *fh = NULL;
|
||||
FILE *fo = NULL;
|
||||
ElfW(Ehdr) *ehdr;
|
||||
ElfW(Shdr) *shdr;
|
||||
ElfW(Sym) *sym;
|
||||
int i, fsize, i_lib, i_obj;
|
||||
char *buf, *shstr, *symtab = NULL, *strtab = NULL;
|
||||
char *buf;
|
||||
char *shstr;
|
||||
char *symtab = NULL;
|
||||
char *strtab = NULL;
|
||||
int symtabsize = 0;//, strtabsize = 0;
|
||||
char *anames = NULL;
|
||||
int *afpos = NULL;
|
||||
int istrlen, strpos = 0, fpos = 0, funccnt = 0, funcmax, hofs;
|
||||
char tfile[260], stmp[20];
|
||||
char *file, *name;
|
||||
int ret = 2;
|
||||
const char *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored.
|
||||
char tfile[260];
|
||||
char stmp[20];
|
||||
char *file;
|
||||
char *name;
|
||||
char const *ops_conflict = "habdioptxN"; // unsupported but destructive if ignored.
|
||||
int verbose = 0;
|
||||
|
||||
i_lib = 0; i_obj = 0; // will hold the index of the lib and first obj
|
||||
|
@ -142,7 +151,7 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
|
|||
}
|
||||
|
||||
funcmax = 250;
|
||||
afpos = tcc_realloc(NULL, funcmax * sizeof *afpos); // 250 func
|
||||
afpos = tcc_realloc(NULL, funcmax * sizeof (int)); // 250 func
|
||||
memcpy(&arhdro.ar_mode, "100666", 6);
|
||||
|
||||
// i_obj = first input object file
|
||||
|
@ -215,7 +224,7 @@ ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
|
|||
strpos += istrlen;
|
||||
if (++funccnt >= funcmax) {
|
||||
funcmax += 250;
|
||||
afpos = tcc_realloc(afpos, funcmax * sizeof *afpos); // 250 func more
|
||||
afpos = tcc_realloc(afpos, funcmax * sizeof (int)); // 250 func more
|
||||
}
|
||||
afpos[funccnt] = fpos;
|
||||
}
|
||||
|
@ -487,13 +496,16 @@ ST_FUNC void tcc_tool_cross(TCCState *s, char **argv, int target)
|
|||
int prefix = tcc_basename(a0) - a0;
|
||||
|
||||
snprintf(program, sizeof program,
|
||||
"%.*s%s"
|
||||
#if !defined (TCC_TARGET_PE) && !defined (_WIN32)
|
||||
"%.*s%s-tcc"
|
||||
#else
|
||||
#ifdef TCC_TARGET_PE
|
||||
"-win32"
|
||||
#endif
|
||||
"-tcc"
|
||||
#ifdef _WIN32
|
||||
".exe"
|
||||
#endif
|
||||
#endif
|
||||
, prefix, a0, target == 64 ? "x86_64" : "i386");
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
TCC=${TCC-./mes-tcc}
|
||||
MESCC=${MESCC-mescc}
|
||||
MES_PREFIX=${MES_PREFIX-../mes}
|
||||
MES_PREFIX=${MES_PREFIX-${MESCC%/*}}
|
||||
TINYCC_SEED=${TINYCC_SEED-../tinycc-seed}
|
||||
OBJDUMP=${OBJDUMP-objdump}
|
||||
DIFF=${DIFF-diff}
|
||||
|
||||
unset C_INCLUDE_PATH LIBRARY_PATH
|
||||
|
||||
t=${1-$MES_PREFIX/scaffold/tests/t}
|
||||
mkdir -p scaffold
|
||||
b=scaffold/${t##*/}
|
||||
rm -f "$b".i686-unknown-linux-gnu-out
|
||||
rm -f "$b".mes-out
|
||||
|
||||
r=0
|
||||
if [ -x ./i686-unknown-linux-gnu-tcc ]; then
|
||||
./i686-unknown-linux-gnu-tcc\
|
||||
-c\
|
||||
-o "$b".mes-gcc-o\
|
||||
-nostdlib\
|
||||
-g\
|
||||
-m32\
|
||||
-D __TINYC__=1\
|
||||
-I $MES_PREFIX/include\
|
||||
-I $MES_PREFIX/scaffold/tests\
|
||||
-I $MES_PREFIX/scaffold/tinycc\
|
||||
"$t".c &> 1
|
||||
#$OBJDUMP -d "$t".mes-gcc-o > 1.s
|
||||
./i686-unknown-linux-gnu-tcc\
|
||||
-static\
|
||||
-o "$b".mes-gcc-out\
|
||||
-L .\
|
||||
-L $TINYCC_SEED\
|
||||
"$b".mes-gcc-o &> 1.link
|
||||
set +e
|
||||
"$b".mes-gcc-out arg1 arg2 arg3 arg4 arg5 > "$b".mes-gcc-stdout
|
||||
m=$?
|
||||
set -e
|
||||
[ -f "$t".exit ] && r=$(cat "$t".exit)
|
||||
[ $m = $r ]
|
||||
if [ -f "$t".expect ]; then
|
||||
$DIFF -ub "$t".expect "$b".mes-gcc-stdout;
|
||||
fi
|
||||
fi
|
||||
|
||||
$TCC\
|
||||
-c\
|
||||
-g\
|
||||
-m32\
|
||||
-o "$b".mes-o\
|
||||
-D __TINYC__=1\
|
||||
-I $MES_PREFIX/include\
|
||||
-I $MES_PREFIX/scaffold/tests\
|
||||
-I $MES_PREFIX/scaffold/tinycc\
|
||||
"$t".c &> 2
|
||||
$OBJDUMP -d "$b".mes-o > 2.s || true
|
||||
$TCC\
|
||||
-static\
|
||||
-o "$b".mes-out\
|
||||
-g\
|
||||
-m32\
|
||||
-D __TINYC__=1\
|
||||
-I $MES_PREFIX/include\
|
||||
-I $MES_PREFIX/scaffold/tests\
|
||||
-I $MES_PREFIX/scaffold/tinycc\
|
||||
-L $TINYCC_SEED\
|
||||
"$t".c &> 2.link
|
||||
set +e
|
||||
"$b".mes-out arg1 arg2 arg3 arg4 arg5 > "$b".mes-stdout
|
||||
m=$?
|
||||
#$OBJDUMP -d "$t".mes-out > 2.x
|
||||
|
||||
set -e
|
||||
[ $m = $r ]
|
||||
[ -f "$t".exit ] && r=$(cat "$t".exit)
|
||||
if [ -f "$t".expect ]; then
|
||||
$DIFF -ub "$t".expect "$b".mes-stdout;
|
||||
fi
|
||||
|
||||
#diff -y 1.s 2.s
|
||||
#diff -y 1 2
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/perl -w
|
||||
#! /usr/bin/env perl
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
|
||||
|
|
Loading…
Reference in New Issue