mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-24 03:40:09 +08:00
libtcc usability improvements
- tccgen.c: cleanup switch data etc. after errors (*) - tccpe.c: faster get_dllexports (*) - tccpe.c: support -Wl,-e[ntry]=... (*) - libtcc.c: win32: use ANSI functions (GetModuleFileNameA etc.) - tccrun.c: be nice to tcc-0.9.26 ("struct/enum already defined") - tccpp.c: be nice to tcc-0.9.27's va_start/end macros (*) suggested by Robert Schlicht https://lists.gnu.org/archive/html/tinycc-devel/2024-03/msg00012.html
This commit is contained in:
parent
9d2068c630
commit
2b0a663df9
11
libtcc.c
11
libtcc.c
@ -101,7 +101,7 @@ BOOL WINAPI DllMain (HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
static inline char *config_tccdir_w32(char *path)
|
||||
{
|
||||
char *p;
|
||||
GetModuleFileName(tcc_module, path, MAX_PATH);
|
||||
GetModuleFileNameA(tcc_module, path, MAX_PATH);
|
||||
p = tcc_basename(normalize_slashes(strlwr(path)));
|
||||
if (p > path)
|
||||
--p;
|
||||
@ -115,7 +115,7 @@ static inline char *config_tccdir_w32(char *path)
|
||||
static void tcc_add_systemdir(TCCState *s)
|
||||
{
|
||||
char buf[1000];
|
||||
GetSystemDirectory(buf, sizeof buf);
|
||||
GetSystemDirectoryA(buf, sizeof buf);
|
||||
tcc_add_library_path(s, normalize_slashes(buf));
|
||||
}
|
||||
#endif
|
||||
@ -801,14 +801,11 @@ LIBTCCAPI TCCState *tcc_new(void)
|
||||
TCCState *s;
|
||||
|
||||
s = tcc_mallocz(sizeof(TCCState));
|
||||
if (!s)
|
||||
return NULL;
|
||||
#ifdef MEM_DEBUG
|
||||
tcc_memcheck(1);
|
||||
#endif
|
||||
|
||||
#undef gnu_ext
|
||||
|
||||
s->gnu_ext = 1;
|
||||
s->tcc_ext = 1;
|
||||
s->nocommon = 1;
|
||||
@ -874,11 +871,13 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
|
||||
cstr_free(&s1->cmdline_defs);
|
||||
cstr_free(&s1->cmdline_incl);
|
||||
cstr_free(&s1->linker_arg);
|
||||
tcc_free(s1->dState);
|
||||
#ifdef TCC_IS_NATIVE
|
||||
/* free runtime memory */
|
||||
tcc_run_free(s1);
|
||||
#endif
|
||||
tcc_free(s1->dState);
|
||||
/* free loaded dlls array */
|
||||
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
||||
tcc_free(s1);
|
||||
#ifdef MEM_DEBUG
|
||||
tcc_memcheck(-1);
|
||||
|
36
tccgen.c
36
tccgen.c
@ -157,6 +157,7 @@ static void gv_dup(void);
|
||||
static int get_temp_local_var(int size,int align);
|
||||
static void clear_temp_local_var_list();
|
||||
static void cast_error(CType *st, CType *dt);
|
||||
static void end_switch(void);
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* Automagical code suppression */
|
||||
@ -381,12 +382,10 @@ ST_FUNC void tccgen_init(TCCState *s1)
|
||||
|
||||
ST_FUNC int tccgen_compile(TCCState *s1)
|
||||
{
|
||||
cur_text_section = NULL;
|
||||
funcname = "";
|
||||
func_ind = -1;
|
||||
anon_sym = SYM_FIRST_ANOM;
|
||||
nocode_wanted = DATA_ONLY_WANTED; /* no code outside of functions */
|
||||
local_scope = 0;
|
||||
debug_modes = (s1->do_debug ? 1 : 0) | s1->test_coverage << 1;
|
||||
|
||||
tcc_debug_start(s1);
|
||||
@ -418,10 +417,19 @@ ST_FUNC void tccgen_finish(TCCState *s1)
|
||||
free_defines(NULL);
|
||||
/* free sym_pools */
|
||||
dynarray_reset(&sym_pools, &nb_sym_pools);
|
||||
sym_free_first = NULL;
|
||||
global_label_stack = local_label_stack = NULL;
|
||||
cstr_free(&initstr);
|
||||
dynarray_reset(&stk_data, &nb_stk_data);
|
||||
while (cur_switch)
|
||||
end_switch();
|
||||
local_scope = 0;
|
||||
loop_scope = NULL;
|
||||
all_cleanups = NULL;
|
||||
pending_gotos = NULL;
|
||||
nb_temp_local_vars = 0;
|
||||
global_label_stack = NULL;
|
||||
local_label_stack = NULL;
|
||||
cur_text_section = NULL;
|
||||
sym_free_first = NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@ -6754,6 +6762,14 @@ static void gcase(struct case_t **base, int len, int *bsym)
|
||||
*bsym = gjmp(*bsym);
|
||||
}
|
||||
|
||||
static void end_switch(void)
|
||||
{
|
||||
struct switch_t *sw = cur_switch;
|
||||
dynarray_reset(&sw->p, &sw->n);
|
||||
cur_switch = sw->prev;
|
||||
tcc_free(sw);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* __attribute__((cleanup(fn))) */
|
||||
|
||||
@ -7154,15 +7170,14 @@ again:
|
||||
skip_switch:
|
||||
/* break label */
|
||||
gsym(a);
|
||||
|
||||
dynarray_reset(&sw->p, &sw->n);
|
||||
cur_switch = sw->prev;
|
||||
tcc_free(sw);
|
||||
end_switch();
|
||||
|
||||
} else if (t == TOK_CASE) {
|
||||
struct case_t *cr = tcc_malloc(sizeof(struct case_t));
|
||||
struct case_t *cr;
|
||||
if (!cur_switch)
|
||||
expect("switch");
|
||||
cr = tcc_malloc(sizeof(struct case_t));
|
||||
dynarray_add(&cur_switch->p, &cur_switch->n, cr);
|
||||
cr->v1 = cr->v2 = expr_const64();
|
||||
if (gnu_ext && tok == TOK_DOTS) {
|
||||
next();
|
||||
@ -7174,7 +7189,6 @@ again:
|
||||
/* case and default are unreachable from a switch under nocode_wanted */
|
||||
if (!cur_switch->nocode_wanted)
|
||||
cr->sym = gind();
|
||||
dynarray_add(&cur_switch->p, &cur_switch->n, cr);
|
||||
skip(':');
|
||||
goto block_after_label;
|
||||
|
||||
@ -8574,9 +8588,9 @@ static int decl(int l)
|
||||
fn = tcc_malloc(sizeof *fn + strlen(file->filename));
|
||||
strcpy(fn->filename, file->filename);
|
||||
fn->sym = sym;
|
||||
skip_or_save_block(&fn->func_str);
|
||||
dynarray_add(&tcc_state->inline_fns,
|
||||
&tcc_state->nb_inline_fns, fn);
|
||||
skip_or_save_block(&fn->func_str);
|
||||
} else {
|
||||
/* compute text section */
|
||||
cur_text_section = ad.section;
|
||||
|
75
tccpe.c
75
tccpe.c
@ -921,7 +921,7 @@ static void pe_build_imports(struct pe_info *pe)
|
||||
if (pe->type == PE_RUN) {
|
||||
if (dllref) {
|
||||
if ( !dllref->handle )
|
||||
dllref->handle = LoadLibrary(dllref->name);
|
||||
dllref->handle = LoadLibraryA(dllref->name);
|
||||
v = (ADDR3264)GetProcAddress(dllref->handle, ordinal?(char*)0+ordinal:name);
|
||||
}
|
||||
if (!v)
|
||||
@ -1600,14 +1600,15 @@ static int read_mem(int fd, unsigned offset, void *buffer, unsigned len)
|
||||
|
||||
static int get_dllexports(int fd, char **pp)
|
||||
{
|
||||
int l, i, n, n0, ret;
|
||||
int i, k, l, n, n0, ret;
|
||||
char *p;
|
||||
|
||||
IMAGE_SECTION_HEADER ish;
|
||||
IMAGE_EXPORT_DIRECTORY ied;
|
||||
IMAGE_DOS_HEADER dh;
|
||||
IMAGE_FILE_HEADER ih;
|
||||
DWORD sig, ref, addr, ptr, namep;
|
||||
DWORD sig, ref, addr;
|
||||
DWORD *namep = NULL, p0 = 0, p1;
|
||||
|
||||
int pef_hdroffset, opt_hdroffset, sec_hdroffset;
|
||||
|
||||
@ -1652,33 +1653,37 @@ static int get_dllexports(int fd, char **pp)
|
||||
goto found;
|
||||
}
|
||||
goto the_end_0;
|
||||
|
||||
found:
|
||||
ref = ish.VirtualAddress - ish.PointerToRawData;
|
||||
if (!read_mem(fd, addr - ref, &ied, sizeof ied))
|
||||
goto the_end;
|
||||
|
||||
namep = ied.AddressOfNames - ref;
|
||||
for (i = 0; i < ied.NumberOfNames; ++i) {
|
||||
if (!read_mem(fd, namep, &ptr, sizeof ptr))
|
||||
k = ied.NumberOfNames;
|
||||
if (k) {
|
||||
namep = tcc_malloc(l = k * sizeof *namep);
|
||||
if (!read_mem(fd, ied.AddressOfNames - ref, namep, l))
|
||||
goto the_end;
|
||||
namep += sizeof ptr;
|
||||
for (l = 0;;) {
|
||||
if (n+1 >= n0)
|
||||
p = tcc_realloc(p, n0 = n0 ? n0 * 2 : 256);
|
||||
if (!read_mem(fd, ptr - ref + l++, p + n, 1)) {
|
||||
tcc_free(p), p = NULL;
|
||||
goto the_end;
|
||||
}
|
||||
if (p[n++] == 0)
|
||||
break;
|
||||
for (i = l = 0; i < k; ++i) {
|
||||
p1 = namep[i] - ref;
|
||||
if (p1 != p0)
|
||||
lseek(fd, p0 = p1, SEEK_SET), l = 0;
|
||||
do {
|
||||
if (0 == l) {
|
||||
if (n + 1000 >= n0)
|
||||
p = tcc_realloc(p, n0 += 1000);
|
||||
if ((l = read(fd, p + n, 1000 - 1)) <= 0)
|
||||
goto the_end;
|
||||
}
|
||||
--l, ++p0;
|
||||
} while (p[n++]);
|
||||
}
|
||||
}
|
||||
if (p)
|
||||
p[n] = 0;
|
||||
}
|
||||
the_end_0:
|
||||
ret = 0;
|
||||
the_end:
|
||||
tcc_free(namep);
|
||||
if (ret && p)
|
||||
tcc_free(p), p = NULL;
|
||||
*pp = p;
|
||||
return ret;
|
||||
}
|
||||
@ -1810,15 +1815,14 @@ quit:
|
||||
static int pe_load_dll(TCCState *s1, int fd, const char *filename)
|
||||
{
|
||||
char *p, *q;
|
||||
int index, ret;
|
||||
|
||||
ret = get_dllexports(fd, &p);
|
||||
if (ret) {
|
||||
DLLReference *ref = tcc_add_dllref(s1, filename, 0);
|
||||
if (ref->found)
|
||||
return 0;
|
||||
if (get_dllexports(fd, &p))
|
||||
return -1;
|
||||
} else if (p) {
|
||||
index = tcc_add_dllref(s1, filename, 0)->index;
|
||||
if (p) {
|
||||
for (q = p; *q; q += 1 + strlen(q))
|
||||
pe_putimport(s1, index, q, 0);
|
||||
pe_putimport(s1, ref->index, q, 0);
|
||||
tcc_free(p);
|
||||
}
|
||||
return 0;
|
||||
@ -1941,15 +1945,20 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
||||
start_symbol = "__start";
|
||||
run_symbol = "__runmain";
|
||||
pe_type = PE_EXE;
|
||||
|
||||
if (s1->pe_subsystem == 2)
|
||||
pe_type = PE_GUI;
|
||||
}
|
||||
|
||||
if (TCC_OUTPUT_MEMORY == s1->output_type && !s1->nostdlib)
|
||||
start_symbol = run_symbol;
|
||||
}
|
||||
|
||||
pe->start_symbol = start_symbol + 1;
|
||||
if (!s1->leading_underscore || strchr(start_symbol, '@'))
|
||||
++start_symbol;
|
||||
if (s1->elf_entryname) {
|
||||
pe->start_symbol = start_symbol = s1->elf_entryname;
|
||||
} else {
|
||||
pe->start_symbol = start_symbol + 1;
|
||||
if (!s1->leading_underscore || strchr(start_symbol, '@'))
|
||||
++start_symbol;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
if (s1->do_backtrace) {
|
||||
@ -2055,8 +2064,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
tcc_add_bcheck(s1);
|
||||
#endif
|
||||
tcc_add_pragma_libs(s1);
|
||||
pe_add_runtime(s1, &pe);
|
||||
tcc_add_pragma_libs(s1);
|
||||
resolve_common_syms(s1);
|
||||
pe_set_options(s1, &pe);
|
||||
pe_check_symbols(&pe);
|
||||
|
11
tccpp.c
11
tccpp.c
@ -3547,11 +3547,7 @@ static void putdefs(CString *cs, const char *p)
|
||||
|
||||
static void tcc_predefs(TCCState *s1, CString *cs, int is_asm)
|
||||
{
|
||||
int a, b, c;
|
||||
|
||||
sscanf(TCC_VERSION, "%d.%d.%d", &a, &b, &c);
|
||||
cstr_printf(cs, "#define __TINYC__ %d\n", a*10000 + b*100 + c);
|
||||
|
||||
cstr_printf(cs, "#define __TINYC__ 9%.2s\n", TCC_VERSION + 4);
|
||||
putdefs(cs, target_machine_defs);
|
||||
putdefs(cs, target_os_defs);
|
||||
|
||||
@ -3742,7 +3738,10 @@ static void tok_print(const int *str, const char *msg, ...)
|
||||
va_list ap;
|
||||
int t, t0, s;
|
||||
CValue cval;
|
||||
va_start(ap, msg), vfprintf(fp, msg, ap), va_end(ap);
|
||||
|
||||
va_start(ap, msg);
|
||||
vfprintf(fp, msg, ap);
|
||||
va_end(ap);
|
||||
|
||||
s = t0 = 0;
|
||||
while (str) {
|
||||
|
4
tccrun.c
4
tccrun.c
@ -179,8 +179,6 @@ ST_FUNC void tcc_run_free(TCCState *s1)
|
||||
dlclose(ref->handle);
|
||||
#endif
|
||||
}
|
||||
/* free loaded dlls array */
|
||||
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
||||
/* unmap or unprotect and free memory */
|
||||
ptr = s1->run_ptr;
|
||||
if (NULL == ptr)
|
||||
@ -854,7 +852,7 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc, bt_info *bi)
|
||||
char *dirs[DIR_TABLE_SIZE];
|
||||
#endif
|
||||
unsigned int filename_size;
|
||||
struct dwarf_filename_struct {
|
||||
struct /*dwarf_filename_struct*/ {
|
||||
unsigned int dir_entry;
|
||||
char *name;
|
||||
} filename_table[FILE_TABLE_SIZE];
|
||||
|
@ -3760,14 +3760,13 @@ void asm_dot_test(void)
|
||||
|
||||
void asm_pcrel_test(void)
|
||||
{
|
||||
#if defined(__i386__)
|
||||
unsigned o1, o2;
|
||||
/* subtract text-section label from forward or other-section label */
|
||||
asm("1: mov $2f-1b,%%eax; mov %%eax,%0" : "=m"(o1));
|
||||
/* verify ... */
|
||||
asm("2: mov $2b,%%eax; sub $1b,%%eax; mov %%eax,%0" : "=m"(o2));
|
||||
asm("2: lea 2b"RX",%eax; lea 1b"RX",%ecx; sub %ecx,%eax");
|
||||
asm("mov %%eax,%0" : "=m"(o2));
|
||||
printf("%s : %x\n", __FUNCTION__, o1 - o2); /* should be zero */
|
||||
#endif
|
||||
}
|
||||
|
||||
void asm_test(void)
|
||||
|
@ -137,6 +137,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f
|
||||
@if _%TCC_C%_==__ goto compiler_2parts
|
||||
@rem if TCC_C was defined then build only tcc.exe
|
||||
%CC% -o tcc.exe %TCC_C% %D%
|
||||
@if errorlevel 1 goto :the_end
|
||||
@goto :compiler_done
|
||||
|
||||
:compiler_2parts
|
||||
@ -144,8 +145,10 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f
|
||||
%CC% -o libtcc.dll -shared %LIBTCC_C% %D% -DLIBTCC_AS_DLL
|
||||
@if errorlevel 1 goto :the_end
|
||||
%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
|
||||
@if errorlevel 1 goto :the_end
|
||||
if not _%XCC%_==_yes_ goto :compiler_done
|
||||
%CC% -o %PX%-tcc.exe ..\tcc.c %DX%
|
||||
@if errorlevel 1 goto :the_end
|
||||
:compiler_done
|
||||
@if (%EXES_ONLY%)==(yes) goto :files_done
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user