mirror of
https://github.com/frida/tinycc
synced 2024-12-29 16:19:40 +03:00
Switch to newer tccpe.c (includes support for resources)
This commit is contained in:
parent
adb1456472
commit
5342b32eef
@ -1,5 +1,6 @@
|
||||
version 0.9.24:
|
||||
|
||||
- Switch to newer tccpe.c (includes support for resources)
|
||||
- Handle backslashes within #include, #error, #warning
|
||||
- Import changesets (part 4) 428,457,460,467: defines for openbsd etc.
|
||||
- Use _WIN32 for a windows hosted tcc and define it for the PE target,
|
||||
|
@ -380,7 +380,7 @@ void gfunc_call(int nb_args)
|
||||
}
|
||||
save_regs(0); /* save used temporary registers */
|
||||
func_sym = vtop->type.ref;
|
||||
func_call = func_sym->r;
|
||||
func_call = FUNC_CALL(func_sym->r);
|
||||
/* fast call case */
|
||||
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
||||
func_call == FUNC_FASTCALLW) {
|
||||
@ -402,7 +402,7 @@ void gfunc_call(int nb_args)
|
||||
}
|
||||
}
|
||||
gcall_or_jmp(0);
|
||||
if (args_size && func_sym->r != FUNC_STDCALL)
|
||||
if (args_size && func_call != FUNC_STDCALL)
|
||||
gadd_sp(args_size);
|
||||
vtop--;
|
||||
}
|
||||
@ -423,7 +423,7 @@ void gfunc_prolog(CType *func_type)
|
||||
CType *type;
|
||||
|
||||
sym = func_type->ref;
|
||||
func_call = sym->r;
|
||||
func_call = FUNC_CALL(sym->r);
|
||||
addr = 8;
|
||||
loc = 0;
|
||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||
|
309
tcc.c
309
tcc.c
@ -40,7 +40,7 @@
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#include <sys/timeb.h>
|
||||
// #include <windows.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
@ -230,10 +230,24 @@ typedef struct AttributeDef {
|
||||
int aligned;
|
||||
int packed;
|
||||
Section *section;
|
||||
unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
|
||||
unsigned char dllexport;
|
||||
int func_attr; /* calling convention, exports, ... */
|
||||
} AttributeDef;
|
||||
|
||||
/* -------------------------------------------------- */
|
||||
/* gr: wrappers for casting sym->r for other purposes */
|
||||
typedef struct {
|
||||
unsigned
|
||||
func_call : 8,
|
||||
func_args : 8,
|
||||
func_export : 1;
|
||||
} func_attr_t;
|
||||
|
||||
#define FUNC_CALL(r) (((func_attr_t*)&(r))->func_call)
|
||||
#define FUNC_EXPORT(r) (((func_attr_t*)&(r))->func_export)
|
||||
#define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args)
|
||||
#define INLINE_DEF(r) (*(int **)&(r))
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
#define SYM_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
||||
#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
|
||||
#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
|
||||
@ -383,6 +397,9 @@ static CType char_pointer_type, func_old_type, int_type;
|
||||
/* true if isid(c) || isnum(c) */
|
||||
static unsigned char isidnum_table[256];
|
||||
|
||||
/* display some information during compilation */
|
||||
static int verbose = 0;
|
||||
|
||||
/* compile with debug symbol (and use them if error during execution) */
|
||||
static int do_debug = 0;
|
||||
|
||||
@ -723,14 +740,6 @@ static const char tcc_keywords[] =
|
||||
#define TOK_UIDENT TOK_DEFINE
|
||||
|
||||
#ifdef _WIN32
|
||||
int __stdcall GetModuleFileNameA(void *, char *, int);
|
||||
void *__stdcall GetProcAddress(void *, const char *);
|
||||
void *__stdcall GetModuleHandleA(const char *);
|
||||
void *__stdcall LoadLibraryA(const char *);
|
||||
int __stdcall FreeConsole(void);
|
||||
int __stdcall VirtualProtect(void*,unsigned long,unsigned long,unsigned long*);
|
||||
#define PAGE_EXECUTE_READWRITE 0x0040
|
||||
|
||||
#define snprintf _snprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#ifndef __GNUC__
|
||||
@ -758,6 +767,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||
static char *pstrcpy(char *buf, int buf_size, const char *s);
|
||||
static char *pstrcat(char *buf, int buf_size, const char *s);
|
||||
static char *tcc_basename(const char *name);
|
||||
static char *tcc_fileextension (const char *p);
|
||||
|
||||
static void next(void);
|
||||
static void next_nomacro(void);
|
||||
@ -858,10 +868,12 @@ int tcc_output_coff(TCCState *s1, FILE *f);
|
||||
|
||||
/* tccpe.c */
|
||||
void *resolve_sym(TCCState *s1, const char *sym, int type);
|
||||
int pe_load_def_file(struct TCCState *s1, FILE *fp);
|
||||
void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
|
||||
unsigned long pe_add_runtime(struct TCCState *s1);
|
||||
int tcc_output_pe(struct TCCState *s1, const char *filename);
|
||||
int pe_load_def_file(struct TCCState *s1, int fd);
|
||||
int pe_test_res_file(void *v, int size);
|
||||
int pe_load_res_file(struct TCCState *s1, int fd);
|
||||
void pe_add_runtime(struct TCCState *s1);
|
||||
void pe_guess_outfile(char *objfilename, int output_type);
|
||||
int pe_output_file(struct TCCState *s1, const char *filename);
|
||||
|
||||
/* tccasm.c */
|
||||
|
||||
@ -1036,6 +1048,27 @@ static int strstart(const char *str, const char *val, const char **ptr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* extract the basename of a file */
|
||||
static char *tcc_basename(const char *name)
|
||||
{
|
||||
char *p = strchr(name, 0);
|
||||
while (p > name
|
||||
&& p[-1] != '/'
|
||||
#ifdef _WIN32
|
||||
&& p[-1] != '\\'
|
||||
#endif
|
||||
)
|
||||
--p;
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *tcc_fileextension (const char *name)
|
||||
{
|
||||
char *b = tcc_basename(name);
|
||||
char *e = strrchr(b, '.');
|
||||
return e ? e : strchr(b, 0);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
char *normalize_slashes(char *path)
|
||||
{
|
||||
@ -1162,6 +1195,16 @@ static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
|
||||
*nb_ptr = nb;
|
||||
}
|
||||
|
||||
static void dynarray_reset(void *pp, int *n)
|
||||
{
|
||||
void **p;
|
||||
for (p = *(void***)pp; *n; ++p, --*n)
|
||||
if (*p)
|
||||
tcc_free(*p);
|
||||
tcc_free(*(void**)pp);
|
||||
*(void**)pp = NULL;
|
||||
}
|
||||
|
||||
/* symbol allocator */
|
||||
static Sym *__sym_malloc(void)
|
||||
{
|
||||
@ -1291,7 +1334,7 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
||||
unsigned long value, unsigned long size,
|
||||
int can_add_underscore)
|
||||
{
|
||||
int sym_type, sym_bind, sh_num, info;
|
||||
int sym_type, sym_bind, sh_num, info, other, attr;
|
||||
Elf32_Sym *esym;
|
||||
const char *name;
|
||||
char buf1[256];
|
||||
@ -1302,16 +1345,29 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
||||
sh_num = SHN_ABS;
|
||||
else
|
||||
sh_num = section->sh_num;
|
||||
if (!sym->c) {
|
||||
if ((sym->type.t & VT_BTYPE) == VT_FUNC)
|
||||
sym_type = STT_FUNC;
|
||||
else
|
||||
sym_type = STT_OBJECT;
|
||||
if (sym->type.t & VT_STATIC)
|
||||
sym_bind = STB_LOCAL;
|
||||
else
|
||||
sym_bind = STB_GLOBAL;
|
||||
|
||||
other = attr = 0;
|
||||
|
||||
if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
|
||||
sym_type = STT_FUNC;
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (sym->type.ref)
|
||||
attr = sym->type.ref->r;
|
||||
if (FUNC_EXPORT(attr))
|
||||
other |= 1;
|
||||
if (FUNC_CALL(attr) == FUNC_STDCALL)
|
||||
other |= 2;
|
||||
#endif
|
||||
} else {
|
||||
sym_type = STT_OBJECT;
|
||||
}
|
||||
|
||||
if (sym->type.t & VT_STATIC)
|
||||
sym_bind = STB_LOCAL;
|
||||
else
|
||||
sym_bind = STB_GLOBAL;
|
||||
|
||||
if (!sym->c) {
|
||||
name = get_tok_str(sym->v, NULL);
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
if (do_bounds_check) {
|
||||
@ -1342,18 +1398,26 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TCC_TARGET_PE
|
||||
if ((other & 2) && can_add_underscore) {
|
||||
sprintf(buf1, "_%s@%d", name, FUNC_ARGS(attr));
|
||||
name = buf1;
|
||||
} else
|
||||
#endif
|
||||
if (tcc_state->leading_underscore && can_add_underscore) {
|
||||
buf1[0] = '_';
|
||||
pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
|
||||
name = buf1;
|
||||
}
|
||||
info = ELF32_ST_INFO(sym_bind, sym_type);
|
||||
sym->c = add_elf_sym(symtab_section, value, size, info, 0, sh_num, name);
|
||||
sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
|
||||
} else {
|
||||
esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
|
||||
esym->st_value = value;
|
||||
esym->st_size = size;
|
||||
esym->st_shndx = sh_num;
|
||||
esym->st_other |= other;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2868,7 +2932,7 @@ static void preprocess(int is_bof)
|
||||
{
|
||||
TCCState *s1 = tcc_state;
|
||||
int size, i, c, n, saved_parse_flags;
|
||||
char buf[1024], *q, *p;
|
||||
char buf[1024], *q;
|
||||
char buf1[1024];
|
||||
BufferedFile *f;
|
||||
Sym *s;
|
||||
@ -2962,10 +3026,7 @@ static void preprocess(int is_bof)
|
||||
} else {
|
||||
if (c == '\"') {
|
||||
/* first search in current dir if "header.h" */
|
||||
size = 0;
|
||||
p = strrchr(file->filename, '/');
|
||||
if (p)
|
||||
size = p + 1 - file->filename;
|
||||
size = tcc_basename(file->filename) - file->filename;
|
||||
if (size > sizeof(buf1) - 1)
|
||||
size = sizeof(buf1) - 1;
|
||||
memcpy(buf1, file->filename, size);
|
||||
@ -4026,7 +4087,9 @@ static int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
||||
cstr_ccat(&cstr, ' ');
|
||||
TOK_GET(t, st, cval);
|
||||
cstr_cat(&cstr, get_tok_str(t, &cval));
|
||||
#ifndef PP_NOSPACES
|
||||
notfirst = 1;
|
||||
#endif
|
||||
}
|
||||
cstr_ccat(&cstr, '\0');
|
||||
#ifdef PP_DEBUG
|
||||
@ -6112,7 +6175,7 @@ static int is_compatible_func(CType *type1, CType *type2)
|
||||
if (!is_compatible_types(&s1->type, &s2->type))
|
||||
return 0;
|
||||
/* check func_call */
|
||||
if (s1->r != s2->r)
|
||||
if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
|
||||
return 0;
|
||||
/* XXX: not complete */
|
||||
if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
|
||||
@ -6569,12 +6632,12 @@ static void parse_attribute(AttributeDef *ad)
|
||||
case TOK_CDECL1:
|
||||
case TOK_CDECL2:
|
||||
case TOK_CDECL3:
|
||||
ad->func_call = FUNC_CDECL;
|
||||
FUNC_CALL(ad->func_attr) = FUNC_CDECL;
|
||||
break;
|
||||
case TOK_STDCALL1:
|
||||
case TOK_STDCALL2:
|
||||
case TOK_STDCALL3:
|
||||
ad->func_call = FUNC_STDCALL;
|
||||
FUNC_CALL(ad->func_attr) = FUNC_STDCALL;
|
||||
break;
|
||||
#ifdef TCC_TARGET_I386
|
||||
case TOK_REGPARM1:
|
||||
@ -6586,17 +6649,17 @@ static void parse_attribute(AttributeDef *ad)
|
||||
else if (n < 0)
|
||||
n = 0;
|
||||
if (n > 0)
|
||||
ad->func_call = FUNC_FASTCALL1 + n - 1;
|
||||
FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1;
|
||||
skip(')');
|
||||
break;
|
||||
case TOK_FASTCALL1:
|
||||
case TOK_FASTCALL2:
|
||||
case TOK_FASTCALL3:
|
||||
ad->func_call = FUNC_FASTCALLW;
|
||||
FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW;
|
||||
break;
|
||||
#endif
|
||||
case TOK_DLLEXPORT:
|
||||
ad->dllexport = 1;
|
||||
FUNC_EXPORT(ad->func_attr) = 1;
|
||||
break;
|
||||
default:
|
||||
if (tcc_state->warn_unsupported)
|
||||
@ -6979,7 +7042,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
||||
}
|
||||
the_end:
|
||||
if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED))
|
||||
error("signed and unsigned modifier");
|
||||
error("signed and unsigned modifier");
|
||||
if (tcc_state->char_is_unsigned) {
|
||||
if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
|
||||
t |= VT_UNSIGNED;
|
||||
@ -7009,7 +7072,7 @@ static inline void convert_parameter_type(CType *pt)
|
||||
|
||||
static void post_type(CType *type, AttributeDef *ad)
|
||||
{
|
||||
int n, l, t1;
|
||||
int n, l, t1, arg_size, align;
|
||||
Sym **plast, *s, *first;
|
||||
AttributeDef ad1;
|
||||
CType pt;
|
||||
@ -7020,6 +7083,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||
l = 0;
|
||||
first = NULL;
|
||||
plast = &first;
|
||||
arg_size = 0;
|
||||
if (tok != ')') {
|
||||
for(;;) {
|
||||
/* read param name and compute offset */
|
||||
@ -7038,6 +7102,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||
type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
|
||||
if ((pt.t & VT_BTYPE) == VT_VOID)
|
||||
error("parameter declared as void");
|
||||
arg_size += (type_size(&pt, &align) + 3) & ~3;
|
||||
} else {
|
||||
old_proto:
|
||||
n = tok;
|
||||
@ -7070,7 +7135,8 @@ static void post_type(CType *type, AttributeDef *ad)
|
||||
type->t &= ~(VT_STORAGE | VT_CONSTANT);
|
||||
post_type(type, ad);
|
||||
/* we push a anonymous symbol which will contain the function prototype */
|
||||
s = sym_push(SYM_FIELD, type, ad->func_call, l);
|
||||
FUNC_ARGS(ad->func_attr) = arg_size;
|
||||
s = sym_push(SYM_FIELD, type, ad->func_attr, l);
|
||||
s->next = first;
|
||||
type->t = t1 | VT_FUNC;
|
||||
type->ref = s;
|
||||
@ -7629,6 +7695,7 @@ static void unary(void)
|
||||
next();
|
||||
sa = s->next; /* first parameter */
|
||||
nb_args = 0;
|
||||
ret.r2 = VT_CONST;
|
||||
/* compute first implicit argument if a structure is returned */
|
||||
if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||
/* get some space for the returned structure */
|
||||
@ -7643,7 +7710,6 @@ static void unary(void)
|
||||
nb_args++;
|
||||
} else {
|
||||
ret.type = s->type;
|
||||
ret.r2 = VT_CONST;
|
||||
/* return in register */
|
||||
if (is_float(ret.type.t)) {
|
||||
ret.r = REG_FRET;
|
||||
@ -8660,12 +8726,11 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
||||
them as ((w)char *) expressions */
|
||||
if ((tok == TOK_LSTR &&
|
||||
#ifdef TCC_TARGET_PE
|
||||
(t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)) ||
|
||||
(t1->t & VT_BTYPE) == VT_SHORT && (t1->t & VT_UNSIGNED)
|
||||
#else
|
||||
(t1->t & VT_BTYPE) == VT_INT) ||
|
||||
(t1->t & VT_BTYPE) == VT_INT
|
||||
#endif
|
||||
(tok == TOK_STR &&
|
||||
(t1->t & VT_BTYPE) == VT_BYTE)) {
|
||||
) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
|
||||
while (tok == TOK_STR || tok == TOK_LSTR) {
|
||||
int cstr_len, ch;
|
||||
CString *cstr;
|
||||
@ -9166,9 +9231,9 @@ static void gen_inline_functions(void)
|
||||
sym->c != 0) {
|
||||
/* the function was used: generate its code and
|
||||
convert it to a normal function */
|
||||
str = (int *)sym->r;
|
||||
str = INLINE_DEF(sym->r);
|
||||
sym->r = VT_SYM | VT_CONST;
|
||||
type->t &= ~VT_INLINE;
|
||||
sym->type.t &= ~VT_INLINE;
|
||||
|
||||
macro_ptr = str;
|
||||
next();
|
||||
@ -9190,7 +9255,10 @@ static void gen_inline_functions(void)
|
||||
if (((type->t & VT_BTYPE) == VT_FUNC) &&
|
||||
(type->t & (VT_STATIC | VT_INLINE)) ==
|
||||
(VT_STATIC | VT_INLINE)) {
|
||||
str = (int *)sym->r;
|
||||
//gr printf("sym %d %s\n", sym->r, get_tok_str(sym->v, NULL));
|
||||
if (sym->r == (VT_SYM | VT_CONST)) //gr beware!
|
||||
continue;
|
||||
str = INLINE_DEF(sym->r);
|
||||
tok_str_free(str);
|
||||
sym->r = 0; /* fail safe */
|
||||
}
|
||||
@ -9273,9 +9341,13 @@ static void decl(int l)
|
||||
/* specific case: if not func_call defined, we put
|
||||
the one of the prototype */
|
||||
/* XXX: should have default value */
|
||||
if (sym->type.ref->r != FUNC_CDECL &&
|
||||
type.ref->r == FUNC_CDECL)
|
||||
type.ref->r = sym->type.ref->r;
|
||||
r = sym->type.ref->r;
|
||||
if (FUNC_CALL(r) != FUNC_CDECL
|
||||
&& FUNC_CALL(type.ref->r) == FUNC_CDECL)
|
||||
FUNC_CALL(type.ref->r) = FUNC_CALL(r);
|
||||
if (FUNC_EXPORT(r))
|
||||
FUNC_EXPORT(type.ref->r) = 1;
|
||||
|
||||
if (!is_compatible_types(&sym->type, &type)) {
|
||||
func_error1:
|
||||
error("incompatible types for redefinition of '%s'",
|
||||
@ -9317,7 +9389,7 @@ static void decl(int l)
|
||||
}
|
||||
tok_str_add(&func_str, -1);
|
||||
tok_str_add(&func_str, 0);
|
||||
sym->r = (int)func_str.str;
|
||||
INLINE_DEF(sym->r) = func_str.str;
|
||||
} else {
|
||||
/* compute text section */
|
||||
cur_text_section = ad.section;
|
||||
@ -9325,11 +9397,6 @@ static void decl(int l)
|
||||
cur_text_section = text_section;
|
||||
sym->r = VT_SYM | VT_CONST;
|
||||
gen_function(sym);
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (ad.dllexport) {
|
||||
((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
@ -9341,8 +9408,8 @@ static void decl(int l)
|
||||
} else if ((type.t & VT_BTYPE) == VT_FUNC) {
|
||||
/* external function definition */
|
||||
/* specific case for func_call attribute */
|
||||
if (ad.func_call)
|
||||
type.ref->r = ad.func_call;
|
||||
if (ad.func_attr)
|
||||
type.ref->r = ad.func_attr;
|
||||
external_sym(v, &type, 0);
|
||||
} else {
|
||||
/* not lvalue if array */
|
||||
@ -9891,9 +9958,9 @@ int tcc_relocate(TCCState *s1)
|
||||
relocate_common_syms();
|
||||
|
||||
tcc_add_linker_symbols(s1);
|
||||
|
||||
#ifndef TCC_TARGET_PE
|
||||
build_got_entries(s1);
|
||||
|
||||
#endif
|
||||
/* compute relocation address : section are relocated in place. We
|
||||
also alloc the bss space */
|
||||
for(i = 1; i < s1->nb_sections; i++) {
|
||||
@ -10118,27 +10185,15 @@ void tcc_delete(TCCState *s1)
|
||||
tcc_free(s1->sections);
|
||||
|
||||
/* free loaded dlls array */
|
||||
for(i = 0; i < s1->nb_loaded_dlls; i++)
|
||||
tcc_free(s1->loaded_dlls[i]);
|
||||
tcc_free(s1->loaded_dlls);
|
||||
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
||||
|
||||
/* library paths */
|
||||
for(i = 0; i < s1->nb_library_paths; i++)
|
||||
tcc_free(s1->library_paths[i]);
|
||||
tcc_free(s1->library_paths);
|
||||
/* free library paths */
|
||||
dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
|
||||
|
||||
/* cached includes */
|
||||
for(i = 0; i < s1->nb_cached_includes; i++)
|
||||
tcc_free(s1->cached_includes[i]);
|
||||
tcc_free(s1->cached_includes);
|
||||
|
||||
for(i = 0; i < s1->nb_include_paths; i++)
|
||||
tcc_free(s1->include_paths[i]);
|
||||
tcc_free(s1->include_paths);
|
||||
|
||||
for(i = 0; i < s1->nb_sysinclude_paths; i++)
|
||||
tcc_free(s1->sysinclude_paths[i]);
|
||||
tcc_free(s1->sysinclude_paths);
|
||||
/* free include paths */
|
||||
dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
|
||||
dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
|
||||
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
|
||||
|
||||
tcc_free(s1);
|
||||
}
|
||||
@ -10163,19 +10218,14 @@ int tcc_add_sysinclude_path(TCCState *s1, const char *pathname)
|
||||
|
||||
static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
{
|
||||
const char *ext, *filename1;
|
||||
const char *ext;
|
||||
Elf32_Ehdr ehdr;
|
||||
int fd, ret;
|
||||
BufferedFile *saved_file;
|
||||
|
||||
/* find source file type with extension */
|
||||
filename1 = strrchr(filename, '/');
|
||||
if (filename1)
|
||||
filename1++;
|
||||
else
|
||||
filename1 = filename;
|
||||
ext = strrchr(filename1, '.');
|
||||
if (ext)
|
||||
ext = tcc_fileextension(filename);
|
||||
if (ext[0])
|
||||
ext++;
|
||||
|
||||
/* open the file */
|
||||
@ -10191,7 +10241,7 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
|
||||
if (flags & AFF_PREPROCESS) {
|
||||
ret = tcc_preprocess(s1);
|
||||
} else if (!ext || !strcmp(ext, "c")) {
|
||||
} else if (!ext[0] || !strcmp(ext, "c")) {
|
||||
/* C file assumed */
|
||||
ret = tcc_compile(s1);
|
||||
} else
|
||||
@ -10206,7 +10256,7 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
#endif
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (!strcmp(ext, "def")) {
|
||||
ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
|
||||
ret = pe_load_def_file(s1, file->fd);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -10256,6 +10306,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||
if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
|
||||
ret = tcc_load_coff(s1, fd);
|
||||
} else
|
||||
#endif
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (pe_test_res_file(&ehdr, ret)) {
|
||||
ret = pe_load_res_file(s1, fd);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* as GNU ld, consider it is an ld script if not recognized */
|
||||
@ -10478,20 +10533,6 @@ int tcc_set_flag(TCCState *s, const char *flag_name, int value)
|
||||
flag_name, value);
|
||||
}
|
||||
|
||||
/* extract the basename of a file */
|
||||
static char *tcc_basename(const char *name)
|
||||
{
|
||||
char *p = strchr(name, 0);
|
||||
while (p > name
|
||||
&& p[-1] != '/'
|
||||
#ifdef _WIN32
|
||||
&& p[-1] != '\\'
|
||||
#endif
|
||||
)
|
||||
--p;
|
||||
return p;
|
||||
}
|
||||
|
||||
#if !defined(LIBTCC)
|
||||
|
||||
static int64_t getclock_us(void)
|
||||
@ -10535,7 +10576,7 @@ void help(void)
|
||||
" -shared generate a shared library\n"
|
||||
" -static static linking\n"
|
||||
" -rdynamic export all global symbols to dynamic linker\n"
|
||||
" -r relocatable output\n"
|
||||
" -r generate (relocatable) object file\n"
|
||||
"Debugger options:\n"
|
||||
" -g generate runtime debug info\n"
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
@ -10885,6 +10926,7 @@ int main(int argc, char **argv)
|
||||
nb_libraries = 0;
|
||||
reloc_output = 0;
|
||||
print_search_dirs = 0;
|
||||
ret = 0;
|
||||
|
||||
optind = parse_args(s, argc - 1, argv + 1) + 1;
|
||||
|
||||
@ -10915,30 +10957,28 @@ int main(int argc, char **argv)
|
||||
if (!outfile) {
|
||||
s->outfile = stdout;
|
||||
} else {
|
||||
s->outfile = fopen(outfile, "wb");
|
||||
s->outfile = fopen(outfile, "w");
|
||||
if (!s->outfile)
|
||||
error("could not open '%s", outfile);
|
||||
}
|
||||
} else if (output_type != TCC_OUTPUT_MEMORY) {
|
||||
if (!outfile) {
|
||||
/* compute default outfile name */
|
||||
pstrcpy(objfilename, sizeof(objfilename) - 1,
|
||||
/* strip path */
|
||||
tcc_basename(files[0]));
|
||||
char *ext;
|
||||
pstrcpy(objfilename, sizeof(objfilename), tcc_basename(files[0]));
|
||||
ext = tcc_fileextension(objfilename);
|
||||
#ifdef TCC_TARGET_PE
|
||||
pe_guess_outfile(objfilename, output_type);
|
||||
#else
|
||||
if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
|
||||
char *ext = strrchr(objfilename, '.');
|
||||
if (!ext)
|
||||
goto default_outfile;
|
||||
/* add .o extension */
|
||||
strcpy(ext + 1, "o");
|
||||
} else {
|
||||
default_outfile:
|
||||
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
||||
}
|
||||
if (output_type == TCC_OUTPUT_DLL)
|
||||
strcpy(ext, ".dll");
|
||||
else
|
||||
if (output_type == TCC_OUTPUT_EXE)
|
||||
strcpy(ext, ".exe");
|
||||
else
|
||||
#endif
|
||||
if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext)
|
||||
strcpy(ext, ".o");
|
||||
else
|
||||
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
||||
outfile = objfilename;
|
||||
}
|
||||
}
|
||||
@ -10950,29 +10990,29 @@ int main(int argc, char **argv)
|
||||
tcc_set_output_type(s, output_type);
|
||||
|
||||
/* compile or add each files or library */
|
||||
for(i = 0;i < nb_files; i++) {
|
||||
for(i = 0; i < nb_files && ret == 0; i++) {
|
||||
const char *filename;
|
||||
|
||||
filename = files[i];
|
||||
if (output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
tcc_add_file_internal(s, filename,
|
||||
AFF_PRINT_ERROR | AFF_PREPROCESS);
|
||||
if (tcc_add_file_internal(s, filename,
|
||||
AFF_PRINT_ERROR | AFF_PREPROCESS) < 0)
|
||||
ret = 1;
|
||||
} else if (filename[0] == '-') {
|
||||
if (tcc_add_library(s, filename + 2) < 0)
|
||||
error("cannot find %s", filename);
|
||||
} else {
|
||||
if (filename[0] == '-') {
|
||||
if (tcc_add_library(s, filename + 2) < 0)
|
||||
error("cannot find %s", filename);
|
||||
} else {
|
||||
if (tcc_add_file(s, filename) < 0) {
|
||||
ret = 1;
|
||||
goto the_end;
|
||||
}
|
||||
}
|
||||
if (tcc_add_file(s, filename) < 0)
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* free all files */
|
||||
tcc_free(files);
|
||||
|
||||
if (ret)
|
||||
goto the_end;
|
||||
|
||||
if (do_bench) {
|
||||
double total_time;
|
||||
total_time = (double)(getclock_us() - start_time) / 1000000.0;
|
||||
@ -10989,13 +11029,12 @@ int main(int argc, char **argv)
|
||||
if (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||
if (outfile)
|
||||
fclose(s->outfile);
|
||||
ret = 0;
|
||||
} else if (s->output_type == TCC_OUTPUT_MEMORY) {
|
||||
ret = tcc_run(s, argc - optind, argv + optind);
|
||||
} else
|
||||
#ifdef TCC_TARGET_PE
|
||||
if (s->output_type != TCC_OUTPUT_OBJ) {
|
||||
ret = tcc_output_pe(s, outfile);
|
||||
ret = pe_output_file(s, outfile);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
161
tccelf.c
161
tccelf.c
@ -531,11 +531,11 @@ static void relocate_section(TCCState *s1, Section *s)
|
||||
*(int *)ptr += s1->got_offsets[sym_index];
|
||||
break;
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_CALL:
|
||||
case R_ARM_JUMP24:
|
||||
case R_ARM_PLT32:
|
||||
{
|
||||
case R_ARM_PC24:
|
||||
case R_ARM_CALL:
|
||||
case R_ARM_JUMP24:
|
||||
case R_ARM_PLT32:
|
||||
{
|
||||
int x;
|
||||
x = (*(int *)ptr)&0xffffff;
|
||||
(*(int *)ptr) &= 0xff000000;
|
||||
@ -548,42 +548,42 @@ static void relocate_section(TCCState *s1, Section *s)
|
||||
x >>= 2;
|
||||
x &= 0xffffff;
|
||||
(*(int *)ptr) |= x;
|
||||
}
|
||||
break;
|
||||
case R_ARM_PREL31:
|
||||
{
|
||||
int x;
|
||||
x = (*(int *)ptr) & 0x7fffffff;
|
||||
(*(int *)ptr) &= 0x80000000;
|
||||
x = (x * 2) / 2;
|
||||
x += val - addr;
|
||||
if((x^(x>>1))&0x40000000)
|
||||
error("can't relocate value at %x",addr);
|
||||
(*(int *)ptr) |= x & 0x7fffffff;
|
||||
}
|
||||
case R_ARM_ABS32:
|
||||
*(int *)ptr += val;
|
||||
break;
|
||||
case R_ARM_BASE_PREL:
|
||||
*(int *)ptr += s1->got->sh_addr - addr;
|
||||
break;
|
||||
case R_ARM_GOTOFF32:
|
||||
}
|
||||
break;
|
||||
case R_ARM_PREL31:
|
||||
{
|
||||
int x;
|
||||
x = (*(int *)ptr) & 0x7fffffff;
|
||||
(*(int *)ptr) &= 0x80000000;
|
||||
x = (x * 2) / 2;
|
||||
x += val - addr;
|
||||
if((x^(x>>1))&0x40000000)
|
||||
error("can't relocate value at %x",addr);
|
||||
(*(int *)ptr) |= x & 0x7fffffff;
|
||||
}
|
||||
case R_ARM_ABS32:
|
||||
*(int *)ptr += val;
|
||||
break;
|
||||
case R_ARM_BASE_PREL:
|
||||
*(int *)ptr += s1->got->sh_addr - addr;
|
||||
break;
|
||||
case R_ARM_GOTOFF32:
|
||||
*(int *)ptr += val - s1->got->sh_addr;
|
||||
break;
|
||||
case R_ARM_GOT_BREL:
|
||||
/* we load the got offset */
|
||||
*(int *)ptr += s1->got_offsets[sym_index];
|
||||
break;
|
||||
case R_ARM_COPY:
|
||||
case R_ARM_COPY:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
|
||||
default:
|
||||
fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
|
||||
type,addr,(unsigned int )ptr,val);
|
||||
break;
|
||||
#elif defined(TCC_TARGET_C67)
|
||||
case R_C60_32:
|
||||
*(int *)ptr += val;
|
||||
break;
|
||||
case R_C60_32:
|
||||
*(int *)ptr += val;
|
||||
break;
|
||||
case R_C60LO16:
|
||||
{
|
||||
uint32_t orig;
|
||||
@ -603,7 +603,7 @@ static void relocate_section(TCCState *s1, Section *s)
|
||||
case R_C60HI16:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
|
||||
fprintf(stderr,"FIXME: handle reloc type %x at %lx [%.8x] to %lx\n",
|
||||
type,addr,(unsigned int )ptr,val);
|
||||
break;
|
||||
#else
|
||||
@ -784,7 +784,7 @@ static void put_got_entry(TCCState *s1,
|
||||
offset = plt->data_offset - 16;
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
if (reloc_type == R_ARM_JUMP_SLOT) {
|
||||
if (reloc_type == R_ARM_JUMP_SLOT) {
|
||||
Section *plt;
|
||||
uint8_t *p;
|
||||
|
||||
@ -797,17 +797,17 @@ static void put_got_entry(TCCState *s1,
|
||||
if (plt->data_offset == 0) {
|
||||
/* first plt entry */
|
||||
p = section_ptr_add(plt, 16);
|
||||
put32(p , 0xe52de004);
|
||||
put32(p + 4, 0xe59fe010);
|
||||
put32(p + 8, 0xe08fe00e);
|
||||
put32(p + 12, 0xe5bef008);
|
||||
put32(p , 0xe52de004);
|
||||
put32(p + 4, 0xe59fe010);
|
||||
put32(p + 8, 0xe08fe00e);
|
||||
put32(p + 12, 0xe5bef008);
|
||||
}
|
||||
|
||||
p = section_ptr_add(plt, 16);
|
||||
put32(p , 0xe59fc004);
|
||||
put32(p+4, 0xe08fc00c);
|
||||
put32(p+8, 0xe59cf000);
|
||||
put32(p+12, s1->got->data_offset);
|
||||
put32(p , 0xe59fc004);
|
||||
put32(p+4, 0xe08fc00c);
|
||||
put32(p+8, 0xe59cf000);
|
||||
put32(p+12, s1->got->data_offset);
|
||||
|
||||
/* the symbol is modified so that it will be relocated to
|
||||
the PLT */
|
||||
@ -872,7 +872,7 @@ static void build_got_entries(TCCState *s1)
|
||||
}
|
||||
break;
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
case R_ARM_GOT_BREL:
|
||||
case R_ARM_GOT_BREL:
|
||||
case R_ARM_GOTOFF32:
|
||||
case R_ARM_BASE_PREL:
|
||||
case R_ARM_PLT32:
|
||||
@ -891,7 +891,7 @@ static void build_got_entries(TCCState *s1)
|
||||
}
|
||||
break;
|
||||
#elif defined(TCC_TARGET_C67)
|
||||
case R_C60_GOT32:
|
||||
case R_C60_GOT32:
|
||||
case R_C60_GOTOFF:
|
||||
case R_C60_GOTPC:
|
||||
case R_C60_PLT32:
|
||||
@ -1547,13 +1547,13 @@ int tcc_output_file(TCCState *s1, const char *filename)
|
||||
p += 16;
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM)
|
||||
int x;
|
||||
x=s1->got->sh_addr - s1->plt->sh_addr - 12;
|
||||
p +=16;
|
||||
while (p < p_end) {
|
||||
put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
|
||||
p += 16;
|
||||
}
|
||||
int x;
|
||||
x=s1->got->sh_addr - s1->plt->sh_addr - 12;
|
||||
p +=16;
|
||||
while (p < p_end) {
|
||||
put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
|
||||
p += 16;
|
||||
}
|
||||
#elif defined(TCC_TARGET_C67)
|
||||
/* XXX: TODO */
|
||||
#else
|
||||
@ -1682,8 +1682,8 @@ int tcc_output_file(TCCState *s1, const char *filename)
|
||||
#endif
|
||||
#ifdef TCC_TARGET_ARM
|
||||
#ifdef TCC_ARM_EABI
|
||||
ehdr.e_ident[EI_OSABI] = 0;
|
||||
ehdr.e_flags = 4 << 24;
|
||||
ehdr.e_ident[EI_OSABI] = 0;
|
||||
ehdr.e_flags = 4 << 24;
|
||||
#else
|
||||
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
|
||||
#endif
|
||||
@ -1859,7 +1859,7 @@ static int tcc_load_object_file(TCCState *s1,
|
||||
if (sh->sh_type != SHT_PROGBITS &&
|
||||
sh->sh_type != SHT_REL &&
|
||||
#ifdef TCC_ARM_EABI
|
||||
sh->sh_type != SHT_ARM_EXIDX &&
|
||||
sh->sh_type != SHT_ARM_EXIDX &&
|
||||
#endif
|
||||
sh->sh_type != SHT_NOBITS)
|
||||
continue;
|
||||
@ -2022,16 +2022,16 @@ static int tcc_load_object_file(TCCState *s1,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
|
||||
#define ARMAG "!<arch>\012" /* For COFF and a.out archives */
|
||||
|
||||
typedef struct ArchiveHeader {
|
||||
char ar_name[16]; /* name of this member */
|
||||
char ar_date[12]; /* file mtime */
|
||||
char ar_uid[6]; /* owner uid; printed as decimal */
|
||||
char ar_gid[6]; /* owner gid; printed as decimal */
|
||||
char ar_mode[8]; /* file mode, printed as octal */
|
||||
char ar_size[10]; /* file size, printed as decimal */
|
||||
char ar_fmag[2]; /* should contain ARFMAG */
|
||||
char ar_name[16]; /* name of this member */
|
||||
char ar_date[12]; /* file mtime */
|
||||
char ar_uid[6]; /* owner uid; printed as decimal */
|
||||
char ar_gid[6]; /* owner gid; printed as decimal */
|
||||
char ar_mode[8]; /* file mode, printed as octal */
|
||||
char ar_size[10]; /* file size, printed as decimal */
|
||||
char ar_fmag[2]; /* should contain ARFMAG */
|
||||
} ArchiveHeader;
|
||||
|
||||
static int get_be32(const uint8_t *b)
|
||||
@ -2056,26 +2056,26 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
|
||||
ar_names = ar_index + nsyms * 4;
|
||||
|
||||
do {
|
||||
bound = 0;
|
||||
for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
|
||||
sym_index = find_elf_sym(symtab_section, p);
|
||||
if(sym_index) {
|
||||
sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
|
||||
if(sym->st_shndx == SHN_UNDEF) {
|
||||
off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
|
||||
bound = 0;
|
||||
for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
|
||||
sym_index = find_elf_sym(symtab_section, p);
|
||||
if(sym_index) {
|
||||
sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
|
||||
if(sym->st_shndx == SHN_UNDEF) {
|
||||
off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
|
||||
#if 0
|
||||
printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
|
||||
printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
|
||||
#endif
|
||||
++bound;
|
||||
lseek(fd, off, SEEK_SET);
|
||||
if(tcc_load_object_file(s1, fd, off) < 0) {
|
||||
++bound;
|
||||
lseek(fd, off, SEEK_SET);
|
||||
if(tcc_load_object_file(s1, fd, off) < 0) {
|
||||
fail:
|
||||
ret = -1;
|
||||
goto the_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(bound);
|
||||
ret = 0;
|
||||
the_end:
|
||||
@ -2119,8 +2119,8 @@ static int tcc_load_archive(TCCState *s1, int fd)
|
||||
size = (size + 1) & ~1;
|
||||
if (!strcmp(ar_name, "/")) {
|
||||
/* coff symbol table : we handle it */
|
||||
if(s1->alacarte_link)
|
||||
return tcc_load_alacarte(s1, fd, size);
|
||||
if(s1->alacarte_link)
|
||||
return tcc_load_alacarte(s1, fd, size);
|
||||
} else if (!strcmp(ar_name, "//") ||
|
||||
!strcmp(ar_name, "__.SYMDEF") ||
|
||||
!strcmp(ar_name, "__.SYMDEF/") ||
|
||||
@ -2146,7 +2146,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
||||
Elf32_Sym *sym, *dynsym;
|
||||
Elf32_Dyn *dt, *dynamic;
|
||||
unsigned char *dynstr;
|
||||
const char *name, *soname, *p;
|
||||
const char *name, *soname;
|
||||
DLLReference *dllref;
|
||||
|
||||
read(fd, &ehdr, sizeof(ehdr));
|
||||
@ -2185,10 +2185,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
||||
}
|
||||
|
||||
/* compute the real library name */
|
||||
soname = filename;
|
||||
p = strrchr(soname, '/');
|
||||
if (p)
|
||||
soname = p + 1;
|
||||
soname = tcc_basename(filename);
|
||||
|
||||
for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
|
||||
if (dt->d_tag == DT_SONAME) {
|
||||
|
155
win32/readme.txt
155
win32/readme.txt
@ -1,115 +1,126 @@
|
||||
|
||||
TinyCC-PE
|
||||
---------
|
||||
TinyCC-PE
|
||||
---------
|
||||
|
||||
TinyCC (aka TCC) is a small but hyperfast C compiler,
|
||||
written by Fabrice Bellard,
|
||||
TinyCC (aka TCC) is a small but hyperfast C compiler,
|
||||
written by Fabrice Bellard,
|
||||
|
||||
|
||||
TinyCC-PE is the TinyCC compiler with an extension to
|
||||
write PE executables for MS-Windows.
|
||||
TinyCC-PE is the TinyCC compiler with an extension to
|
||||
write PE executables for MS-Windows.
|
||||
|
||||
|
||||
Features:
|
||||
---------
|
||||
Features:
|
||||
---------
|
||||
|
||||
TinyCC-PE can produce console applications, native windows
|
||||
GUI programs and DLL's.
|
||||
TinyCC-PE can produce console applications, native windows
|
||||
GUI programs and DLL's.
|
||||
|
||||
Most of the features pointed out by Fabrice Bellard for the
|
||||
original version are still valid, i.e:
|
||||
Most of the features pointed out by Fabrice Bellard for the
|
||||
original version are still valid, i.e:
|
||||
|
||||
- SMALL! The package with ~400kb includes a complete C-compiler
|
||||
with header files for console and GUI applications.
|
||||
- SMALL! The package with ~400kb includes a complete C-compiler
|
||||
with header files for console and GUI applications.
|
||||
|
||||
- With the -run switch you can run C-sources without any
|
||||
linking directly from the command line.
|
||||
- With the -run switch you can run C-sources without any
|
||||
linking directly from the command line.
|
||||
|
||||
- TCC can of course compile itself.
|
||||
- TCC can of course compile itself.
|
||||
|
||||
|
||||
Compilation: (omit that if you use the binary ZIP package)
|
||||
------------
|
||||
Compilation: (omit that if you use the binary ZIP package)
|
||||
------------
|
||||
|
||||
You must use the MinGW and MSYS tools available at
|
||||
http://www.mingw.org to compile TCC for Windows. Untar the TCC
|
||||
archive and type in the MSYS shell:
|
||||
You must use the MinGW and MSYS tools available at
|
||||
http://www.mingw.org to compile TCC for Windows. Untar the TCC
|
||||
archive and type in the MSYS shell:
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
TCC is installed in c:\Program Files\tcc
|
||||
TCC is installed in c:\Program Files\tcc
|
||||
|
||||
Installation: (from the binary ZIP package)
|
||||
-------------
|
||||
|
||||
Just unzip the package to a directory anywhere on your computer.
|
||||
Alternatively you can use win32\build-tcc.bat to compile TCC
|
||||
with just gcc and ar from MINGW. To install, copy the entire
|
||||
contents of the win32 directory to where you want.
|
||||
|
||||
|
||||
Examples:
|
||||
---------
|
||||
Installation: (from the binary ZIP package)
|
||||
-------------
|
||||
|
||||
For the 'Fibonacci' console example type from the command line:
|
||||
|
||||
tcc examples\fib.c
|
||||
Just unzip the package to a directory anywhere on your computer.
|
||||
|
||||
|
||||
For the 'Hello Windows' GUI example:
|
||||
Examples:
|
||||
---------
|
||||
|
||||
tcc examples\hello_win.c
|
||||
For the 'Fibonacci' console example type from the command line:
|
||||
|
||||
tcc examples\fib.c
|
||||
|
||||
For the 'Hello Windows' GUI example:
|
||||
|
||||
tcc examples\hello_win.c
|
||||
|
||||
For the 'Hello DLL' example:
|
||||
|
||||
tcc -shared examples\dll.c
|
||||
tcc examples\hello_dll.c examples\dll.def
|
||||
|
||||
|
||||
For the 'Hello DLL' example:
|
||||
Import Definitions:
|
||||
-------------------
|
||||
|
||||
tcc -shared examples\dll.c
|
||||
tcc examples\hello_dll.c examples\dll.def
|
||||
TinyCC-PE searches and reads import definition files similar
|
||||
to libraries.
|
||||
|
||||
The included 'tiny_impdef' program may be used to make .def files
|
||||
for any DLL, e.g for an 'opengl32.def':
|
||||
|
||||
tiny_impdef.exe opengl32.dll
|
||||
|
||||
or to the same effect:
|
||||
|
||||
tcc -run tiny_impdef.c opengl32.dll
|
||||
|
||||
|
||||
Import Definitions:
|
||||
-------------------
|
||||
Resource Files:
|
||||
---------------
|
||||
|
||||
TinyCC-PE searches and reads import definition files similar
|
||||
to libraries.
|
||||
TinyCC-PE can now link windows resources in coff format as generated
|
||||
by MINGW's windres.exe. For example:
|
||||
|
||||
The included 'tiny_impdef' program may be used to make .def files
|
||||
for any DLL, e.g for an 'opengl32.def':
|
||||
|
||||
tiny_impdef.exe opengl32.dll
|
||||
|
||||
or to the same effect:
|
||||
|
||||
tcc -lkernel32 -run tiny_impdef.c opengl32.dll
|
||||
windres -O coff app.rc -o appres.o
|
||||
tcc app.c appres.o -o app.exe
|
||||
|
||||
|
||||
Header Files:
|
||||
-------------
|
||||
Header Files:
|
||||
-------------
|
||||
|
||||
The system header files, except '_mingw.h', are from the
|
||||
2.0 mingw distribution. See also: http://www.mingw.org/
|
||||
The system header files, except '_mingw.h', are from the
|
||||
3.7 mingw distribution. See also: http://www.mingw.org/
|
||||
|
||||
|
||||
Compile TCC:
|
||||
------------
|
||||
Compile TCC:
|
||||
------------
|
||||
|
||||
With TCC itself just say:
|
||||
With TCC itself just say:
|
||||
|
||||
tcc src\tcc.c -lkernel32 -o tcc.new.exe
|
||||
tcc src\tcc.c -o tcc.new.exe
|
||||
|
||||
Other compilers like mingw-gcc or msvc work as well.
|
||||
To make libtcc1.a, you need 'ar' from the mingw binutils.
|
||||
Other compilers like mingw-gcc or msvc work as well.
|
||||
To make libtcc1.a, you need 'ar' from the mingw binutils.
|
||||
|
||||
|
||||
Documentation and License:
|
||||
--------------------------
|
||||
Documentation and License:
|
||||
--------------------------
|
||||
|
||||
TCC is distributed under the GNU Lesser General Public License
|
||||
(see COPYING file).
|
||||
TCC is distributed under the GNU Lesser General Public License
|
||||
(see COPYING file).
|
||||
|
||||
Please read the original tcc-doc.html to have all the features
|
||||
of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
|
||||
|
||||
|
||||
--------------------------------------------
|
||||
09.Apr.2005 - grischka@users.sourceforge.net
|
||||
Please read the original tcc-doc.html to have all the features
|
||||
of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
|
||||
|
||||
--
|
||||
grischka@users.sourceforge.net
|
||||
|
Loading…
Reference in New Issue
Block a user