From 94bf4d2c227e2073458cabc768d1167e1f3ab2f8 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 19 Dec 2009 22:08:52 +0100 Subject: [PATCH] tccpe: improve dllimport --- i386-gen.c | 31 ++----------------------------- libtcc.c | 5 +++++ tcc.h | 3 ++- tccgen.c | 8 ++++++-- tccpe.c | 38 ++++++++++++++++++++++++++------------ x86_64-gen.c | 10 ++++++++++ 6 files changed, 51 insertions(+), 44 deletions(-) diff --git a/i386-gen.c b/i386-gen.c index 93af341..0bc41aa 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -197,33 +197,6 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c) } } -#ifdef TCC_TARGET_PE -static void mk_pointer(CType *type); -static void indir(void); - -int handle_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)) -{ - if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST)) - return 0; - if (0 == (sv->sym->type.t & VT_IMPORT)) - return 0; - - printf("import %d %04x %s\n", r, ind, get_tok_str(sv->sym->v, NULL)); - - sv->sym->type.t &= ~VT_IMPORT; - ++vtop; - - *vtop = *sv; - mk_pointer(&vtop->type); - indir(); - fn(r, vtop); - - --vtop; - sv->sym->type.t |= VT_IMPORT; - return 1; -} -#endif - /* load 'r' from value 'sv' */ void load(int r, SValue *sv) { @@ -231,7 +204,7 @@ void load(int r, SValue *sv) SValue v1; #ifdef TCC_TARGET_PE - if (handle_dllimport(r, sv, load)) + if (pe_dllimport(r, sv, load)) return; #endif fr = sv->r; @@ -299,7 +272,7 @@ void store(int r, SValue *v) int fr, bt, ft, fc; #ifdef TCC_TARGET_PE - if (handle_dllimport(r, v, store)) + if (pe_dllimport(r, v, store)) return; #endif ft = v->type.t; diff --git a/libtcc.c b/libtcc.c index 823078e..5b11396 100644 --- a/libtcc.c +++ b/libtcc.c @@ -214,6 +214,7 @@ int tcc_output_coff(TCCState *s1, FILE *f); /* tccpe.c */ int pe_load_file(struct TCCState *s1, const char *filename, int fd); int pe_output_file(struct TCCState *s1, const char *filename); +int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)); /* tccasm.c */ #ifdef CONFIG_TCC_ASM @@ -780,6 +781,10 @@ static void put_extern_sym2(Sym *sym, Section *section, sym_type = STT_NOTYPE; } else { sym_type = STT_OBJECT; +#ifdef TCC_TARGET_PE + if (sym->type.t & VT_EXPORT) + other |= 1; +#endif } if (sym->type.t & VT_STATIC) diff --git a/tcc.h b/tcc.h index 430eb79..59fe333 100644 --- a/tcc.h +++ b/tcc.h @@ -576,11 +576,12 @@ struct TCCState { #define VT_TYPEDEF 0x00000200 /* typedef definition */ #define VT_INLINE 0x00000400 /* inline definition */ #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ +#define VT_EXPORT 0x00008000 /* win32: data exported from dll */ #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ /* type mask (except storage) */ -#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT) +#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT) #define VT_TYPE (~(VT_STORAGE)) /* token values */ diff --git a/tccgen.c b/tccgen.c index 3c45646..7be1f22 100644 --- a/tccgen.c +++ b/tccgen.c @@ -5143,7 +5143,7 @@ static void decl(int l) if (!(type.t & VT_ARRAY)) r |= lvalue_type(type.t); has_init = (tok == '='); - if ((btype.t & VT_EXTERN) || + if ((btype.t & VT_EXTERN) || ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && !has_init && l == VT_CONST && type.ref->c < 0)) { /* external variable */ @@ -5163,7 +5163,11 @@ static void decl(int l) r |= l; if (has_init) next(); - decl_initializer_alloc(&type, &ad, r, +#ifdef TCC_TARGET_PE + if (ad.func_export) + type.t |= VT_EXPORT; +#endif + decl_initializer_alloc(&type, &ad, r, has_init, v, l); } } diff --git a/tccpe.c b/tccpe.c index 41de3f6..3a997bf 100644 --- a/tccpe.c +++ b/tccpe.c @@ -853,18 +853,6 @@ ST_FN void pe_build_imports(struct pe_info *pe) } /* ------------------------------------------------------------- */ -/* - For now only functions are exported. Export of data - would work, but import requires compiler support to - do an additional indirection. - - For instance: - __declspec(dllimport) extern int something; - - needs to be translated to: - - *(int*)something -*/ struct pe_sort_sym { @@ -1431,6 +1419,32 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname) } #endif +/* ------------------------------------------------------------- */ +/* helper function for load/store to insert one more indirection */ + +int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)) +{ + int t; + if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST)) + return 0; + t = sv->sym->type.t; + if (0 == (t & VT_IMPORT)) + return 0; + + sv->sym->type.t = t & ~VT_IMPORT; + //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL)); + + *++vtop = *sv; + vtop->type.t &= ~(VT_ARRAY|VT_IMPORT); + mk_pointer(&vtop->type); + indir(); + fn(r, vtop); + --vtop; + + sv->sym->type.t = t; + return 1; +} + /* ------------------------------------------------------------- */ ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len) diff --git a/x86_64-gen.c b/x86_64-gen.c index 9f05889..86ec4ea 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -312,6 +312,11 @@ void load(int r, SValue *sv) int v, t, ft, fc, fr; SValue v1; +#ifdef TCC_TARGET_PE + if (pe_dllimport(r, sv, load)) + return; +#endif + fr = sv->r; ft = sv->type.t; fc = sv->c.ul; @@ -439,6 +444,11 @@ void store(int r, SValue *v) /* store the REX prefix in this variable when PIC is enabled */ int pic = 0; +#ifdef TCC_TARGET_PE + if (pe_dllimport(r, v, store)) + return; +#endif + ft = v->type.t; fc = v->c.ul; fr = v->r & VT_VALMASK;