aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgrischka <grischka>2009-12-19 22:08:52 +0100
committergrischka <grischka>2009-12-19 22:16:21 +0100
commit94bf4d2c227e2073458cabc768d1167e1f3ab2f8 (patch)
treec18160b09f29b7a3dddbdb10756edb1526d98f4e
parent1308e8ebcfba43b4b96b7ef32f1a177b1168665d (diff)
downloadtinycc-94bf4d2c227e2073458cabc768d1167e1f3ab2f8.tar.gz
tinycc-94bf4d2c227e2073458cabc768d1167e1f3ab2f8.tar.bz2
tccpe: improve dllimport
-rw-r--r--i386-gen.c31
-rw-r--r--libtcc.c5
-rw-r--r--tcc.h3
-rw-r--r--tccgen.c8
-rw-r--r--tccpe.c38
-rw-r--r--x86_64-gen.c10
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
{
@@ -1432,6 +1420,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;