From 5b113f3ee3bc0f3e476535f39d9c3b4562242976 Mon Sep 17 00:00:00 2001 From: grischka Date: Fri, 13 Nov 2009 17:14:05 +0100 Subject: [PATCH] win32: handle __declspec(dllimport) --- i386-gen.c | 34 ++++++++++++++++++++++++++++++++++ tcc.h | 7 +++++-- tccgen.c | 12 ++++++++++-- tcctok.h | 1 + 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/i386-gen.c b/i386-gen.c index ff5028ef..d44737ac 100644 --- a/i386-gen.c +++ b/i386-gen.c @@ -184,6 +184,32 @@ 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) @@ -191,6 +217,10 @@ void load(int r, SValue *sv) int v, t, ft, fc, fr; SValue v1; +#ifdef TCC_TARGET_PE + if (handle_dllimport(r, sv, load)) + return; +#endif fr = sv->r; ft = sv->type.t; fc = sv->c.ul; @@ -255,6 +285,10 @@ void store(int r, SValue *v) { int fr, bt, ft, fc; +#ifdef TCC_TARGET_PE + if (handle_dllimport(r, v, store)) + return; +#endif ft = v->type.t; fc = v->c.ul; fr = v->r & VT_VALMASK; diff --git a/tcc.h b/tcc.h index bf242e5f..61164d45 100644 --- a/tcc.h +++ b/tcc.h @@ -276,11 +276,13 @@ typedef struct { unsigned func_call : 8, func_args : 8, - func_export : 1; + func_export : 1, + func_import : 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_IMPORT(r) (((func_attr_t*)&(r))->func_import) #define FUNC_ARGS(r) (((func_attr_t*)&(r))->func_args) /* -------------------------------------------------- */ @@ -570,11 +572,12 @@ struct TCCState { #define VT_STATIC 0x00000100 /* static variable */ #define VT_TYPEDEF 0x00000200 /* typedef definition */ #define VT_INLINE 0x00000400 /* inline definition */ +#define VT_IMPORT 0x00004000 /* win32: extern data imported 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) +#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT) #define VT_TYPE (~(VT_STORAGE)) /* token values */ diff --git a/tccgen.c b/tccgen.c index bb7c4e94..0ced4b6b 100644 --- a/tccgen.c +++ b/tccgen.c @@ -1100,8 +1100,9 @@ void gen_opic(int op) } goto general_case; } else if (c2 && (op == '+' || op == '-') && - ((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == - (VT_CONST | VT_SYM) || + (((vtop[-1].r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM) + && !(vtop[-1].sym->type.t & VT_IMPORT)) + || (vtop[-1].r & (VT_VALMASK | VT_LVAL)) == VT_LOCAL)) { /* symbol + constant case */ if (op == '-') @@ -2257,6 +2258,9 @@ static void parse_attribute(AttributeDef *ad) case TOK_DLLEXPORT: FUNC_EXPORT(ad->func_attr) = 1; break; + case TOK_DLLIMPORT: + FUNC_IMPORT(ad->func_attr) = 1; + break; default: if (tcc_state->warn_unsupported) warning("'%s' attribute ignored", get_tok_str(t, NULL)); @@ -5131,6 +5135,10 @@ static void decl(int l) /* NOTE: as GCC, uninitialized global static arrays of null size are considered as extern */ +#ifdef TCC_TARGET_PE + if (FUNC_IMPORT(ad.func_attr)) + type.t |= VT_IMPORT; +#endif external_sym(v, &type, r); } else { type.t |= (btype.t & VT_STATIC); /* Retain "static". */ diff --git a/tcctok.h b/tcctok.h index 6dc47782..ceb11847 100644 --- a/tcctok.h +++ b/tcctok.h @@ -105,6 +105,7 @@ DEF(TOK_FASTCALL2, "__fastcall") DEF(TOK_FASTCALL3, "__fastcall__") DEF(TOK_DLLEXPORT, "dllexport") + DEF(TOK_DLLIMPORT, "dllimport") DEF(TOK_NORETURN1, "noreturn") DEF(TOK_NORETURN2, "__noreturn__") DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p") -- 2.11.4.GIT