mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
tcc.c:main() free all & etc...
tcc.c: - be nice to leak checkers tcctools.c: - remove unused TCCState params tccrun.c: - call bound_exit() after signals to let it free mem tccelf.c: - use section_add() instead of section_ptr_add() when more appropriate tccpp.c: - use size_t to align tal_header naturally - 'POINTER_SIZE' and 'PTR_SIZE' in the same source is confusing - "char file_name[TAL_DEBUG_FILE_LEN + 1];" looks silly. - next_nomacro(): skip UTF8 BOM at BOF tccgen.c: - get rid of STMT_EXPR clause on top of block - warn with useless type like 'int;' - move skip()'s in block() for better error line-info - BIT_SIZE bits are meaningful only with VT_BITFIELD (not with enums for example) workflow/test-win32: - build with MSVC using build-tcc.bat also alloca.S: - fix 'off by one' problem on win32 (must touch current page too because the 'push %edx' at the end could touch the next page) - must not align greater than 4 when used for struct args (i386-gen.c:gfunc_call()) libtcc.c: - accept -g1dwarf (dwarf output, only line info)
This commit is contained in:
parent
8845b6cd45
commit
deb7a3fc73
30
.github/workflows/build.yml
vendored
30
.github/workflows/build.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
|||||||
|
|
||||||
test-x86_64-win32:
|
test-x86_64-win32:
|
||||||
runs-on: windows-2025
|
runs-on: windows-2025
|
||||||
timeout-minutes: 4
|
timeout-minutes: 6
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: make & test tcc (x86_64-win32)
|
- name: make & test tcc (x86_64-win32)
|
||||||
@ -44,10 +44,22 @@ jobs:
|
|||||||
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
|
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-x86_64-gcc"
|
||||||
echo ::endgroup::
|
echo ::endgroup::
|
||||||
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
|
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
|
||||||
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: amd64
|
||||||
|
- name: build with MSVC (x86_64-win32)
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
echo ::group:: run build-tcc.bat
|
||||||
|
cd win32
|
||||||
|
call build-tcc.bat -t 64 -c cl
|
||||||
|
echo ::endgroup::
|
||||||
|
.\tcc -I.. libtcc.dll -v ../tests/libtcc_test.c -o libtest.exe && .\libtest.exe
|
||||||
|
.\tcc -I.. libtcc.dll -run ../tests/libtcc_test.c
|
||||||
|
|
||||||
test-i386-win32:
|
test-i386-win32:
|
||||||
runs-on: windows-2025
|
runs-on: windows-2025
|
||||||
timeout-minutes: 4
|
timeout-minutes: 6
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: make & test tcc (i386-win32)
|
- name: make & test tcc (i386-win32)
|
||||||
@ -59,7 +71,19 @@ jobs:
|
|||||||
set CHERE_INVOKING=yes
|
set CHERE_INVOKING=yes
|
||||||
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"
|
C:\msys64\usr\bin\bash -l -c "pacman -S --noconfirm mingw-w64-i686-gcc"
|
||||||
echo ::endgroup::
|
echo ::endgroup::
|
||||||
C:\msys64\usr\bin\bash -l -c "./configure && make all && make test -k"
|
C:\msys64\usr\bin\bash -l -c "./configure && make && make test -k"
|
||||||
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x86
|
||||||
|
- name: build with MSVC (i386-win32)
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
echo ::group:: run build-tcc.bat
|
||||||
|
cd win32
|
||||||
|
call build-tcc.bat -t 32 -c cl
|
||||||
|
echo ::endgroup::
|
||||||
|
.\tcc -I.. libtcc.dll -v ../tests/libtcc_test.c -o libtest.exe && .\libtest.exe
|
||||||
|
.\tcc -I.. libtcc.dll -run ../tests/libtcc_test.c
|
||||||
|
|
||||||
test-armv7-linux:
|
test-armv7-linux:
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|||||||
@ -417,6 +417,7 @@ ST_FUNC void gfunc_call(int nb_args)
|
|||||||
/* allocate the necessary size on stack */
|
/* allocate the necessary size on stack */
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (size >= 4096) {
|
if (size >= 4096) {
|
||||||
|
save_reg(TREG_EDX);
|
||||||
r = get_reg(RC_EAX);
|
r = get_reg(RC_EAX);
|
||||||
oad(0x68, size); // push size
|
oad(0x68, size); // push size
|
||||||
/* cannot call normal 'alloca' with bound checking */
|
/* cannot call normal 'alloca' with bound checking */
|
||||||
|
|||||||
@ -17,13 +17,13 @@ _(__bound_alloca):
|
|||||||
mov %eax, %ecx
|
mov %eax, %ecx
|
||||||
test %eax,%eax
|
test %eax,%eax
|
||||||
jz p6
|
jz p6
|
||||||
add $15+1,%eax
|
add $3 + 1,%eax
|
||||||
and $-16,%eax
|
and $-4,%eax
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
p4:
|
p4:
|
||||||
cmp $4096,%eax
|
cmp $4096,%eax
|
||||||
jbe p5
|
jb p5
|
||||||
test %eax,-4096(%esp)
|
test %eax,-4096(%esp)
|
||||||
sub $4096,%esp
|
sub $4096,%esp
|
||||||
sub $4096,%eax
|
sub $4096,%eax
|
||||||
@ -33,7 +33,6 @@ p5:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
sub %eax,%esp
|
sub %eax,%esp
|
||||||
and $-16,%esp
|
|
||||||
mov %esp,%eax
|
mov %esp,%eax
|
||||||
|
|
||||||
push %edx
|
push %edx
|
||||||
@ -72,12 +71,11 @@ _(__bound_alloca_nr):
|
|||||||
#else
|
#else
|
||||||
pop %rdx
|
pop %rdx
|
||||||
mov %rdi,%rax
|
mov %rdi,%rax
|
||||||
|
and %eax,%eax
|
||||||
|
jz p3
|
||||||
mov %rax,%rsi # size, a second parm to the __bound_new_region
|
mov %rax,%rsi # size, a second parm to the __bound_new_region
|
||||||
|
|
||||||
add $15 + 1,%rax # add one extra to separate regions
|
add $15 + 1,%rax # add one extra to separate regions
|
||||||
and $-16,%rax
|
and $-16,%rax
|
||||||
jz p3
|
|
||||||
|
|
||||||
|
|
||||||
sub %rax,%rsp
|
sub %rax,%rsp
|
||||||
mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
|
mov %rsp,%rdi # pointer, a first parm to the __bound_new_region
|
||||||
|
|||||||
@ -15,14 +15,14 @@ _(alloca):
|
|||||||
_(__alloca):
|
_(__alloca):
|
||||||
pop %edx
|
pop %edx
|
||||||
pop %eax
|
pop %eax
|
||||||
add $15,%eax
|
add $3,%eax
|
||||||
and $-16,%eax
|
and $-4,%eax
|
||||||
jz p3
|
jz p3
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
p1:
|
p1:
|
||||||
cmp $4096,%eax
|
cmp $4096,%eax
|
||||||
jbe p2
|
jb p2
|
||||||
test %eax,-4096(%esp)
|
test %eax,-4096(%esp)
|
||||||
sub $4096,%esp
|
sub $4096,%esp
|
||||||
sub $4096,%eax
|
sub $4096,%eax
|
||||||
@ -30,7 +30,6 @@ p1:
|
|||||||
p2:
|
p2:
|
||||||
#endif
|
#endif
|
||||||
sub %eax,%esp
|
sub %eax,%esp
|
||||||
and $-16,%esp
|
|
||||||
mov %esp,%eax
|
mov %esp,%eax
|
||||||
p3:
|
p3:
|
||||||
push %edx
|
push %edx
|
||||||
@ -55,7 +54,7 @@ _(alloca):
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
p1:
|
p1:
|
||||||
cmp $4096,%rax
|
cmp $4096,%rax
|
||||||
jbe p2
|
jb p2
|
||||||
test %rax,-4096(%rsp)
|
test %rax,-4096(%rsp)
|
||||||
sub $4096,%rsp
|
sub $4096,%rsp
|
||||||
sub $4096,%rax
|
sub $4096,%rax
|
||||||
|
|||||||
45
libtcc.c
45
libtcc.c
@ -804,7 +804,6 @@ static int tcc_compile(TCCState *s1, int filetype, const char *str, int fd)
|
|||||||
s1->error_set_jmp_enabled = 1;
|
s1->error_set_jmp_enabled = 1;
|
||||||
|
|
||||||
if (setjmp(s1->error_jmp_buf) == 0) {
|
if (setjmp(s1->error_jmp_buf) == 0) {
|
||||||
s1->nb_errors = 0;
|
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
int len = strlen(str);
|
int len = strlen(str);
|
||||||
@ -1816,8 +1815,7 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
|
|||||||
const TCCOption *popt;
|
const TCCOption *popt;
|
||||||
const char *optarg, *r;
|
const char *optarg, *r;
|
||||||
const char *run = NULL;
|
const char *run = NULL;
|
||||||
int x;
|
int optind = 1, empty = 1, x;
|
||||||
int tool = 0, arg_start = 0, not_empty = 0, optind = 1;
|
|
||||||
char **argv = *pargv;
|
char **argv = *pargv;
|
||||||
int argc = *pargc;
|
int argc = *pargc;
|
||||||
|
|
||||||
@ -1836,21 +1834,16 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
optind++;
|
optind++;
|
||||||
if (tool) { /* ignore all except -v and @listfile */
|
|
||||||
s->verbose += !strcmp(r, "-v");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r[0] != '-' || r[1] == '\0') { /* file or '-' (stdin) */
|
if (r[0] != '-' || r[1] == '\0') { /* file or '-' (stdin) */
|
||||||
args_parser_add_file(s, r, s->filetype);
|
args_parser_add_file(s, r, s->filetype);
|
||||||
not_empty = 1;
|
empty = 0;
|
||||||
dorun:
|
dorun:
|
||||||
if (run) {
|
if (run) {
|
||||||
/* tcc -run <file> <args...> */
|
/* tcc -run <file> <args...> */
|
||||||
if (tcc_set_options(s, run))
|
if (tcc_set_options(s, run) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
arg_start = optind - 1; /* argv[0] will be <file> */
|
x = 0;
|
||||||
break;
|
goto extra_action;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1923,14 +1916,16 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
|
|||||||
case TCC_OPTION_g:
|
case TCC_OPTION_g:
|
||||||
s->do_debug = 2;
|
s->do_debug = 2;
|
||||||
s->dwarf = CONFIG_DWARF_VERSION;
|
s->dwarf = CONFIG_DWARF_VERSION;
|
||||||
|
g_redo:
|
||||||
if (strstart("dwarf", &optarg)) {
|
if (strstart("dwarf", &optarg)) {
|
||||||
s->dwarf = (*optarg) ? (0 - atoi(optarg)) : DEFAULT_DWARF_VERSION;
|
s->dwarf = (*optarg) ? (0 - atoi(optarg)) : DEFAULT_DWARF_VERSION;
|
||||||
} else if (0 == strcmp("stabs", optarg)) {
|
} else if (0 == strcmp("stabs", optarg)) {
|
||||||
s->dwarf = 0;
|
s->dwarf = 0;
|
||||||
} else if (isnum(*optarg)) {
|
} else if (isnum(*optarg)) {
|
||||||
x = *optarg - '0';
|
x = *optarg++ - '0';
|
||||||
/* -g0 = no info, -g1 = lines/functions only, -g2 = full info */
|
/* -g0 = no info, -g1 = lines/functions only, -g2 = full info */
|
||||||
s->do_debug = x > 2 ? 2 : x == 0 && s->do_backtrace ? 1 : x;
|
s->do_debug = x > 2 ? 2 : x == 0 && s->do_backtrace ? 1 : x;
|
||||||
|
goto g_redo;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
} else if (0 == strcmp(".pdb", optarg)) {
|
} else if (0 == strcmp(".pdb", optarg)) {
|
||||||
s->dwarf = 5, s->do_debug |= 16;
|
s->dwarf = 5, s->do_debug |= 16;
|
||||||
@ -2030,7 +2025,6 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_W:
|
case TCC_OPTION_W:
|
||||||
s->warn_none = 0;
|
|
||||||
if (optarg[0] && set_flag(s, options_W, optarg) < 0)
|
if (optarg[0] && set_flag(s, options_W, optarg) < 0)
|
||||||
goto unsupported_option;
|
goto unsupported_option;
|
||||||
break;
|
break;
|
||||||
@ -2141,29 +2135,24 @@ PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
|
|||||||
case TCC_OPTION_ar:
|
case TCC_OPTION_ar:
|
||||||
x = OPT_AR;
|
x = OPT_AR;
|
||||||
extra_action:
|
extra_action:
|
||||||
arg_start = optind - 1;
|
if (NULL == argv[0]) /* from tcc_set_options() */
|
||||||
if (not_empty)
|
return -1;
|
||||||
|
if (!empty && x)
|
||||||
return tcc_error_noabort("cannot parse %s here", r);
|
return tcc_error_noabort("cannot parse %s here", r);
|
||||||
tool = x;
|
--optind;
|
||||||
break;
|
*pargc = argc - optind;
|
||||||
|
*pargv = argv + optind;
|
||||||
|
return x;
|
||||||
default:
|
default:
|
||||||
unsupported_option:
|
unsupported_option:
|
||||||
tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
|
tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
not_empty = 1;
|
empty = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->link_optind < s->link_argc)
|
if (s->link_optind < s->link_argc)
|
||||||
return tcc_error_noabort("argument to '-Wl,%s' is missing", s->link_argv[s->link_optind]);
|
return tcc_error_noabort("argument to '-Wl,%s' is missing", s->link_argv[s->link_optind]);
|
||||||
if (NULL == argv[0]) /* from tcc_set_options() */
|
if (!empty)
|
||||||
return 0;
|
|
||||||
if (arg_start) {
|
|
||||||
*pargc = argc - arg_start;
|
|
||||||
*pargv = argv + arg_start;
|
|
||||||
return tool;
|
|
||||||
}
|
|
||||||
if (not_empty)
|
|
||||||
return 0;
|
return 0;
|
||||||
if (s->verbose == 2)
|
if (s->verbose == 2)
|
||||||
return OPT_PRINT_DIRS;
|
return OPT_PRINT_DIRS;
|
||||||
|
|||||||
41
tcc.c
41
tcc.c
@ -283,51 +283,51 @@ static unsigned getclock_ms(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc0, char **argv0)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
TCCState *s, *s1;
|
TCCState *s, *s1;
|
||||||
int ret, opt, n = 0, t = 0, done;
|
int ret, opt, n = 0, t = 0, done;
|
||||||
unsigned start_time = 0, end_time = 0;
|
unsigned start_time = 0, end_time = 0;
|
||||||
const char *first_file;
|
const char *first_file;
|
||||||
int argc; char **argv;
|
int argc0 = argc;
|
||||||
|
char **argv0 = argv;
|
||||||
FILE *ppfp = stdout;
|
FILE *ppfp = stdout;
|
||||||
|
|
||||||
redo:
|
redo:
|
||||||
argc = argc0, argv = argv0;
|
argc = argc0, argv = argv0;
|
||||||
s = s1 = tcc_new();
|
s = s1 = tcc_new();
|
||||||
opt = tcc_parse_args(s, &argc, &argv);
|
opt = tcc_parse_args(s, &argc, &argv);
|
||||||
if (opt < 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
|
ret = 0;
|
||||||
if (opt == OPT_HELP) {
|
if (opt == OPT_HELP) {
|
||||||
fputs(help, stdout);
|
fputs(help, stdout);
|
||||||
if (!s->verbose)
|
|
||||||
return 0;
|
|
||||||
++opt;
|
|
||||||
}
|
|
||||||
if (opt == OPT_HELP2) {
|
|
||||||
fputs(help2, stdout);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (opt == OPT_M32 || opt == OPT_M64)
|
|
||||||
return tcc_tool_cross(s, argv, opt);
|
|
||||||
if (s->verbose)
|
if (s->verbose)
|
||||||
|
goto help2;
|
||||||
|
} else if (opt == OPT_HELP2) {
|
||||||
|
help2: fputs(help2, stdout);
|
||||||
|
} else if (opt == OPT_M32 || opt == OPT_M64) {
|
||||||
|
ret = tcc_tool_cross(argv, opt);
|
||||||
|
} else if (s->verbose)
|
||||||
printf("%s", version);
|
printf("%s", version);
|
||||||
|
|
||||||
if (opt == OPT_AR)
|
if (opt == OPT_AR)
|
||||||
return tcc_tool_ar(s, argc, argv);
|
ret = tcc_tool_ar(argc, argv);
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (opt == OPT_IMPDEF)
|
if (opt == OPT_IMPDEF)
|
||||||
return tcc_tool_impdef(s, argc, argv);
|
ret = tcc_tool_impdef(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
if (opt == OPT_V)
|
|
||||||
return 0;
|
|
||||||
if (opt == OPT_PRINT_DIRS) {
|
if (opt == OPT_PRINT_DIRS) {
|
||||||
/* initialize search dirs */
|
/* initialize search dirs */
|
||||||
set_environment(s);
|
set_environment(s);
|
||||||
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
|
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
|
||||||
print_search_dirs(s);
|
print_search_dirs(s);
|
||||||
return 0;
|
}
|
||||||
|
if (opt < 0) err:
|
||||||
|
ret = 1;
|
||||||
|
if (opt) {
|
||||||
|
tcc_delete(s);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->nb_files == 0) {
|
if (s->nb_files == 0) {
|
||||||
@ -345,7 +345,7 @@ redo:
|
|||||||
tcc_error_noabort("cannot specify output file with -c many files");
|
tcc_error_noabort("cannot specify output file with -c many files");
|
||||||
}
|
}
|
||||||
if (s->nb_errors)
|
if (s->nb_errors)
|
||||||
return 1;
|
goto err;
|
||||||
if (s->do_bench)
|
if (s->do_bench)
|
||||||
start_time = getclock_ms();
|
start_time = getclock_ms();
|
||||||
}
|
}
|
||||||
@ -419,7 +419,6 @@ redo:
|
|||||||
tcc_print_stats(s, end_time - start_time);
|
tcc_print_stats(s, end_time - start_time);
|
||||||
|
|
||||||
tcc_delete(s);
|
tcc_delete(s);
|
||||||
|
|
||||||
if (!done)
|
if (!done)
|
||||||
goto redo;
|
goto redo;
|
||||||
if (ppfp && ppfp != stdout)
|
if (ppfp && ppfp != stdout)
|
||||||
|
|||||||
9
tcc.h
9
tcc.h
@ -95,13 +95,12 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||||||
# define O_BINARY 0
|
# define O_BINARY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifdef __clang__ // clang -fsanitize compains about: NULL+value
|
||||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
#define offsetof(type, field) __builtin_offsetof(type, field)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __clang__ // clang -fsanitize compains about: NULL+value
|
#ifndef offsetof
|
||||||
#undef offsetof
|
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
||||||
#define offsetof(type, field) __builtin_offsetof(type, field)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef countof
|
#ifndef countof
|
||||||
|
|||||||
25
tccelf.c
25
tccelf.c
@ -318,8 +318,7 @@ ST_FUNC size_t section_add(Section *sec, addr_t size, int align)
|
|||||||
ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
|
ST_FUNC void *section_ptr_add(Section *sec, addr_t size)
|
||||||
{
|
{
|
||||||
size_t offset = section_add(sec, size, 1);
|
size_t offset = section_add(sec, size, 1);
|
||||||
// clang -fsanitize compains about: NULL+value
|
return sec->data + offset;
|
||||||
return sec->data ? sec->data + offset : (void *)offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef ELF_OBJ_ONLY
|
#ifndef ELF_OBJ_ONLY
|
||||||
@ -1598,7 +1597,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1)
|
|||||||
|
|
||||||
s = data_section;
|
s = data_section;
|
||||||
/* Align to PTR_SIZE */
|
/* Align to PTR_SIZE */
|
||||||
section_ptr_add(s, -s->data_offset & (PTR_SIZE - 1));
|
section_add(s, 0, PTR_SIZE);
|
||||||
o = s->data_offset;
|
o = s->data_offset;
|
||||||
/* create a struct rt_context (see tccrun.c) */
|
/* create a struct rt_context (see tccrun.c) */
|
||||||
if (s1->dwarf) {
|
if (s1->dwarf) {
|
||||||
@ -2837,7 +2836,6 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
|||||||
int textrel, got_sym, dt_flags_1;
|
int textrel, got_sym, dt_flags_1;
|
||||||
|
|
||||||
file_type = s1->output_type;
|
file_type = s1->output_type;
|
||||||
s1->nb_errors = 0;
|
|
||||||
ret = -1;
|
ret = -1;
|
||||||
interp = dynstr = dynamic = NULL;
|
interp = dynstr = dynamic = NULL;
|
||||||
sec_order = NULL;
|
sec_order = NULL;
|
||||||
@ -3030,7 +3028,6 @@ static int elf_output_obj(TCCState *s1, const char *filename)
|
|||||||
{
|
{
|
||||||
Section *s;
|
Section *s;
|
||||||
int i, ret, file_offset;
|
int i, ret, file_offset;
|
||||||
s1->nb_errors = 0;
|
|
||||||
/* Allocate strings for section names */
|
/* Allocate strings for section names */
|
||||||
alloc_sec_names(s1, 1);
|
alloc_sec_names(s1, 1);
|
||||||
file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
|
file_offset = (sizeof (ElfW(Ehdr)) + 3) & -4;
|
||||||
@ -3049,6 +3046,7 @@ static int elf_output_obj(TCCState *s1, const char *filename)
|
|||||||
|
|
||||||
LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
|
LIBTCCAPI int tcc_output_file(TCCState *s, const char *filename)
|
||||||
{
|
{
|
||||||
|
s->nb_errors = 0;
|
||||||
if (s->test_coverage)
|
if (s->test_coverage)
|
||||||
tcc_tcov_add_file(s, filename);
|
tcc_tcov_add_file(s, filename);
|
||||||
if (s->output_type == TCC_OUTPUT_OBJ)
|
if (s->output_type == TCC_OUTPUT_OBJ)
|
||||||
@ -3254,21 +3252,19 @@ invalid:
|
|||||||
s->sh_entsize = sh->sh_entsize;
|
s->sh_entsize = sh->sh_entsize;
|
||||||
sm_table[i].new_section = 1;
|
sm_table[i].new_section = 1;
|
||||||
found:
|
found:
|
||||||
|
size = sh->sh_size;
|
||||||
/* align start of section */
|
/* align start of section */
|
||||||
s->data_offset += -s->data_offset & (sh->sh_addralign - 1);
|
offset = section_add(s, size, sh->sh_addralign);
|
||||||
if (sh->sh_addralign > s->sh_addralign)
|
if (sh->sh_addralign > s->sh_addralign)
|
||||||
s->sh_addralign = sh->sh_addralign;
|
s->sh_addralign = sh->sh_addralign;
|
||||||
sm_table[i].offset = s->data_offset;
|
sm_table[i].offset = offset;
|
||||||
sm_table[i].s = s;
|
sm_table[i].s = s;
|
||||||
/* concatenate sections */
|
/* concatenate sections */
|
||||||
size = sh->sh_size;
|
if (sh->sh_type != SHT_NOBITS && size) {
|
||||||
if (sh->sh_type != SHT_NOBITS) {
|
|
||||||
unsigned char *ptr;
|
unsigned char *ptr;
|
||||||
lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
|
lseek(fd, file_offset + sh->sh_offset, SEEK_SET);
|
||||||
ptr = section_ptr_add(s, size);
|
ptr = s->data + offset;
|
||||||
full_read(fd, ptr, size);
|
full_read(fd, ptr, size);
|
||||||
} else {
|
|
||||||
s->data_offset += size;
|
|
||||||
}
|
}
|
||||||
#if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
#if defined TCC_TARGET_ARM || defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
||||||
/* align code sections to instruction lenght */
|
/* align code sections to instruction lenght */
|
||||||
@ -3310,6 +3306,9 @@ invalid:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!symtab)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* resolve symbols */
|
/* resolve symbols */
|
||||||
old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
|
old_to_new_syms = tcc_mallocz(nb_syms * sizeof(int));
|
||||||
|
|
||||||
@ -3405,7 +3404,7 @@ invalid:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
ret = 0;
|
ret = 0;
|
||||||
the_end:
|
the_end:
|
||||||
tcc_free(symtab);
|
tcc_free(symtab);
|
||||||
|
|||||||
92
tccgen.c
92
tccgen.c
@ -2963,13 +2963,13 @@ static int combine_types(CType *dest, SValue *op1, SValue *op2, int op)
|
|||||||
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
|
(t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_LLONG | VT_UNSIGNED))
|
||||||
type.t |= VT_UNSIGNED;
|
type.t |= VT_UNSIGNED;
|
||||||
} else {
|
} else {
|
||||||
int t1_bit = BIT_SIZE(t1) <= 31 ? VT_BITFIELD : 0;
|
|
||||||
int t2_bit = BIT_SIZE(t2) <= 31 ? VT_BITFIELD : 0;
|
|
||||||
/* integer operations */
|
/* integer operations */
|
||||||
type.t = VT_INT | (VT_LONG & (t1 | t2));
|
type.t = VT_INT | (VT_LONG & (t1 | t2));
|
||||||
/* convert to unsigned if it does not fit in an integer */
|
/* convert to unsigned if it does not fit in an integer */
|
||||||
if ((t1 & (VT_BTYPE | VT_UNSIGNED | t1_bit)) == (VT_INT | VT_UNSIGNED) ||
|
if (((t1 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)
|
||||||
(t2 & (VT_BTYPE | VT_UNSIGNED | t2_bit)) == (VT_INT | VT_UNSIGNED))
|
&& (!(t1 & VT_BITFIELD) || BIT_SIZE(t1) == 32))
|
||||||
|
|| ((t2 & (VT_BTYPE | VT_UNSIGNED)) == (VT_INT | VT_UNSIGNED)
|
||||||
|
&& (!(t2 & VT_BITFIELD) || BIT_SIZE(t2) == 32)))
|
||||||
type.t |= VT_UNSIGNED;
|
type.t |= VT_UNSIGNED;
|
||||||
}
|
}
|
||||||
if (dest)
|
if (dest)
|
||||||
@ -5615,6 +5615,8 @@ ST_FUNC void unary(void)
|
|||||||
as statement expressions can't ever be entered from the
|
as statement expressions can't ever be entered from the
|
||||||
outside, so any reactivation of code emission (from labels
|
outside, so any reactivation of code emission (from labels
|
||||||
or loop heads) can be disabled again after the end of it. */
|
or loop heads) can be disabled again after the end of it. */
|
||||||
|
/* default return value is (void) */
|
||||||
|
vpushi(0), vtop->type.t = VT_VOID;
|
||||||
block(STMT_EXPR);
|
block(STMT_EXPR);
|
||||||
/* If the statement expr can be entered, then we retain the current
|
/* If the statement expr can be entered, then we retain the current
|
||||||
nocode_wanted state (from e.g. a 'return 0;' in the stmt-expr).
|
nocode_wanted state (from e.g. a 'return 0;' in the stmt-expr).
|
||||||
@ -7036,12 +7038,6 @@ static void block(int flags)
|
|||||||
struct scope o;
|
struct scope o;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
|
|
||||||
if (flags & STMT_EXPR) {
|
|
||||||
/* default return value is (void) */
|
|
||||||
vpushi(0);
|
|
||||||
vtop->type.t = VT_VOID;
|
|
||||||
}
|
|
||||||
|
|
||||||
again:
|
again:
|
||||||
t = tok;
|
t = tok;
|
||||||
/* If the token carries a value, next() might destroy it. Only with
|
/* If the token carries a value, next() might destroy it. Only with
|
||||||
@ -7057,8 +7053,8 @@ again:
|
|||||||
new_scope_s(&o);
|
new_scope_s(&o);
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
skip(')');
|
|
||||||
a = gvtst(1, 0);
|
a = gvtst(1, 0);
|
||||||
|
skip(')');
|
||||||
block(0);
|
block(0);
|
||||||
if (tok == TOK_ELSE) {
|
if (tok == TOK_ELSE) {
|
||||||
d = gjmp(0);
|
d = gjmp(0);
|
||||||
@ -7076,8 +7072,8 @@ again:
|
|||||||
d = gind();
|
d = gind();
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
skip(')');
|
|
||||||
a = gvtst(1, 0);
|
a = gvtst(1, 0);
|
||||||
|
skip(')');
|
||||||
b = 0;
|
b = 0;
|
||||||
lblock(&a, &b);
|
lblock(&a, &b);
|
||||||
gjmp_addr(d);
|
gjmp_addr(d);
|
||||||
@ -7105,8 +7101,6 @@ again:
|
|||||||
while (tok != '}') {
|
while (tok != '}') {
|
||||||
decl(VT_LOCAL);
|
decl(VT_LOCAL);
|
||||||
if (tok != '}') {
|
if (tok != '}') {
|
||||||
if (flags & STMT_EXPR)
|
|
||||||
vpop();
|
|
||||||
block(flags | STMT_COMPOUND);
|
block(flags | STMT_COMPOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -7208,9 +7202,9 @@ again:
|
|||||||
skip(TOK_WHILE);
|
skip(TOK_WHILE);
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
|
c = gvtst(0, 0);
|
||||||
skip(')');
|
skip(')');
|
||||||
skip(';');
|
skip(';');
|
||||||
c = gvtst(0, 0);
|
|
||||||
gsym_addr(c, d);
|
gsym_addr(c, d);
|
||||||
gsym(a);
|
gsym(a);
|
||||||
prev_scope_s(&o);
|
prev_scope_s(&o);
|
||||||
@ -7228,9 +7222,9 @@ again:
|
|||||||
new_scope_s(&o);
|
new_scope_s(&o);
|
||||||
skip('(');
|
skip('(');
|
||||||
gexpr();
|
gexpr();
|
||||||
skip(')');
|
|
||||||
if (!is_integer_btype(vtop->type.t & VT_BTYPE))
|
if (!is_integer_btype(vtop->type.t & VT_BTYPE))
|
||||||
tcc_error("switch value not an integer");
|
tcc_error("switch value not an integer");
|
||||||
|
skip(')');
|
||||||
sw->sv = *vtop--; /* save switch value */
|
sw->sv = *vtop--; /* save switch value */
|
||||||
a = 0;
|
a = 0;
|
||||||
b = gjmp(0); /* jump to first case */
|
b = gjmp(0); /* jump to first case */
|
||||||
@ -8294,6 +8288,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
|||||||
if (type->t & VT_VLA) {
|
if (type->t & VT_VLA) {
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
if (has_init)
|
||||||
|
tcc_error("variable length array cannot be initialized");
|
||||||
|
|
||||||
if (NODATA_WANTED)
|
if (NODATA_WANTED)
|
||||||
goto no_alloc;
|
goto no_alloc;
|
||||||
|
|
||||||
@ -8513,6 +8510,27 @@ static void do_Static_assert(void)
|
|||||||
skip(';');
|
skip(';');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
static void pe_check_linkage(CType *type, AttributeDef *ad)
|
||||||
|
{
|
||||||
|
if (!ad->a.dllimport && !ad->a.dllexport)
|
||||||
|
return;
|
||||||
|
if (type->t & VT_STATIC)
|
||||||
|
tcc_error("cannot have dll linkage with static");
|
||||||
|
if (type->t & VT_TYPEDEF) {
|
||||||
|
const char *m = ad->a.dllimport ? "im" : "ex";
|
||||||
|
tcc_warning("'dll%sport' attribute ignored for typedef", m);
|
||||||
|
ad->a.dllimport = 0;
|
||||||
|
ad->a.dllexport = 0;
|
||||||
|
} else if (ad->a.dllimport) {
|
||||||
|
if ((type->t & VT_BTYPE) == VT_FUNC)
|
||||||
|
ad->a.dllimport = 0;
|
||||||
|
else
|
||||||
|
type->t |= VT_EXTERN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
/* 'l' is VT_LOCAL or VT_CONST to define default storage type
|
||||||
or VT_CMP if parsing old style parameter list
|
or VT_CMP if parsing old style parameter list
|
||||||
or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
|
or VT_JMP if parsing c99 for decl: for (int i = 0, ...) */
|
||||||
@ -8559,18 +8577,18 @@ static int decl(int l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tok == ';') {
|
if (tok == ';') {
|
||||||
if ((btype.t & VT_BTYPE) == VT_STRUCT) {
|
if ((btype.t & VT_BTYPE) == VT_STRUCT
|
||||||
v = btype.ref->v;
|
&& (btype.ref->v & ~SYM_STRUCT) < SYM_FIRST_ANOM)
|
||||||
if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) >= SYM_FIRST_ANOM)
|
; /* struct decl with named tag */
|
||||||
tcc_warning("unnamed struct/union that defines no instances");
|
else if (IS_ENUM(btype.t))
|
||||||
|
; /* enum decl */
|
||||||
|
else
|
||||||
|
tcc_warning("useless type defines no instances");
|
||||||
|
if (l == VT_JMP)
|
||||||
|
return 1;
|
||||||
next();
|
next();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (IS_ENUM(btype.t)) {
|
|
||||||
next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) { /* iterate thru each declaration */
|
while (1) { /* iterate thru each declaration */
|
||||||
type = btype;
|
type = btype;
|
||||||
@ -8637,20 +8655,7 @@ static int decl(int l)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (ad.a.dllimport || ad.a.dllexport) {
|
pe_check_linkage(&type, &ad);
|
||||||
if (type.t & VT_STATIC)
|
|
||||||
tcc_error("cannot have dll linkage with static");
|
|
||||||
if (type.t & VT_TYPEDEF) {
|
|
||||||
tcc_warning("'%s' attribute ignored for typedef",
|
|
||||||
ad.a.dllimport ? (ad.a.dllimport = 0, "dllimport") :
|
|
||||||
(ad.a.dllexport = 0, "dllexport"));
|
|
||||||
} else if (ad.a.dllimport) {
|
|
||||||
if ((type.t & VT_BTYPE) == VT_FUNC)
|
|
||||||
ad.a.dllimport = 0;
|
|
||||||
else
|
|
||||||
type.t |= VT_EXTERN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (tok == '{') {
|
if (tok == '{') {
|
||||||
if (l != VT_CONST)
|
if (l != VT_CONST)
|
||||||
@ -8700,6 +8705,7 @@ static int decl(int l)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
has_init = 0;
|
||||||
if (l == VT_CMP) {
|
if (l == VT_CMP) {
|
||||||
/* find parameter in function parameter list */
|
/* find parameter in function parameter list */
|
||||||
for (sym = func_vt.ref->next; sym; sym = sym->next)
|
for (sym = func_vt.ref->next; sym; sym = sym->next)
|
||||||
@ -8747,9 +8753,9 @@ static int decl(int l)
|
|||||||
/* not lvalue if array */
|
/* not lvalue if array */
|
||||||
r |= VT_LVAL;
|
r |= VT_LVAL;
|
||||||
}
|
}
|
||||||
has_init = (tok == '=');
|
|
||||||
if (has_init && (type.t & VT_VLA))
|
if (tok == '=')
|
||||||
tcc_error("variable length array cannot be initialized");
|
has_init = 1;
|
||||||
|
|
||||||
if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST))
|
if (((type.t & VT_EXTERN) && (!has_init || l != VT_CONST))
|
||||||
|| (type.t & VT_BTYPE) == VT_FUNC
|
|| (type.t & VT_BTYPE) == VT_FUNC
|
||||||
@ -8789,7 +8795,7 @@ static int decl(int l)
|
|||||||
}
|
}
|
||||||
if (tok != ',') {
|
if (tok != ',') {
|
||||||
if (l == VT_JMP)
|
if (l == VT_JMP)
|
||||||
return 1;
|
return has_init ? v : 1;
|
||||||
skip(';');
|
skip(';');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
32
tccpp.c
32
tccpp.c
@ -117,16 +117,6 @@ ST_FUNC void expect(const char *msg)
|
|||||||
|
|
||||||
#define USE_TAL
|
#define USE_TAL
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# if defined _M_AMD64 || defined _M_ARM64 || defined _M_ARM64EC || defined _M_IA64 || defined _M_X64
|
|
||||||
# define POINTER_SIZE 8
|
|
||||||
# else
|
|
||||||
# define POINTER_SIZE 4
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define POINTER_SIZE sizeof(void *)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef USE_TAL
|
#ifndef USE_TAL
|
||||||
#define tal_free(al, p) tcc_free(p)
|
#define tal_free(al, p) tcc_free(p)
|
||||||
#define tal_realloc(al, p, size) tcc_realloc(p, size)
|
#define tal_realloc(al, p, size) tcc_realloc(p, size)
|
||||||
@ -143,7 +133,6 @@ ST_FUNC void expect(const char *msg)
|
|||||||
#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
|
#define tal_free(al, p) tal_free_impl(al, p, __FILE__, __LINE__)
|
||||||
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
|
#define tal_realloc(al, p, size) tal_realloc_impl(&al, p, size, __FILE__, __LINE__)
|
||||||
#define TAL_DEBUG_PARAMS , const char *file, int line
|
#define TAL_DEBUG_PARAMS , const char *file, int line
|
||||||
#define TAL_DEBUG_FILE_LEN 40
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
|
#define TOKSYM_TAL_SIZE (768 * 1024) /* allocator for tiny TokenSym in table_ident */
|
||||||
@ -167,13 +156,16 @@ typedef struct TinyAlloc {
|
|||||||
} TinyAlloc;
|
} TinyAlloc;
|
||||||
|
|
||||||
typedef struct tal_header_t {
|
typedef struct tal_header_t {
|
||||||
ALIGNED(POINTER_SIZE) unsigned size;
|
size_t size; /* word align */
|
||||||
#ifdef TAL_DEBUG
|
#ifdef TAL_DEBUG
|
||||||
int line_num; /* negative line_num used for double free check */
|
int line_num; /* negative line_num used for double free check */
|
||||||
char file_name[TAL_DEBUG_FILE_LEN + 1];
|
char file_name[40];
|
||||||
#endif
|
#endif
|
||||||
} tal_header_t;
|
} tal_header_t;
|
||||||
|
|
||||||
|
#define TAL_ALIGN(size) \
|
||||||
|
(((size) + (sizeof (size_t) - 1)) & ~(sizeof (size_t) - 1))
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
|
static TinyAlloc *tal_new(TinyAlloc **pal, unsigned limit, unsigned size)
|
||||||
@ -208,7 +200,7 @@ tail_call:
|
|||||||
tal_header_t *header = (tal_header_t *)p;
|
tal_header_t *header = (tal_header_t *)p;
|
||||||
if (header->line_num > 0) {
|
if (header->line_num > 0) {
|
||||||
fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
|
fprintf(stderr, "%s:%d: chunk of %d bytes leaked\n",
|
||||||
header->file_name, header->line_num, header->size);
|
header->file_name, header->line_num, (int)header->size);
|
||||||
}
|
}
|
||||||
p += header->size + sizeof(tal_header_t);
|
p += header->size + sizeof(tal_header_t);
|
||||||
}
|
}
|
||||||
@ -256,7 +248,7 @@ static void *tal_realloc_impl(TinyAlloc **pal, void *p, unsigned size TAL_DEBUG_
|
|||||||
tal_header_t *header;
|
tal_header_t *header;
|
||||||
void *ret;
|
void *ret;
|
||||||
int is_own;
|
int is_own;
|
||||||
unsigned adj_size = (size + POINTER_SIZE - 1) & -POINTER_SIZE;
|
unsigned adj_size = TAL_ALIGN(size);
|
||||||
TinyAlloc *al = *pal;
|
TinyAlloc *al = *pal;
|
||||||
|
|
||||||
tail_call:
|
tail_call:
|
||||||
@ -266,9 +258,8 @@ tail_call:
|
|||||||
header = (tal_header_t *)al->p;
|
header = (tal_header_t *)al->p;
|
||||||
header->size = adj_size;
|
header->size = adj_size;
|
||||||
#ifdef TAL_DEBUG
|
#ifdef TAL_DEBUG
|
||||||
{ int ofs = strlen(file) - TAL_DEBUG_FILE_LEN;
|
{ int ofs = strlen(file) + 1 - sizeof header->file_name;
|
||||||
strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), TAL_DEBUG_FILE_LEN);
|
strcpy(header->file_name, file + (ofs > 0 ? ofs : 0));
|
||||||
header->file_name[TAL_DEBUG_FILE_LEN] = 0;
|
|
||||||
header->line_num = line; }
|
header->line_num = line; }
|
||||||
#endif
|
#endif
|
||||||
ret = al->p + sizeof(tal_header_t);
|
ret = al->p + sizeof(tal_header_t);
|
||||||
@ -2986,6 +2977,11 @@ maybe_newline:
|
|||||||
tok = c;
|
tok = c;
|
||||||
p++;
|
p++;
|
||||||
break;
|
break;
|
||||||
|
case 0xEF: /* UTF8 BOM ? */
|
||||||
|
if (p[1] == 0xBB && p[2] == 0xBF && p == file->buffer) {
|
||||||
|
p += 3;
|
||||||
|
goto redo_no_start;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
|
if (c >= 0x80 && c <= 0xFF) /* utf8 identifiers */
|
||||||
goto parse_ident_fast;
|
goto parse_ident_fast;
|
||||||
|
|||||||
13
tccrun.c
13
tccrun.c
@ -312,6 +312,7 @@ static int tcc_relocate_ex(TCCState *s1, void *ptr, unsigned ptr_diff)
|
|||||||
addr_t mem, addr;
|
addr_t mem, addr;
|
||||||
|
|
||||||
if (NULL == ptr) {
|
if (NULL == ptr) {
|
||||||
|
s1->nb_errors = 0;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
pe_output_file(s1, NULL);
|
pe_output_file(s1, NULL);
|
||||||
#else
|
#else
|
||||||
@ -495,10 +496,6 @@ static void bt_link(TCCState *s1)
|
|||||||
{
|
{
|
||||||
#ifdef CONFIG_TCC_BACKTRACE
|
#ifdef CONFIG_TCC_BACKTRACE
|
||||||
rt_context *rc;
|
rt_context *rc;
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
|
||||||
void *p;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!s1->do_backtrace)
|
if (!s1->do_backtrace)
|
||||||
return;
|
return;
|
||||||
rc = tcc_get_symbol(s1, "__rt_info");
|
rc = tcc_get_symbol(s1, "__rt_info");
|
||||||
@ -511,6 +508,7 @@ static void bt_link(TCCState *s1)
|
|||||||
rc->prog_base &= 0xffffffff00000000ULL;
|
rc->prog_base &= 0xffffffff00000000ULL;
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (s1->do_bounds_check) {
|
if (s1->do_bounds_check) {
|
||||||
|
void *p;
|
||||||
if ((p = tcc_get_symbol(s1, "__bound_init")))
|
if ((p = tcc_get_symbol(s1, "__bound_init")))
|
||||||
((void(*)(void*,int))p)(rc->bounds_start, 1);
|
((void(*)(void*,int))p)(rc->bounds_start, 1);
|
||||||
}
|
}
|
||||||
@ -599,6 +597,13 @@ static void rt_exit(rt_frame *f, int code)
|
|||||||
s = rt_find_state(f);
|
s = rt_find_state(f);
|
||||||
rt_post_sem();
|
rt_post_sem();
|
||||||
if (s && s->run_lj) {
|
if (s && s->run_lj) {
|
||||||
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
if (f->fp) { /* called from signal */
|
||||||
|
void *p = tcc_get_symbol(s, "__bound_exit");
|
||||||
|
if (p)
|
||||||
|
((void (*)(void))p)();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (code == 0)
|
if (code == 0)
|
||||||
code = RT_EXIT_ZERO;
|
code = RT_EXIT_ZERO;
|
||||||
((void(*)(void*,int))s->run_lj)(s->run_jb, code);
|
((void(*)(void*,int))s->run_lj)(s->run_jb, code);
|
||||||
|
|||||||
12
tcctools.c
12
tcctools.c
@ -54,7 +54,7 @@ static int ar_usage(int ret) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ST_FUNC int tcc_tool_ar(TCCState *s1, int argc, char **argv)
|
ST_FUNC int tcc_tool_ar(int argc, char **argv)
|
||||||
{
|
{
|
||||||
static const ArHdr arhdr_init = {
|
static const ArHdr arhdr_init = {
|
||||||
"/ ",
|
"/ ",
|
||||||
@ -360,7 +360,7 @@ the_end:
|
|||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
|
|
||||||
ST_FUNC int tcc_tool_impdef(TCCState *s1, int argc, char **argv)
|
ST_FUNC int tcc_tool_impdef(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int ret, v, i;
|
int ret, v, i;
|
||||||
char infile[260];
|
char infile[260];
|
||||||
@ -487,9 +487,9 @@ the_end:
|
|||||||
|
|
||||||
#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
|
#if !defined TCC_TARGET_I386 && !defined TCC_TARGET_X86_64
|
||||||
|
|
||||||
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int option)
|
ST_FUNC int tcc_tool_cross(char **argv, int option)
|
||||||
{
|
{
|
||||||
tcc_error_noabort("-m%d not implemented.", option);
|
fprintf(stderr, "tcc -m%d not implemented\n", option);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,7 +546,7 @@ static int execvp_win32(const char *prog, char **argv)
|
|||||||
#define execvp execvp_win32
|
#define execvp execvp_win32
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target)
|
ST_FUNC int tcc_tool_cross(char **argv, int target)
|
||||||
{
|
{
|
||||||
char program[4096];
|
char program[4096];
|
||||||
char *a0 = argv[0];
|
char *a0 = argv[0];
|
||||||
@ -565,7 +565,7 @@ ST_FUNC int tcc_tool_cross(TCCState *s1, char **argv, int target)
|
|||||||
|
|
||||||
if (strcmp(a0, program))
|
if (strcmp(a0, program))
|
||||||
execvp(argv[0] = program, argv);
|
execvp(argv[0] = program, argv);
|
||||||
tcc_error_noabort("could not run '%s'", program);
|
fprintf(stderr, "tcc: could not run '%s'\n", program);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -79,7 +79,7 @@ endif
|
|||||||
|
|
||||||
all test :
|
all test :
|
||||||
@echo ------------ version ------------
|
@echo ------------ version ------------
|
||||||
@ASAN_OPTIONS=detect_leaks=0 $(TCC_LOCAL) -v
|
@$(TCC_LOCAL) -v
|
||||||
@$(MAKE) --no-print-directory -s clean
|
@$(MAKE) --no-print-directory -s clean
|
||||||
@$(MAKE) --no-print-directory -s -r _all
|
@$(MAKE) --no-print-directory -s -r _all
|
||||||
|
|
||||||
|
|||||||
@ -102,7 +102,6 @@ GEN-ALWAYS =
|
|||||||
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
|
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
|
||||||
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \
|
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \
|
||||||
-e 's;0x[0-9A-Fa-f]\{1,\};0x?;g'
|
-e 's;0x[0-9A-Fa-f]\{1,\};0x?;g'
|
||||||
112_backtrace.test: LEAK=ASAN_OPTIONS=detect_leaks=0
|
|
||||||
|
|
||||||
# this test creates two DLLs and an EXE
|
# this test creates two DLLs and an EXE
|
||||||
113_btdll.test: T1 = \
|
113_btdll.test: T1 = \
|
||||||
@ -137,7 +136,7 @@ all test tests2.all: $(filter-out $(SKIP),$(TESTS))
|
|||||||
@echo Test: $*...
|
@echo Test: $*...
|
||||||
@$(call T1,$<) $(T3)
|
@$(call T1,$<) $(T3)
|
||||||
|
|
||||||
T1 = $(LEAK) $(TCC) $(FLAGS) $(T2) $(ARGS)
|
T1 = $(TCC) $(FLAGS) $(T2) $(ARGS)
|
||||||
T2 = $(if $(NORUN),$1 -o $(basename $@).exe && ./$(basename $@).exe,-run $1)
|
T2 = $(if $(NORUN),$1 -o $(basename $@).exe && ./$(basename $@).exe,-run $1)
|
||||||
T3 = $(FILTER) >$*.output 2>&1 || true \
|
T3 = $(FILTER) >$*.output 2>&1 || true \
|
||||||
&& diff -Nbu $(filter %.expect,$^) $*.output \
|
&& diff -Nbu $(filter %.expect,$^) $*.output \
|
||||||
|
|||||||
@ -132,6 +132,10 @@ if %TX%==32 echo>> ..\config.h #ifdef TCC_TARGET_I386
|
|||||||
echo>> ..\config.h #define CONFIG_TCC_CROSSPREFIX "%PX%-"
|
echo>> ..\config.h #define CONFIG_TCC_CROSSPREFIX "%PX%-"
|
||||||
echo>> ..\config.h #endif
|
echo>> ..\config.h #endif
|
||||||
|
|
||||||
|
@rem echo>> ..\config.h #define CONFIG_TCC_PREDEFS 1
|
||||||
|
@rem %CC% -DC2STR ..\conftest.c -o c2str.exe
|
||||||
|
@rem .\c2str.exe ../include/tccdefs.h ../tccdefs_.h
|
||||||
|
|
||||||
for %%f in (*tcc.exe *tcc.dll) do @del %%f
|
for %%f in (*tcc.exe *tcc.dll) do @del %%f
|
||||||
|
|
||||||
@if _%TCC_C%_==__ goto compiler_2parts
|
@if _%TCC_C%_==__ goto compiler_2parts
|
||||||
@ -200,8 +204,9 @@ exit /B %ERRORLEVEL%
|
|||||||
.\tcc -B. -m%1 -c ../lib/alloca.S
|
.\tcc -B. -m%1 -c ../lib/alloca.S
|
||||||
.\tcc -B. -m%1 -c ../lib/alloca-bt.S
|
.\tcc -B. -m%1 -c ../lib/alloca-bt.S
|
||||||
.\tcc -B. -m%1 -c ../lib/stdatomic.c
|
.\tcc -B. -m%1 -c ../lib/stdatomic.c
|
||||||
|
.\tcc -B. -m%1 -c ../lib/atomic.S
|
||||||
.\tcc -B. -m%1 -c ../lib/builtin.c
|
.\tcc -B. -m%1 -c ../lib/builtin.c
|
||||||
.\tcc -B. -m%1 -ar lib/%2libtcc1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o builtin.o
|
.\tcc -B. -m%1 -ar lib/%2libtcc1.a libtcc1.o crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o chkstk.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o
|
||||||
.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt -I..
|
.\tcc -B. -m%1 -c ../lib/bcheck.c -o lib/%2bcheck.o -bt -I..
|
||||||
.\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o
|
.\tcc -B. -m%1 -c ../lib/bt-exe.c -o lib/%2bt-exe.o
|
||||||
.\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o
|
.\tcc -B. -m%1 -c ../lib/bt-log.c -o lib/%2bt-log.o
|
||||||
|
|||||||
@ -376,10 +376,16 @@ extern "C" {
|
|||||||
_CRTIMP int __cdecl _set_error_mode(int _Mode);
|
_CRTIMP int __cdecl _set_error_mode(int _Mode);
|
||||||
void __cdecl srand(unsigned int _Seed);
|
void __cdecl srand(unsigned int _Seed);
|
||||||
double __cdecl strtod(const char *_Str,char **_EndPtr);
|
double __cdecl strtod(const char *_Str,char **_EndPtr);
|
||||||
float __cdecl strtof(const char *nptr, char **endptr);
|
|
||||||
#if !defined __NO_ISOCEXT /* in libmingwex.a */
|
#if !defined __NO_ISOCEXT /* in libmingwex.a */
|
||||||
|
#if __TINYC__
|
||||||
|
__CRT_INLINE float __cdecl strtof (const char *p, char ** e) { return strtod(p, e); }
|
||||||
|
__CRT_INLINE long double __cdecl strtold(const char *p, char ** e) { return strtod(p, e); }
|
||||||
|
#else
|
||||||
float __cdecl strtof (const char * __restrict__, char ** __restrict__);
|
float __cdecl strtof (const char * __restrict__, char ** __restrict__);
|
||||||
long double __cdecl strtold(const char * __restrict__, char ** __restrict__);
|
long double __cdecl strtold(const char * __restrict__, char ** __restrict__);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
float __cdecl strtof(const char *nptr, char **endptr);
|
||||||
#endif /* __NO_ISOCEXT */
|
#endif /* __NO_ISOCEXT */
|
||||||
_CRTIMP double __cdecl _strtod_l(const char *_Str,char **_EndPtr,_locale_t _Locale);
|
_CRTIMP double __cdecl _strtod_l(const char *_Str,char **_EndPtr,_locale_t _Locale);
|
||||||
long __cdecl strtol(const char *_Str,char **_EndPtr,int _Radix);
|
long __cdecl strtol(const char *_Str,char **_EndPtr,int _Radix);
|
||||||
|
|||||||
@ -859,7 +859,7 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef !defined (InterlockedAnd64)
|
#ifndef InterlockedAnd64
|
||||||
#define InterlockedAnd64 InterlockedAnd64_Inline
|
#define InterlockedAnd64 InterlockedAnd64_Inline
|
||||||
|
|
||||||
__CRT_INLINE LONGLONG InterlockedAnd64_Inline (LONGLONG volatile *Destination,LONGLONG Value) {
|
__CRT_INLINE LONGLONG InterlockedAnd64_Inline (LONGLONG volatile *Destination,LONGLONG Value) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user