Unified · Split
| @@ -197,33 +197,6 @@ static void gen_modrm(int op_reg, int r, Sym *sym, int c) · 196 unmodified lines | ||
| 197 | 197 | } |
| 198 | 198 | } |
| 199 | 199 | |
| 200 | −#ifdef TCC_TARGET_PE | |
| 201 | −static void mk_pointer(CType *type); | |
| 202 | −static void indir(void); | |
| 203 | − | |
| 204 | −int handle_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)) | |
| 205 | −{ | |
| 206 | − if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST)) | |
| 207 | − return 0; | |
| 208 | − if (0 == (sv->sym->type.t & VT_IMPORT)) | |
| 209 | − return 0; | |
| 210 | − | |
| 211 | − printf("import %d %04x %s\n", r, ind, get_tok_str(sv->sym->v, NULL)); | |
| 212 | − | |
| 213 | − sv->sym->type.t &= ~VT_IMPORT; | |
| 214 | − ++vtop; | |
| 215 | − | |
| 216 | − *vtop = *sv; | |
| 217 | − mk_pointer(&vtop->type); | |
| 218 | − indir(); | |
| 219 | − fn(r, vtop); | |
| 220 | − | |
| 221 | − --vtop; | |
| 222 | − sv->sym->type.t |= VT_IMPORT; | |
| 223 | − return 1; | |
| 224 | −} | |
| 225 | −#endif | |
| 226 | − | |
| 227 | 200 | /* load 'r' from value 'sv' */ |
| 228 | 201 | void load(int r, SValue *sv) |
| 229 | 202 | { |
| @@ -231,7 +204,7 @@ void load(int r, SValue *sv) · 1 unmodified line | ||
| 231 | 204 | SValue v1; |
| 232 | 205 | |
| 233 | 206 | #ifdef TCC_TARGET_PE |
| 234 | − if (handle_dllimport(r, sv, load)) | |
| 207 | + if (pe_dllimport(r, sv, load)) | |
| 235 | 208 | return; |
| 236 | 209 | #endif |
| 237 | 210 | fr = sv->r; |
| @@ -299,7 +272,7 @@ void store(int r, SValue *v) · 61 unmodified lines | ||
| 299 | 272 | int fr, bt, ft, fc; |
| 300 | 273 | |
| 301 | 274 | #ifdef TCC_TARGET_PE |
| 302 | − if (handle_dllimport(r, v, store)) | |
| 275 | + if (pe_dllimport(r, v, store)) | |
| 303 | 276 | return; |
| 304 | 277 | #endif |
| 305 | 278 | ft = v->type.t; |
| @@ -214,6 +214,7 @@ int tcc_output_coff(TCCState *s1, FILE *f); · 213 unmodified lines | ||
| 214 | 214 | /* tccpe.c */ |
| 215 | 215 | int pe_load_file(struct TCCState *s1, const char *filename, int fd); |
| 216 | 216 | int pe_output_file(struct TCCState *s1, const char *filename); |
| 217 | +int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)); | |
| 217 | 218 | |
| 218 | 219 | /* tccasm.c */ |
| 219 | 220 | #ifdef CONFIG_TCC_ASM |
| @@ -780,6 +781,10 @@ static void put_extern_sym2(Sym *sym, Section *section, · 560 unmodified lines | ||
| 780 | 781 | sym_type = STT_NOTYPE; |
| 781 | 782 | } else { |
| 782 | 783 | sym_type = STT_OBJECT; |
| 784 | +#ifdef TCC_TARGET_PE | |
| 785 | + if (sym->type.t & VT_EXPORT) | |
| 786 | + other |= 1; | |
| 787 | +#endif | |
| 783 | 788 | } |
| 784 | 789 | |
| 785 | 790 | if (sym->type.t & VT_STATIC) |
| @@ -576,11 +576,12 @@ struct TCCState { · 575 unmodified lines | ||
| 576 | 576 | #define VT_TYPEDEF 0x00000200 /* typedef definition */ |
| 577 | 577 | #define VT_INLINE 0x00000400 /* inline definition */ |
| 578 | 578 | #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ |
| 579 | +#define VT_EXPORT 0x00008000 /* win32: data exported from dll */ | |
| 579 | 580 | |
| 580 | 581 | #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ |
| 581 | 582 | |
| 582 | 583 | /* type mask (except storage) */ |
| 583 | −#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT) | |
| 584 | +#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT) | |
| 584 | 585 | #define VT_TYPE (~(VT_STORAGE)) |
| 585 | 586 | |
| 586 | 587 | /* token values */ |
| @@ -5143,7 +5143,7 @@ static void decl(int l) · 5142 unmodified lines | ||
| 5143 | 5143 | if (!(type.t & VT_ARRAY)) |
| 5144 | 5144 | r |= lvalue_type(type.t); |
| 5145 | 5145 | has_init = (tok == '='); |
| 5146 | − if ((btype.t & VT_EXTERN) || | |
| 5146 | + if ((btype.t & VT_EXTERN) || | |
| 5147 | 5147 | ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && |
| 5148 | 5148 | !has_init && l == VT_CONST && type.ref->c < 0)) { |
| 5149 | 5149 | /* external variable */ |
| @@ -5163,7 +5163,11 @@ static void decl(int l) · 13 unmodified lines | ||
| 5163 | 5163 | r |= l; |
| 5164 | 5164 | if (has_init) |
| 5165 | 5165 | next(); |
| 5166 | − decl_initializer_alloc(&type, &ad, r, | |
| 5166 | +#ifdef TCC_TARGET_PE | |
| 5167 | + if (ad.func_export) | |
| 5168 | + type.t |= VT_EXPORT; | |
| 5169 | +#endif | |
| 5170 | + decl_initializer_alloc(&type, &ad, r, | |
| 5167 | 5171 | has_init, v, l); |
| 5168 | 5172 | } |
| 5169 | 5173 | } |
| @@ -853,18 +853,6 @@ ST_FN void pe_build_imports(struct pe_info *pe) · 852 unmodified lines | ||
| 853 | 853 | } |
| 854 | 854 | |
| 855 | 855 | /* ------------------------------------------------------------- */ |
| 856 | −/* | |
| 857 | − For now only functions are exported. Export of data | |
| 858 | − would work, but import requires compiler support to | |
| 859 | − do an additional indirection. | |
| 860 | − | |
| 861 | − For instance: | |
| 862 | − __declspec(dllimport) extern int something; | |
| 863 | − | |
| 864 | − needs to be translated to: | |
| 865 | − | |
| 866 | − *(int*)something | |
| 867 | −*/ | |
| 868 | 856 | |
| 869 | 857 | struct pe_sort_sym |
| 870 | 858 | { |
| @@ -1431,6 +1419,32 @@ ST_FN void pe_print_sections(TCCState *s1, const char *fname) · 560 unmodified lines | ||
| 1431 | 1419 | } |
| 1432 | 1420 | #endif |
| 1433 | 1421 | |
| 1422 | +/* ------------------------------------------------------------- */ | |
| 1423 | +/* helper function for load/store to insert one more indirection */ | |
| 1424 | + | |
| 1425 | +int pe_dllimport(int r, SValue *sv, void (*fn)(int r, SValue *sv)) | |
| 1426 | +{ | |
| 1427 | + int t; | |
| 1428 | + if ((sv->r & (VT_VALMASK|VT_SYM|VT_CONST)) != (VT_SYM|VT_CONST)) | |
| 1429 | + return 0; | |
| 1430 | + t = sv->sym->type.t; | |
| 1431 | + if (0 == (t & VT_IMPORT)) | |
| 1432 | + return 0; | |
| 1433 | + | |
| 1434 | + sv->sym->type.t = t & ~VT_IMPORT; | |
| 1435 | + //printf("import %x %04x %s\n", t, ind, get_tok_str(sv->sym->v, NULL)); | |
| 1436 | + | |
| 1437 | + *++vtop = *sv; | |
| 1438 | + vtop->type.t &= ~(VT_ARRAY|VT_IMPORT); | |
| 1439 | + mk_pointer(&vtop->type); | |
| 1440 | + indir(); | |
| 1441 | + fn(r, vtop); | |
| 1442 | + --vtop; | |
| 1443 | + | |
| 1444 | + sv->sym->type.t = t; | |
| 1445 | + return 1; | |
| 1446 | +} | |
| 1447 | + | |
| 1434 | 1448 | /* ------------------------------------------------------------- */ |
| 1435 | 1449 | |
| 1436 | 1450 | ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len) |
| @@ -312,6 +312,11 @@ void load(int r, SValue *sv) · 311 unmodified lines | ||
| 312 | 312 | int v, t, ft, fc, fr; |
| 313 | 313 | SValue v1; |
| 314 | 314 | |
| 315 | +#ifdef TCC_TARGET_PE | |
| 316 | + if (pe_dllimport(r, sv, load)) | |
| 317 | + return; | |
| 318 | +#endif | |
| 319 | + | |
| 315 | 320 | fr = sv->r; |
| 316 | 321 | ft = sv->type.t; |
| 317 | 322 | fc = sv->c.ul; |
| @@ -439,6 +444,11 @@ void store(int r, SValue *v) · 121 unmodified lines | ||
| 439 | 444 | /* store the REX prefix in this variable when PIC is enabled */ |
| 440 | 445 | int pic = 0; |
| 441 | 446 | |
| 447 | +#ifdef TCC_TARGET_PE | |
| 448 | + if (pe_dllimport(r, v, store)) | |
| 449 | + return; | |
| 450 | +#endif | |
| 451 | + | |
| 442 | 452 | ft = v->type.t; |
| 443 | 453 | fc = v->c.ul; |
| 444 | 454 | fr = v->r & VT_VALMASK; |