mirror of
https://github.com/frida/tinycc
synced 2025-01-17 08:49:18 +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:
|
version 0.9.24:
|
||||||
|
|
||||||
|
- Switch to newer tccpe.c (includes support for resources)
|
||||||
- Handle backslashes within #include, #error, #warning
|
- Handle backslashes within #include, #error, #warning
|
||||||
- Import changesets (part 4) 428,457,460,467: defines for openbsd etc.
|
- 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,
|
- 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 */
|
save_regs(0); /* save used temporary registers */
|
||||||
func_sym = vtop->type.ref;
|
func_sym = vtop->type.ref;
|
||||||
func_call = func_sym->r;
|
func_call = FUNC_CALL(func_sym->r);
|
||||||
/* fast call case */
|
/* fast call case */
|
||||||
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
|
||||||
func_call == FUNC_FASTCALLW) {
|
func_call == FUNC_FASTCALLW) {
|
||||||
@ -402,7 +402,7 @@ void gfunc_call(int nb_args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
gcall_or_jmp(0);
|
gcall_or_jmp(0);
|
||||||
if (args_size && func_sym->r != FUNC_STDCALL)
|
if (args_size && func_call != FUNC_STDCALL)
|
||||||
gadd_sp(args_size);
|
gadd_sp(args_size);
|
||||||
vtop--;
|
vtop--;
|
||||||
}
|
}
|
||||||
@ -423,7 +423,7 @@ void gfunc_prolog(CType *func_type)
|
|||||||
CType *type;
|
CType *type;
|
||||||
|
|
||||||
sym = func_type->ref;
|
sym = func_type->ref;
|
||||||
func_call = sym->r;
|
func_call = FUNC_CALL(sym->r);
|
||||||
addr = 8;
|
addr = 8;
|
||||||
loc = 0;
|
loc = 0;
|
||||||
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
|
||||||
|
289
tcc.c
289
tcc.c
@ -40,7 +40,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
// #include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -230,10 +230,24 @@ typedef struct AttributeDef {
|
|||||||
int aligned;
|
int aligned;
|
||||||
int packed;
|
int packed;
|
||||||
Section *section;
|
Section *section;
|
||||||
unsigned char func_call; /* FUNC_CDECL, FUNC_STDCALL, FUNC_FASTCALLx */
|
int func_attr; /* calling convention, exports, ... */
|
||||||
unsigned char dllexport;
|
|
||||||
} AttributeDef;
|
} 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_STRUCT 0x40000000 /* struct/union/enum symbol space */
|
||||||
#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
|
#define SYM_FIELD 0x20000000 /* struct/union field symbol space */
|
||||||
#define SYM_FIRST_ANOM 0x10000000 /* first anonymous sym */
|
#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) */
|
/* true if isid(c) || isnum(c) */
|
||||||
static unsigned char isidnum_table[256];
|
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) */
|
/* compile with debug symbol (and use them if error during execution) */
|
||||||
static int do_debug = 0;
|
static int do_debug = 0;
|
||||||
|
|
||||||
@ -723,14 +740,6 @@ static const char tcc_keywords[] =
|
|||||||
#define TOK_UIDENT TOK_DEFINE
|
#define TOK_UIDENT TOK_DEFINE
|
||||||
|
|
||||||
#ifdef _WIN32
|
#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 snprintf _snprintf
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
#ifndef __GNUC__
|
#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 *pstrcpy(char *buf, int buf_size, const char *s);
|
||||||
static char *pstrcat(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_basename(const char *name);
|
||||||
|
static char *tcc_fileextension (const char *p);
|
||||||
|
|
||||||
static void next(void);
|
static void next(void);
|
||||||
static void next_nomacro(void);
|
static void next_nomacro(void);
|
||||||
@ -858,10 +868,12 @@ int tcc_output_coff(TCCState *s1, FILE *f);
|
|||||||
|
|
||||||
/* tccpe.c */
|
/* tccpe.c */
|
||||||
void *resolve_sym(TCCState *s1, const char *sym, int type);
|
void *resolve_sym(TCCState *s1, const char *sym, int type);
|
||||||
int pe_load_def_file(struct TCCState *s1, FILE *fp);
|
int pe_load_def_file(struct TCCState *s1, int fd);
|
||||||
void pe_setup_paths(struct TCCState *s1, int *p_output_type, const char **p_outfile, char *first_file);
|
int pe_test_res_file(void *v, int size);
|
||||||
unsigned long pe_add_runtime(struct TCCState *s1);
|
int pe_load_res_file(struct TCCState *s1, int fd);
|
||||||
int tcc_output_pe(struct TCCState *s1, const char *filename);
|
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 */
|
/* tccasm.c */
|
||||||
|
|
||||||
@ -1036,6 +1048,27 @@ static int strstart(const char *str, const char *val, const char **ptr)
|
|||||||
return 1;
|
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
|
#ifdef _WIN32
|
||||||
char *normalize_slashes(char *path)
|
char *normalize_slashes(char *path)
|
||||||
{
|
{
|
||||||
@ -1162,6 +1195,16 @@ static void dynarray_add(void ***ptab, int *nb_ptr, void *data)
|
|||||||
*nb_ptr = nb;
|
*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 */
|
/* symbol allocator */
|
||||||
static Sym *__sym_malloc(void)
|
static Sym *__sym_malloc(void)
|
||||||
{
|
{
|
||||||
@ -1291,7 +1334,7 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
unsigned long value, unsigned long size,
|
unsigned long value, unsigned long size,
|
||||||
int can_add_underscore)
|
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;
|
Elf32_Sym *esym;
|
||||||
const char *name;
|
const char *name;
|
||||||
char buf1[256];
|
char buf1[256];
|
||||||
@ -1302,16 +1345,29 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
sh_num = SHN_ABS;
|
sh_num = SHN_ABS;
|
||||||
else
|
else
|
||||||
sh_num = section->sh_num;
|
sh_num = section->sh_num;
|
||||||
if (!sym->c) {
|
|
||||||
if ((sym->type.t & VT_BTYPE) == VT_FUNC)
|
other = attr = 0;
|
||||||
|
|
||||||
|
if ((sym->type.t & VT_BTYPE) == VT_FUNC) {
|
||||||
sym_type = STT_FUNC;
|
sym_type = STT_FUNC;
|
||||||
else
|
#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;
|
sym_type = STT_OBJECT;
|
||||||
|
}
|
||||||
|
|
||||||
if (sym->type.t & VT_STATIC)
|
if (sym->type.t & VT_STATIC)
|
||||||
sym_bind = STB_LOCAL;
|
sym_bind = STB_LOCAL;
|
||||||
else
|
else
|
||||||
sym_bind = STB_GLOBAL;
|
sym_bind = STB_GLOBAL;
|
||||||
|
|
||||||
|
if (!sym->c) {
|
||||||
name = get_tok_str(sym->v, NULL);
|
name = get_tok_str(sym->v, NULL);
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
if (do_bounds_check) {
|
if (do_bounds_check) {
|
||||||
@ -1342,18 +1398,26 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (tcc_state->leading_underscore && can_add_underscore) {
|
||||||
buf1[0] = '_';
|
buf1[0] = '_';
|
||||||
pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
|
pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
|
||||||
name = buf1;
|
name = buf1;
|
||||||
}
|
}
|
||||||
info = ELF32_ST_INFO(sym_bind, sym_type);
|
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 {
|
} else {
|
||||||
esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
|
esym = &((Elf32_Sym *)symtab_section->data)[sym->c];
|
||||||
esym->st_value = value;
|
esym->st_value = value;
|
||||||
esym->st_size = size;
|
esym->st_size = size;
|
||||||
esym->st_shndx = sh_num;
|
esym->st_shndx = sh_num;
|
||||||
|
esym->st_other |= other;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2868,7 +2932,7 @@ static void preprocess(int is_bof)
|
|||||||
{
|
{
|
||||||
TCCState *s1 = tcc_state;
|
TCCState *s1 = tcc_state;
|
||||||
int size, i, c, n, saved_parse_flags;
|
int size, i, c, n, saved_parse_flags;
|
||||||
char buf[1024], *q, *p;
|
char buf[1024], *q;
|
||||||
char buf1[1024];
|
char buf1[1024];
|
||||||
BufferedFile *f;
|
BufferedFile *f;
|
||||||
Sym *s;
|
Sym *s;
|
||||||
@ -2962,10 +3026,7 @@ static void preprocess(int is_bof)
|
|||||||
} else {
|
} else {
|
||||||
if (c == '\"') {
|
if (c == '\"') {
|
||||||
/* first search in current dir if "header.h" */
|
/* first search in current dir if "header.h" */
|
||||||
size = 0;
|
size = tcc_basename(file->filename) - file->filename;
|
||||||
p = strrchr(file->filename, '/');
|
|
||||||
if (p)
|
|
||||||
size = p + 1 - file->filename;
|
|
||||||
if (size > sizeof(buf1) - 1)
|
if (size > sizeof(buf1) - 1)
|
||||||
size = sizeof(buf1) - 1;
|
size = sizeof(buf1) - 1;
|
||||||
memcpy(buf1, file->filename, size);
|
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, ' ');
|
cstr_ccat(&cstr, ' ');
|
||||||
TOK_GET(t, st, cval);
|
TOK_GET(t, st, cval);
|
||||||
cstr_cat(&cstr, get_tok_str(t, &cval));
|
cstr_cat(&cstr, get_tok_str(t, &cval));
|
||||||
|
#ifndef PP_NOSPACES
|
||||||
notfirst = 1;
|
notfirst = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
cstr_ccat(&cstr, '\0');
|
cstr_ccat(&cstr, '\0');
|
||||||
#ifdef PP_DEBUG
|
#ifdef PP_DEBUG
|
||||||
@ -6112,7 +6175,7 @@ static int is_compatible_func(CType *type1, CType *type2)
|
|||||||
if (!is_compatible_types(&s1->type, &s2->type))
|
if (!is_compatible_types(&s1->type, &s2->type))
|
||||||
return 0;
|
return 0;
|
||||||
/* check func_call */
|
/* check func_call */
|
||||||
if (s1->r != s2->r)
|
if (FUNC_CALL(s1->r) != FUNC_CALL(s2->r))
|
||||||
return 0;
|
return 0;
|
||||||
/* XXX: not complete */
|
/* XXX: not complete */
|
||||||
if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
|
if (s1->c == FUNC_OLD || s2->c == FUNC_OLD)
|
||||||
@ -6569,12 +6632,12 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
case TOK_CDECL1:
|
case TOK_CDECL1:
|
||||||
case TOK_CDECL2:
|
case TOK_CDECL2:
|
||||||
case TOK_CDECL3:
|
case TOK_CDECL3:
|
||||||
ad->func_call = FUNC_CDECL;
|
FUNC_CALL(ad->func_attr) = FUNC_CDECL;
|
||||||
break;
|
break;
|
||||||
case TOK_STDCALL1:
|
case TOK_STDCALL1:
|
||||||
case TOK_STDCALL2:
|
case TOK_STDCALL2:
|
||||||
case TOK_STDCALL3:
|
case TOK_STDCALL3:
|
||||||
ad->func_call = FUNC_STDCALL;
|
FUNC_CALL(ad->func_attr) = FUNC_STDCALL;
|
||||||
break;
|
break;
|
||||||
#ifdef TCC_TARGET_I386
|
#ifdef TCC_TARGET_I386
|
||||||
case TOK_REGPARM1:
|
case TOK_REGPARM1:
|
||||||
@ -6586,17 +6649,17 @@ static void parse_attribute(AttributeDef *ad)
|
|||||||
else if (n < 0)
|
else if (n < 0)
|
||||||
n = 0;
|
n = 0;
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
ad->func_call = FUNC_FASTCALL1 + n - 1;
|
FUNC_CALL(ad->func_attr) = FUNC_FASTCALL1 + n - 1;
|
||||||
skip(')');
|
skip(')');
|
||||||
break;
|
break;
|
||||||
case TOK_FASTCALL1:
|
case TOK_FASTCALL1:
|
||||||
case TOK_FASTCALL2:
|
case TOK_FASTCALL2:
|
||||||
case TOK_FASTCALL3:
|
case TOK_FASTCALL3:
|
||||||
ad->func_call = FUNC_FASTCALLW;
|
FUNC_CALL(ad->func_attr) = FUNC_FASTCALLW;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case TOK_DLLEXPORT:
|
case TOK_DLLEXPORT:
|
||||||
ad->dllexport = 1;
|
FUNC_EXPORT(ad->func_attr) = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (tcc_state->warn_unsupported)
|
if (tcc_state->warn_unsupported)
|
||||||
@ -7009,7 +7072,7 @@ static inline void convert_parameter_type(CType *pt)
|
|||||||
|
|
||||||
static void post_type(CType *type, AttributeDef *ad)
|
static void post_type(CType *type, AttributeDef *ad)
|
||||||
{
|
{
|
||||||
int n, l, t1;
|
int n, l, t1, arg_size, align;
|
||||||
Sym **plast, *s, *first;
|
Sym **plast, *s, *first;
|
||||||
AttributeDef ad1;
|
AttributeDef ad1;
|
||||||
CType pt;
|
CType pt;
|
||||||
@ -7020,6 +7083,7 @@ static void post_type(CType *type, AttributeDef *ad)
|
|||||||
l = 0;
|
l = 0;
|
||||||
first = NULL;
|
first = NULL;
|
||||||
plast = &first;
|
plast = &first;
|
||||||
|
arg_size = 0;
|
||||||
if (tok != ')') {
|
if (tok != ')') {
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* read param name and compute offset */
|
/* 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);
|
type_decl(&pt, &ad1, &n, TYPE_DIRECT | TYPE_ABSTRACT);
|
||||||
if ((pt.t & VT_BTYPE) == VT_VOID)
|
if ((pt.t & VT_BTYPE) == VT_VOID)
|
||||||
error("parameter declared as void");
|
error("parameter declared as void");
|
||||||
|
arg_size += (type_size(&pt, &align) + 3) & ~3;
|
||||||
} else {
|
} else {
|
||||||
old_proto:
|
old_proto:
|
||||||
n = tok;
|
n = tok;
|
||||||
@ -7070,7 +7135,8 @@ static void post_type(CType *type, AttributeDef *ad)
|
|||||||
type->t &= ~(VT_STORAGE | VT_CONSTANT);
|
type->t &= ~(VT_STORAGE | VT_CONSTANT);
|
||||||
post_type(type, ad);
|
post_type(type, ad);
|
||||||
/* we push a anonymous symbol which will contain the function prototype */
|
/* 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;
|
s->next = first;
|
||||||
type->t = t1 | VT_FUNC;
|
type->t = t1 | VT_FUNC;
|
||||||
type->ref = s;
|
type->ref = s;
|
||||||
@ -7629,6 +7695,7 @@ static void unary(void)
|
|||||||
next();
|
next();
|
||||||
sa = s->next; /* first parameter */
|
sa = s->next; /* first parameter */
|
||||||
nb_args = 0;
|
nb_args = 0;
|
||||||
|
ret.r2 = VT_CONST;
|
||||||
/* compute first implicit argument if a structure is returned */
|
/* compute first implicit argument if a structure is returned */
|
||||||
if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
|
if ((s->type.t & VT_BTYPE) == VT_STRUCT) {
|
||||||
/* get some space for the returned structure */
|
/* get some space for the returned structure */
|
||||||
@ -7643,7 +7710,6 @@ static void unary(void)
|
|||||||
nb_args++;
|
nb_args++;
|
||||||
} else {
|
} else {
|
||||||
ret.type = s->type;
|
ret.type = s->type;
|
||||||
ret.r2 = VT_CONST;
|
|
||||||
/* return in register */
|
/* return in register */
|
||||||
if (is_float(ret.type.t)) {
|
if (is_float(ret.type.t)) {
|
||||||
ret.r = REG_FRET;
|
ret.r = REG_FRET;
|
||||||
@ -8660,12 +8726,11 @@ static void decl_initializer(CType *type, Section *sec, unsigned long c,
|
|||||||
them as ((w)char *) expressions */
|
them as ((w)char *) expressions */
|
||||||
if ((tok == TOK_LSTR &&
|
if ((tok == TOK_LSTR &&
|
||||||
#ifdef TCC_TARGET_PE
|
#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
|
#else
|
||||||
(t1->t & VT_BTYPE) == VT_INT) ||
|
(t1->t & VT_BTYPE) == VT_INT
|
||||||
#endif
|
#endif
|
||||||
(tok == TOK_STR &&
|
) || (tok == TOK_STR && (t1->t & VT_BTYPE) == VT_BYTE)) {
|
||||||
(t1->t & VT_BTYPE) == VT_BYTE)) {
|
|
||||||
while (tok == TOK_STR || tok == TOK_LSTR) {
|
while (tok == TOK_STR || tok == TOK_LSTR) {
|
||||||
int cstr_len, ch;
|
int cstr_len, ch;
|
||||||
CString *cstr;
|
CString *cstr;
|
||||||
@ -9166,9 +9231,9 @@ static void gen_inline_functions(void)
|
|||||||
sym->c != 0) {
|
sym->c != 0) {
|
||||||
/* the function was used: generate its code and
|
/* the function was used: generate its code and
|
||||||
convert it to a normal function */
|
convert it to a normal function */
|
||||||
str = (int *)sym->r;
|
str = INLINE_DEF(sym->r);
|
||||||
sym->r = VT_SYM | VT_CONST;
|
sym->r = VT_SYM | VT_CONST;
|
||||||
type->t &= ~VT_INLINE;
|
sym->type.t &= ~VT_INLINE;
|
||||||
|
|
||||||
macro_ptr = str;
|
macro_ptr = str;
|
||||||
next();
|
next();
|
||||||
@ -9190,7 +9255,10 @@ static void gen_inline_functions(void)
|
|||||||
if (((type->t & VT_BTYPE) == VT_FUNC) &&
|
if (((type->t & VT_BTYPE) == VT_FUNC) &&
|
||||||
(type->t & (VT_STATIC | VT_INLINE)) ==
|
(type->t & (VT_STATIC | VT_INLINE)) ==
|
||||||
(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);
|
tok_str_free(str);
|
||||||
sym->r = 0; /* fail safe */
|
sym->r = 0; /* fail safe */
|
||||||
}
|
}
|
||||||
@ -9273,9 +9341,13 @@ static void decl(int l)
|
|||||||
/* specific case: if not func_call defined, we put
|
/* specific case: if not func_call defined, we put
|
||||||
the one of the prototype */
|
the one of the prototype */
|
||||||
/* XXX: should have default value */
|
/* XXX: should have default value */
|
||||||
if (sym->type.ref->r != FUNC_CDECL &&
|
r = sym->type.ref->r;
|
||||||
type.ref->r == FUNC_CDECL)
|
if (FUNC_CALL(r) != FUNC_CDECL
|
||||||
type.ref->r = sym->type.ref->r;
|
&& 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)) {
|
if (!is_compatible_types(&sym->type, &type)) {
|
||||||
func_error1:
|
func_error1:
|
||||||
error("incompatible types for redefinition of '%s'",
|
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, -1);
|
||||||
tok_str_add(&func_str, 0);
|
tok_str_add(&func_str, 0);
|
||||||
sym->r = (int)func_str.str;
|
INLINE_DEF(sym->r) = func_str.str;
|
||||||
} else {
|
} else {
|
||||||
/* compute text section */
|
/* compute text section */
|
||||||
cur_text_section = ad.section;
|
cur_text_section = ad.section;
|
||||||
@ -9325,11 +9397,6 @@ static void decl(int l)
|
|||||||
cur_text_section = text_section;
|
cur_text_section = text_section;
|
||||||
sym->r = VT_SYM | VT_CONST;
|
sym->r = VT_SYM | VT_CONST;
|
||||||
gen_function(sym);
|
gen_function(sym);
|
||||||
#ifdef TCC_TARGET_PE
|
|
||||||
if (ad.dllexport) {
|
|
||||||
((Elf32_Sym *)symtab_section->data)[sym->c].st_other |= 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@ -9341,8 +9408,8 @@ static void decl(int l)
|
|||||||
} else if ((type.t & VT_BTYPE) == VT_FUNC) {
|
} else if ((type.t & VT_BTYPE) == VT_FUNC) {
|
||||||
/* external function definition */
|
/* external function definition */
|
||||||
/* specific case for func_call attribute */
|
/* specific case for func_call attribute */
|
||||||
if (ad.func_call)
|
if (ad.func_attr)
|
||||||
type.ref->r = ad.func_call;
|
type.ref->r = ad.func_attr;
|
||||||
external_sym(v, &type, 0);
|
external_sym(v, &type, 0);
|
||||||
} else {
|
} else {
|
||||||
/* not lvalue if array */
|
/* not lvalue if array */
|
||||||
@ -9891,9 +9958,9 @@ int tcc_relocate(TCCState *s1)
|
|||||||
relocate_common_syms();
|
relocate_common_syms();
|
||||||
|
|
||||||
tcc_add_linker_symbols(s1);
|
tcc_add_linker_symbols(s1);
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
build_got_entries(s1);
|
build_got_entries(s1);
|
||||||
|
#endif
|
||||||
/* compute relocation address : section are relocated in place. We
|
/* compute relocation address : section are relocated in place. We
|
||||||
also alloc the bss space */
|
also alloc the bss space */
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
@ -10118,27 +10185,15 @@ void tcc_delete(TCCState *s1)
|
|||||||
tcc_free(s1->sections);
|
tcc_free(s1->sections);
|
||||||
|
|
||||||
/* free loaded dlls array */
|
/* free loaded dlls array */
|
||||||
for(i = 0; i < s1->nb_loaded_dlls; i++)
|
dynarray_reset(&s1->loaded_dlls, &s1->nb_loaded_dlls);
|
||||||
tcc_free(s1->loaded_dlls[i]);
|
|
||||||
tcc_free(s1->loaded_dlls);
|
|
||||||
|
|
||||||
/* library paths */
|
/* free library paths */
|
||||||
for(i = 0; i < s1->nb_library_paths; i++)
|
dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
|
||||||
tcc_free(s1->library_paths[i]);
|
|
||||||
tcc_free(s1->library_paths);
|
|
||||||
|
|
||||||
/* cached includes */
|
/* free include paths */
|
||||||
for(i = 0; i < s1->nb_cached_includes; i++)
|
dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
|
||||||
tcc_free(s1->cached_includes[i]);
|
dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
|
||||||
tcc_free(s1->cached_includes);
|
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
tcc_free(s1);
|
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)
|
static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
||||||
{
|
{
|
||||||
const char *ext, *filename1;
|
const char *ext;
|
||||||
Elf32_Ehdr ehdr;
|
Elf32_Ehdr ehdr;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
BufferedFile *saved_file;
|
BufferedFile *saved_file;
|
||||||
|
|
||||||
/* find source file type with extension */
|
/* find source file type with extension */
|
||||||
filename1 = strrchr(filename, '/');
|
ext = tcc_fileextension(filename);
|
||||||
if (filename1)
|
if (ext[0])
|
||||||
filename1++;
|
|
||||||
else
|
|
||||||
filename1 = filename;
|
|
||||||
ext = strrchr(filename1, '.');
|
|
||||||
if (ext)
|
|
||||||
ext++;
|
ext++;
|
||||||
|
|
||||||
/* open the file */
|
/* open the file */
|
||||||
@ -10191,7 +10241,7 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||||||
|
|
||||||
if (flags & AFF_PREPROCESS) {
|
if (flags & AFF_PREPROCESS) {
|
||||||
ret = tcc_preprocess(s1);
|
ret = tcc_preprocess(s1);
|
||||||
} else if (!ext || !strcmp(ext, "c")) {
|
} else if (!ext[0] || !strcmp(ext, "c")) {
|
||||||
/* C file assumed */
|
/* C file assumed */
|
||||||
ret = tcc_compile(s1);
|
ret = tcc_compile(s1);
|
||||||
} else
|
} else
|
||||||
@ -10206,7 +10256,7 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||||||
#endif
|
#endif
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (!strcmp(ext, "def")) {
|
if (!strcmp(ext, "def")) {
|
||||||
ret = pe_load_def_file(s1, fdopen(file->fd, "rb"));
|
ret = pe_load_def_file(s1, file->fd);
|
||||||
} else
|
} else
|
||||||
#endif
|
#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) {
|
if (*(uint16_t *)(&ehdr) == COFF_C67_MAGIC) {
|
||||||
ret = tcc_load_coff(s1, fd);
|
ret = tcc_load_coff(s1, fd);
|
||||||
} else
|
} else
|
||||||
|
#endif
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
if (pe_test_res_file(&ehdr, ret)) {
|
||||||
|
ret = pe_load_res_file(s1, fd);
|
||||||
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* as GNU ld, consider it is an ld script if not recognized */
|
/* 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);
|
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)
|
#if !defined(LIBTCC)
|
||||||
|
|
||||||
static int64_t getclock_us(void)
|
static int64_t getclock_us(void)
|
||||||
@ -10535,7 +10576,7 @@ void help(void)
|
|||||||
" -shared generate a shared library\n"
|
" -shared generate a shared library\n"
|
||||||
" -static static linking\n"
|
" -static static linking\n"
|
||||||
" -rdynamic export all global symbols to dynamic linker\n"
|
" -rdynamic export all global symbols to dynamic linker\n"
|
||||||
" -r relocatable output\n"
|
" -r generate (relocatable) object file\n"
|
||||||
"Debugger options:\n"
|
"Debugger options:\n"
|
||||||
" -g generate runtime debug info\n"
|
" -g generate runtime debug info\n"
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
@ -10885,6 +10926,7 @@ int main(int argc, char **argv)
|
|||||||
nb_libraries = 0;
|
nb_libraries = 0;
|
||||||
reloc_output = 0;
|
reloc_output = 0;
|
||||||
print_search_dirs = 0;
|
print_search_dirs = 0;
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
optind = parse_args(s, argc - 1, argv + 1) + 1;
|
optind = parse_args(s, argc - 1, argv + 1) + 1;
|
||||||
|
|
||||||
@ -10915,30 +10957,28 @@ int main(int argc, char **argv)
|
|||||||
if (!outfile) {
|
if (!outfile) {
|
||||||
s->outfile = stdout;
|
s->outfile = stdout;
|
||||||
} else {
|
} else {
|
||||||
s->outfile = fopen(outfile, "wb");
|
s->outfile = fopen(outfile, "w");
|
||||||
if (!s->outfile)
|
if (!s->outfile)
|
||||||
error("could not open '%s", outfile);
|
error("could not open '%s", outfile);
|
||||||
}
|
}
|
||||||
} else if (output_type != TCC_OUTPUT_MEMORY) {
|
} else if (output_type != TCC_OUTPUT_MEMORY) {
|
||||||
if (!outfile) {
|
if (!outfile) {
|
||||||
/* compute default outfile name */
|
/* compute default outfile name */
|
||||||
pstrcpy(objfilename, sizeof(objfilename) - 1,
|
char *ext;
|
||||||
/* strip path */
|
pstrcpy(objfilename, sizeof(objfilename), tcc_basename(files[0]));
|
||||||
tcc_basename(files[0]));
|
ext = tcc_fileextension(objfilename);
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
pe_guess_outfile(objfilename, output_type);
|
if (output_type == TCC_OUTPUT_DLL)
|
||||||
#else
|
strcpy(ext, ".dll");
|
||||||
if (output_type == TCC_OUTPUT_OBJ && !reloc_output) {
|
else
|
||||||
char *ext = strrchr(objfilename, '.');
|
if (output_type == TCC_OUTPUT_EXE)
|
||||||
if (!ext)
|
strcpy(ext, ".exe");
|
||||||
goto default_outfile;
|
else
|
||||||
/* add .o extension */
|
|
||||||
strcpy(ext + 1, "o");
|
|
||||||
} else {
|
|
||||||
default_outfile:
|
|
||||||
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
if (output_type == TCC_OUTPUT_OBJ && !reloc_output && *ext)
|
||||||
|
strcpy(ext, ".o");
|
||||||
|
else
|
||||||
|
pstrcpy(objfilename, sizeof(objfilename), "a.out");
|
||||||
outfile = objfilename;
|
outfile = objfilename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -10950,29 +10990,29 @@ int main(int argc, char **argv)
|
|||||||
tcc_set_output_type(s, output_type);
|
tcc_set_output_type(s, output_type);
|
||||||
|
|
||||||
/* compile or add each files or library */
|
/* 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;
|
const char *filename;
|
||||||
|
|
||||||
filename = files[i];
|
filename = files[i];
|
||||||
if (output_type == TCC_OUTPUT_PREPROCESS) {
|
if (output_type == TCC_OUTPUT_PREPROCESS) {
|
||||||
tcc_add_file_internal(s, filename,
|
if (tcc_add_file_internal(s, filename,
|
||||||
AFF_PRINT_ERROR | AFF_PREPROCESS);
|
AFF_PRINT_ERROR | AFF_PREPROCESS) < 0)
|
||||||
} else {
|
ret = 1;
|
||||||
if (filename[0] == '-') {
|
} else if (filename[0] == '-') {
|
||||||
if (tcc_add_library(s, filename + 2) < 0)
|
if (tcc_add_library(s, filename + 2) < 0)
|
||||||
error("cannot find %s", filename);
|
error("cannot find %s", filename);
|
||||||
} else {
|
} else {
|
||||||
if (tcc_add_file(s, filename) < 0) {
|
if (tcc_add_file(s, filename) < 0)
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto the_end;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free all files */
|
/* free all files */
|
||||||
tcc_free(files);
|
tcc_free(files);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
goto the_end;
|
||||||
|
|
||||||
if (do_bench) {
|
if (do_bench) {
|
||||||
double total_time;
|
double total_time;
|
||||||
total_time = (double)(getclock_us() - start_time) / 1000000.0;
|
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 (s->output_type == TCC_OUTPUT_PREPROCESS) {
|
||||||
if (outfile)
|
if (outfile)
|
||||||
fclose(s->outfile);
|
fclose(s->outfile);
|
||||||
ret = 0;
|
|
||||||
} else if (s->output_type == TCC_OUTPUT_MEMORY) {
|
} else if (s->output_type == TCC_OUTPUT_MEMORY) {
|
||||||
ret = tcc_run(s, argc - optind, argv + optind);
|
ret = tcc_run(s, argc - optind, argv + optind);
|
||||||
} else
|
} else
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (s->output_type != TCC_OUTPUT_OBJ) {
|
if (s->output_type != TCC_OUTPUT_OBJ) {
|
||||||
ret = tcc_output_pe(s, outfile);
|
ret = pe_output_file(s, outfile);
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
7
tccelf.c
7
tccelf.c
@ -2146,7 +2146,7 @@ static int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level)
|
|||||||
Elf32_Sym *sym, *dynsym;
|
Elf32_Sym *sym, *dynsym;
|
||||||
Elf32_Dyn *dt, *dynamic;
|
Elf32_Dyn *dt, *dynamic;
|
||||||
unsigned char *dynstr;
|
unsigned char *dynstr;
|
||||||
const char *name, *soname, *p;
|
const char *name, *soname;
|
||||||
DLLReference *dllref;
|
DLLReference *dllref;
|
||||||
|
|
||||||
read(fd, &ehdr, sizeof(ehdr));
|
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 */
|
/* compute the real library name */
|
||||||
soname = filename;
|
soname = tcc_basename(filename);
|
||||||
p = strrchr(soname, '/');
|
|
||||||
if (p)
|
|
||||||
soname = p + 1;
|
|
||||||
|
|
||||||
for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
|
for(i = 0, dt = dynamic; i < nb_dts; i++, dt++) {
|
||||||
if (dt->d_tag == DT_SONAME) {
|
if (dt->d_tag == DT_SONAME) {
|
||||||
|
@ -41,6 +41,11 @@
|
|||||||
|
|
||||||
TCC is installed in c:\Program Files\tcc
|
TCC is installed in c:\Program Files\tcc
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
Installation: (from the binary ZIP package)
|
Installation: (from the binary ZIP package)
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@ -54,12 +59,10 @@
|
|||||||
|
|
||||||
tcc examples\fib.c
|
tcc examples\fib.c
|
||||||
|
|
||||||
|
|
||||||
For the 'Hello Windows' GUI example:
|
For the 'Hello Windows' GUI example:
|
||||||
|
|
||||||
tcc examples\hello_win.c
|
tcc examples\hello_win.c
|
||||||
|
|
||||||
|
|
||||||
For the 'Hello DLL' example:
|
For the 'Hello DLL' example:
|
||||||
|
|
||||||
tcc -shared examples\dll.c
|
tcc -shared examples\dll.c
|
||||||
@ -79,14 +82,24 @@
|
|||||||
|
|
||||||
or to the same effect:
|
or to the same effect:
|
||||||
|
|
||||||
tcc -lkernel32 -run tiny_impdef.c opengl32.dll
|
tcc -run tiny_impdef.c opengl32.dll
|
||||||
|
|
||||||
|
|
||||||
|
Resource Files:
|
||||||
|
---------------
|
||||||
|
|
||||||
|
TinyCC-PE can now link windows resources in coff format as generated
|
||||||
|
by MINGW's windres.exe. For example:
|
||||||
|
|
||||||
|
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
|
The system header files, except '_mingw.h', are from the
|
||||||
2.0 mingw distribution. See also: http://www.mingw.org/
|
3.7 mingw distribution. See also: http://www.mingw.org/
|
||||||
|
|
||||||
|
|
||||||
Compile TCC:
|
Compile TCC:
|
||||||
@ -94,7 +107,7 @@
|
|||||||
|
|
||||||
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.
|
Other compilers like mingw-gcc or msvc work as well.
|
||||||
To make libtcc1.a, you need 'ar' from the mingw binutils.
|
To make libtcc1.a, you need 'ar' from the mingw binutils.
|
||||||
@ -109,7 +122,5 @@
|
|||||||
Please read the original tcc-doc.html to have all the features
|
Please read the original tcc-doc.html to have all the features
|
||||||
of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
|
of TCC. Also visit: http://fabrice.bellard.free.fr/tcc/
|
||||||
|
|
||||||
|
--
|
||||||
--------------------------------------------
|
grischka@users.sourceforge.net
|
||||||
09.Apr.2005 - grischka@users.sourceforge.net
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user