Switch to newer tccpe.c (includes support for resources)

This commit is contained in:
grischka 2007-12-19 17:36:42 +00:00
parent adb1456472
commit 5342b32eef
6 changed files with 1354 additions and 999 deletions

View File

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

View File

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

309
tcc.c
View File

@ -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)
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); 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)
@ -6979,7 +7042,7 @@ static int parse_btype(CType *type, AttributeDef *ad)
} }
the_end: the_end:
if ((t & (VT_SIGNED|VT_UNSIGNED)) == (VT_SIGNED|VT_UNSIGNED)) 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 (tcc_state->char_is_unsigned) {
if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE) if ((t & (VT_SIGNED|VT_UNSIGNED|VT_BTYPE)) == VT_BYTE)
t |= VT_UNSIGNED; t |= VT_UNSIGNED;
@ -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)
ret = 1;
} else if (filename[0] == '-') {
if (tcc_add_library(s, filename + 2) < 0)
error("cannot find %s", filename);
} else { } else {
if (filename[0] == '-') { if (tcc_add_file(s, filename) < 0)
if (tcc_add_library(s, filename + 2) < 0) ret = 1;
error("cannot find %s", filename);
} else {
if (tcc_add_file(s, filename) < 0) {
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
{ {

161
tccelf.c
View File

@ -531,11 +531,11 @@ static void relocate_section(TCCState *s1, Section *s)
*(int *)ptr += s1->got_offsets[sym_index]; *(int *)ptr += s1->got_offsets[sym_index];
break; break;
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
case R_ARM_PC24: case R_ARM_PC24:
case R_ARM_CALL: case R_ARM_CALL:
case R_ARM_JUMP24: case R_ARM_JUMP24:
case R_ARM_PLT32: case R_ARM_PLT32:
{ {
int x; int x;
x = (*(int *)ptr)&0xffffff; x = (*(int *)ptr)&0xffffff;
(*(int *)ptr) &= 0xff000000; (*(int *)ptr) &= 0xff000000;
@ -548,42 +548,42 @@ static void relocate_section(TCCState *s1, Section *s)
x >>= 2; x >>= 2;
x &= 0xffffff; x &= 0xffffff;
(*(int *)ptr) |= x; (*(int *)ptr) |= x;
} }
break; break;
case R_ARM_PREL31: case R_ARM_PREL31:
{ {
int x; int x;
x = (*(int *)ptr) & 0x7fffffff; x = (*(int *)ptr) & 0x7fffffff;
(*(int *)ptr) &= 0x80000000; (*(int *)ptr) &= 0x80000000;
x = (x * 2) / 2; x = (x * 2) / 2;
x += val - addr; x += val - addr;
if((x^(x>>1))&0x40000000) if((x^(x>>1))&0x40000000)
error("can't relocate value at %x",addr); error("can't relocate value at %x",addr);
(*(int *)ptr) |= x & 0x7fffffff; (*(int *)ptr) |= x & 0x7fffffff;
} }
case R_ARM_ABS32: case R_ARM_ABS32:
*(int *)ptr += val; *(int *)ptr += val;
break; break;
case R_ARM_BASE_PREL: case R_ARM_BASE_PREL:
*(int *)ptr += s1->got->sh_addr - addr; *(int *)ptr += s1->got->sh_addr - addr;
break; break;
case R_ARM_GOTOFF32: case R_ARM_GOTOFF32:
*(int *)ptr += val - s1->got->sh_addr; *(int *)ptr += val - s1->got->sh_addr;
break; break;
case R_ARM_GOT_BREL: case R_ARM_GOT_BREL:
/* we load the got offset */ /* we load the got offset */
*(int *)ptr += s1->got_offsets[sym_index]; *(int *)ptr += s1->got_offsets[sym_index];
break; break;
case R_ARM_COPY: case R_ARM_COPY:
break; break;
default: 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); type,addr,(unsigned int )ptr,val);
break; break;
#elif defined(TCC_TARGET_C67) #elif defined(TCC_TARGET_C67)
case R_C60_32: case R_C60_32:
*(int *)ptr += val; *(int *)ptr += val;
break; break;
case R_C60LO16: case R_C60LO16:
{ {
uint32_t orig; uint32_t orig;
@ -603,7 +603,7 @@ static void relocate_section(TCCState *s1, Section *s)
case R_C60HI16: case R_C60HI16:
break; break;
default: 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); type,addr,(unsigned int )ptr,val);
break; break;
#else #else
@ -784,7 +784,7 @@ static void put_got_entry(TCCState *s1,
offset = plt->data_offset - 16; offset = plt->data_offset - 16;
} }
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
if (reloc_type == R_ARM_JUMP_SLOT) { if (reloc_type == R_ARM_JUMP_SLOT) {
Section *plt; Section *plt;
uint8_t *p; uint8_t *p;
@ -797,17 +797,17 @@ static void put_got_entry(TCCState *s1,
if (plt->data_offset == 0) { if (plt->data_offset == 0) {
/* first plt entry */ /* first plt entry */
p = section_ptr_add(plt, 16); p = section_ptr_add(plt, 16);
put32(p , 0xe52de004); put32(p , 0xe52de004);
put32(p + 4, 0xe59fe010); put32(p + 4, 0xe59fe010);
put32(p + 8, 0xe08fe00e); put32(p + 8, 0xe08fe00e);
put32(p + 12, 0xe5bef008); put32(p + 12, 0xe5bef008);
} }
p = section_ptr_add(plt, 16); p = section_ptr_add(plt, 16);
put32(p , 0xe59fc004); put32(p , 0xe59fc004);
put32(p+4, 0xe08fc00c); put32(p+4, 0xe08fc00c);
put32(p+8, 0xe59cf000); put32(p+8, 0xe59cf000);
put32(p+12, s1->got->data_offset); put32(p+12, s1->got->data_offset);
/* the symbol is modified so that it will be relocated to /* the symbol is modified so that it will be relocated to
the PLT */ the PLT */
@ -872,7 +872,7 @@ static void build_got_entries(TCCState *s1)
} }
break; break;
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
case R_ARM_GOT_BREL: case R_ARM_GOT_BREL:
case R_ARM_GOTOFF32: case R_ARM_GOTOFF32:
case R_ARM_BASE_PREL: case R_ARM_BASE_PREL:
case R_ARM_PLT32: case R_ARM_PLT32:
@ -891,7 +891,7 @@ static void build_got_entries(TCCState *s1)
} }
break; break;
#elif defined(TCC_TARGET_C67) #elif defined(TCC_TARGET_C67)
case R_C60_GOT32: case R_C60_GOT32:
case R_C60_GOTOFF: case R_C60_GOTOFF:
case R_C60_GOTPC: case R_C60_GOTPC:
case R_C60_PLT32: case R_C60_PLT32:
@ -1547,13 +1547,13 @@ int tcc_output_file(TCCState *s1, const char *filename)
p += 16; p += 16;
} }
#elif defined(TCC_TARGET_ARM) #elif defined(TCC_TARGET_ARM)
int x; int x;
x=s1->got->sh_addr - s1->plt->sh_addr - 12; x=s1->got->sh_addr - s1->plt->sh_addr - 12;
p +=16; p +=16;
while (p < p_end) { while (p < p_end) {
put32(p + 12, x + get32(p + 12) + s1->plt->data - p); put32(p + 12, x + get32(p + 12) + s1->plt->data - p);
p += 16; p += 16;
} }
#elif defined(TCC_TARGET_C67) #elif defined(TCC_TARGET_C67)
/* XXX: TODO */ /* XXX: TODO */
#else #else
@ -1682,8 +1682,8 @@ int tcc_output_file(TCCState *s1, const char *filename)
#endif #endif
#ifdef TCC_TARGET_ARM #ifdef TCC_TARGET_ARM
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
ehdr.e_ident[EI_OSABI] = 0; ehdr.e_ident[EI_OSABI] = 0;
ehdr.e_flags = 4 << 24; ehdr.e_flags = 4 << 24;
#else #else
ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM; ehdr.e_ident[EI_OSABI] = ELFOSABI_ARM;
#endif #endif
@ -1859,7 +1859,7 @@ static int tcc_load_object_file(TCCState *s1,
if (sh->sh_type != SHT_PROGBITS && if (sh->sh_type != SHT_PROGBITS &&
sh->sh_type != SHT_REL && sh->sh_type != SHT_REL &&
#ifdef TCC_ARM_EABI #ifdef TCC_ARM_EABI
sh->sh_type != SHT_ARM_EXIDX && sh->sh_type != SHT_ARM_EXIDX &&
#endif #endif
sh->sh_type != SHT_NOBITS) sh->sh_type != SHT_NOBITS)
continue; continue;
@ -2022,16 +2022,16 @@ static int tcc_load_object_file(TCCState *s1,
return ret; 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 { typedef struct ArchiveHeader {
char ar_name[16]; /* name of this member */ char ar_name[16]; /* name of this member */
char ar_date[12]; /* file mtime */ char ar_date[12]; /* file mtime */
char ar_uid[6]; /* owner uid; printed as decimal */ char ar_uid[6]; /* owner uid; printed as decimal */
char ar_gid[6]; /* owner gid; printed as decimal */ char ar_gid[6]; /* owner gid; printed as decimal */
char ar_mode[8]; /* file mode, printed as octal */ char ar_mode[8]; /* file mode, printed as octal */
char ar_size[10]; /* file size, printed as decimal */ char ar_size[10]; /* file size, printed as decimal */
char ar_fmag[2]; /* should contain ARFMAG */ char ar_fmag[2]; /* should contain ARFMAG */
} ArchiveHeader; } ArchiveHeader;
static int get_be32(const uint8_t *b) 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; ar_names = ar_index + nsyms * 4;
do { do {
bound = 0; bound = 0;
for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) { for(p = ar_names, i = 0; i < nsyms; i++, p += strlen(p)+1) {
sym_index = find_elf_sym(symtab_section, p); sym_index = find_elf_sym(symtab_section, p);
if(sym_index) { if(sym_index) {
sym = &((Elf32_Sym *)symtab_section->data)[sym_index]; sym = &((Elf32_Sym *)symtab_section->data)[sym_index];
if(sym->st_shndx == SHN_UNDEF) { if(sym->st_shndx == SHN_UNDEF) {
off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader); off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
#if 0 #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 #endif
++bound; ++bound;
lseek(fd, off, SEEK_SET); lseek(fd, off, SEEK_SET);
if(tcc_load_object_file(s1, fd, off) < 0) { if(tcc_load_object_file(s1, fd, off) < 0) {
fail: fail:
ret = -1; ret = -1;
goto the_end; goto the_end;
} }
} }
} }
} }
} while(bound); } while(bound);
ret = 0; ret = 0;
the_end: the_end:
@ -2119,8 +2119,8 @@ static int tcc_load_archive(TCCState *s1, int fd)
size = (size + 1) & ~1; size = (size + 1) & ~1;
if (!strcmp(ar_name, "/")) { if (!strcmp(ar_name, "/")) {
/* coff symbol table : we handle it */ /* coff symbol table : we handle it */
if(s1->alacarte_link) if(s1->alacarte_link)
return tcc_load_alacarte(s1, fd, size); return tcc_load_alacarte(s1, fd, size);
} else if (!strcmp(ar_name, "//") || } else if (!strcmp(ar_name, "//") ||
!strcmp(ar_name, "__.SYMDEF") || !strcmp(ar_name, "__.SYMDEF") ||
!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_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) {

1715
tccpe.c

File diff suppressed because it is too large Load Diff

View File

@ -1,115 +1,126 @@
TinyCC-PE TinyCC-PE
--------- ---------
TinyCC (aka TCC) is a small but hyperfast C compiler, TinyCC (aka TCC) is a small but hyperfast C compiler,
written by Fabrice Bellard, written by Fabrice Bellard,
TinyCC-PE is the TinyCC compiler with an extension to TinyCC-PE is the TinyCC compiler with an extension to
write PE executables for MS-Windows. write PE executables for MS-Windows.
Features: Features:
--------- ---------
TinyCC-PE can produce console applications, native windows TinyCC-PE can produce console applications, native windows
GUI programs and DLL's. GUI programs and DLL's.
Most of the features pointed out by Fabrice Bellard for the Most of the features pointed out by Fabrice Bellard for the
original version are still valid, i.e: original version are still valid, i.e:
- SMALL! The package with ~400kb includes a complete C-compiler - SMALL! The package with ~400kb includes a complete C-compiler
with header files for console and GUI applications. with header files for console and GUI applications.
- With the -run switch you can run C-sources without any - With the -run switch you can run C-sources without any
linking directly from the command line. 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 You must use the MinGW and MSYS tools available at
http://www.mingw.org to compile TCC for Windows. Untar the TCC http://www.mingw.org to compile TCC for Windows. Untar the TCC
archive and type in the MSYS shell: archive and type in the MSYS shell:
./configure ./configure
make make
make install make install
TCC is installed in c:\Program Files\tcc TCC is installed in c:\Program Files\tcc
Installation: (from the binary ZIP package) 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.
Just unzip the package to a directory anywhere on your computer.
Examples: Installation: (from the binary ZIP package)
--------- -------------
For the 'Fibonacci' console example type from the command line: Just unzip the package to a directory anywhere on your computer.
tcc examples\fib.c
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 TinyCC-PE searches and reads import definition files similar
tcc examples\hello_dll.c examples\dll.def 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 TinyCC-PE can now link windows resources in coff format as generated
to libraries. by MINGW's windres.exe. For example:
The included 'tiny_impdef' program may be used to make .def files windres -O coff app.rc -o appres.o
for any DLL, e.g for an 'opengl32.def': tcc app.c appres.o -o app.exe
tiny_impdef.exe opengl32.dll
or to the same effect:
tcc -lkernel32 -run tiny_impdef.c opengl32.dll
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:
------------ ------------
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.
Documentation and License: Documentation and License:
-------------------------- --------------------------
TCC is distributed under the GNU Lesser General Public License TCC is distributed under the GNU Lesser General Public License
(see COPYING file). (see COPYING file).
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/
--------------------------------------------
09.Apr.2005 - grischka@users.sourceforge.net
--
grischka@users.sourceforge.net