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:
grischka 2024-03-11 11:53:46 +01:00
parent 9d2068c630
commit 2b0a663df9
7 changed files with 83 additions and 62 deletions

View File

@ -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);

View File

@ -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
View File

@ -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
View File

@ -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) {

View File

@ -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];

View File

@ -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)

View File

@ -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