mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-13 05:10:07 +08:00
tccpe: improve dllimport
This commit is contained in:
parent
1308e8ebcf
commit
94bf4d2c22
31
i386-gen.c
31
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' */
|
/* load 'r' from value 'sv' */
|
||||||
void load(int r, SValue *sv)
|
void load(int r, SValue *sv)
|
||||||
{
|
{
|
||||||
@ -231,7 +204,7 @@ void load(int r, SValue *sv)
|
|||||||
SValue v1;
|
SValue v1;
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (handle_dllimport(r, sv, load))
|
if (pe_dllimport(r, sv, load))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
@ -299,7 +272,7 @@ void store(int r, SValue *v)
|
|||||||
int fr, bt, ft, fc;
|
int fr, bt, ft, fc;
|
||||||
|
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (handle_dllimport(r, v, store))
|
if (pe_dllimport(r, v, store))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
ft = v->type.t;
|
ft = v->type.t;
|
||||||
|
5
libtcc.c
5
libtcc.c
@ -214,6 +214,7 @@ int tcc_output_coff(TCCState *s1, FILE *f);
|
|||||||
/* tccpe.c */
|
/* tccpe.c */
|
||||||
int pe_load_file(struct TCCState *s1, const char *filename, int fd);
|
int pe_load_file(struct TCCState *s1, const char *filename, int fd);
|
||||||
int pe_output_file(struct TCCState *s1, const char *filename);
|
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 */
|
/* tccasm.c */
|
||||||
#ifdef CONFIG_TCC_ASM
|
#ifdef CONFIG_TCC_ASM
|
||||||
@ -780,6 +781,10 @@ static void put_extern_sym2(Sym *sym, Section *section,
|
|||||||
sym_type = STT_NOTYPE;
|
sym_type = STT_NOTYPE;
|
||||||
} else {
|
} else {
|
||||||
sym_type = STT_OBJECT;
|
sym_type = STT_OBJECT;
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
if (sym->type.t & VT_EXPORT)
|
||||||
|
other |= 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym->type.t & VT_STATIC)
|
if (sym->type.t & VT_STATIC)
|
||||||
|
3
tcc.h
3
tcc.h
@ -576,11 +576,12 @@ struct TCCState {
|
|||||||
#define VT_TYPEDEF 0x00000200 /* typedef definition */
|
#define VT_TYPEDEF 0x00000200 /* typedef definition */
|
||||||
#define VT_INLINE 0x00000400 /* inline definition */
|
#define VT_INLINE 0x00000400 /* inline definition */
|
||||||
#define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */
|
#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 */
|
#define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */
|
||||||
|
|
||||||
/* type mask (except storage) */
|
/* 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))
|
#define VT_TYPE (~(VT_STORAGE))
|
||||||
|
|
||||||
/* token values */
|
/* token values */
|
||||||
|
8
tccgen.c
8
tccgen.c
@ -5143,7 +5143,7 @@ static void decl(int l)
|
|||||||
if (!(type.t & VT_ARRAY))
|
if (!(type.t & VT_ARRAY))
|
||||||
r |= lvalue_type(type.t);
|
r |= lvalue_type(type.t);
|
||||||
has_init = (tok == '=');
|
has_init = (tok == '=');
|
||||||
if ((btype.t & VT_EXTERN) ||
|
if ((btype.t & VT_EXTERN) ||
|
||||||
((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
|
((type.t & VT_ARRAY) && (type.t & VT_STATIC) &&
|
||||||
!has_init && l == VT_CONST && type.ref->c < 0)) {
|
!has_init && l == VT_CONST && type.ref->c < 0)) {
|
||||||
/* external variable */
|
/* external variable */
|
||||||
@ -5163,7 +5163,11 @@ static void decl(int l)
|
|||||||
r |= l;
|
r |= l;
|
||||||
if (has_init)
|
if (has_init)
|
||||||
next();
|
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);
|
has_init, v, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
tccpe.c
38
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
|
struct pe_sort_sym
|
||||||
{
|
{
|
||||||
@ -1431,6 +1419,32 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len)
|
||||||
|
10
x86_64-gen.c
10
x86_64-gen.c
@ -312,6 +312,11 @@ void load(int r, SValue *sv)
|
|||||||
int v, t, ft, fc, fr;
|
int v, t, ft, fc, fr;
|
||||||
SValue v1;
|
SValue v1;
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
if (pe_dllimport(r, sv, load))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
fr = sv->r;
|
fr = sv->r;
|
||||||
ft = sv->type.t;
|
ft = sv->type.t;
|
||||||
fc = sv->c.ul;
|
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 */
|
/* store the REX prefix in this variable when PIC is enabled */
|
||||||
int pic = 0;
|
int pic = 0;
|
||||||
|
|
||||||
|
#ifdef TCC_TARGET_PE
|
||||||
|
if (pe_dllimport(r, v, store))
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
ft = v->type.t;
|
ft = v->type.t;
|
||||||
fc = v->c.ul;
|
fc = v->c.ul;
|
||||||
fr = v->r & VT_VALMASK;
|
fr = v->r & VT_VALMASK;
|
||||||
|
Loading…
Reference in New Issue
Block a user