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 | /* load 'r' from value 'sv' */ | 200 | /* load 'r' from value 'sv' */ |
| 228 | void load(int r, SValue *sv) | 201 | void load(int r, SValue *sv) |
| 229 | { | 202 | { |
| @@ -231,7 +204,7 @@ void load(int r, SValue *sv) · 1 unmodified line | |||
| 231 | SValue v1; | 204 | SValue v1; |
| 232 | 205 | ||
| 233 | #ifdef TCC_TARGET_PE | 206 | #ifdef TCC_TARGET_PE |
| 234 | if (handle_dllimport(r, sv, load)) | 207 | if (pe_dllimport(r, sv, load)) |
| 235 | return; | 208 | return; |
| 236 | #endif | 209 | #endif |
| 237 | fr = sv->r; | 210 | fr = sv->r; |
| @@ -299,7 +272,7 @@ void store(int r, SValue *v) · 61 unmodified lines | |||
| 299 | int fr, bt, ft, fc; | 272 | int fr, bt, ft, fc; |
| 300 | 273 | ||
| 301 | #ifdef TCC_TARGET_PE | 274 | #ifdef TCC_TARGET_PE |
| 302 | if (handle_dllimport(r, v, store)) | 275 | if (pe_dllimport(r, v, store)) |
| 303 | return; | 276 | return; |
| 304 | #endif | 277 | #endif |
| 305 | ft = v->type.t; | 278 | ft = v->type.t; |
| @@ -214,6 +214,7 @@ int tcc_output_coff(TCCState *s1, FILE *f); · 213 unmodified lines | |||
| 214 | /* tccpe.c */ | 214 | /* tccpe.c */ |
| 215 | int pe_load_file(struct TCCState *s1, const char *filename, int fd); | 215 | int pe_load_file(struct TCCState *s1, const char *filename, int fd); |
| 216 | int pe_output_file(struct TCCState *s1, const char *filename); | 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 | /* tccasm.c */ | 219 | /* tccasm.c */ |
| 219 | #ifdef CONFIG_TCC_ASM | 220 | #ifdef CONFIG_TCC_ASM |
| @@ -780,6 +781,10 @@ static void put_extern_sym2(Sym *sym, Section *section, · 560 unmodified lines | |||
| 780 | sym_type = STT_NOTYPE; | 781 | sym_type = STT_NOTYPE; |
| 781 | } else { | 782 | } else { |
| 782 | sym_type = STT_OBJECT; | 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 | if (sym->type.t & VT_STATIC) | 790 | if (sym->type.t & VT_STATIC) |
| @@ -576,11 +576,12 @@ struct TCCState { · 575 unmodified lines | |||
| 576 | #define VT_TYPEDEF 0x00000200 /* typedef definition */ | 576 | #define VT_TYPEDEF 0x00000200 /* typedef definition */ |
| 577 | #define VT_INLINE 0x00000400 /* inline definition */ | 577 | #define VT_INLINE 0x00000400 /* inline definition */ |
| 578 | #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ | 578 | #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ |
| 579 | #define VT_EXPORT 0x00008000 /* win32: data exported from dll */ | ||
| 579 | 580 | ||
| 580 | #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ | 581 | #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ |
| 581 | 582 | ||
| 582 | /* type mask (except storage) */ | 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 | #define VT_TYPE (~(VT_STORAGE)) | 585 | #define VT_TYPE (~(VT_STORAGE)) |
| 585 | 586 | ||
| 586 | /* token values */ | 587 | /* token values */ |
| @@ -5143,7 +5143,7 @@ static void decl(int l) · 5142 unmodified lines | |||
| 5143 | if (!(type.t & VT_ARRAY)) | 5143 | if (!(type.t & VT_ARRAY)) |
| 5144 | r |= lvalue_type(type.t); | 5144 | r |= lvalue_type(type.t); |
| 5145 | has_init = (tok == '='); | 5145 | has_init = (tok == '='); |
| 5146 | if ((btype.t & VT_EXTERN) || | 5146 | if ((btype.t & VT_EXTERN) || |
| 5147 | ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && | 5147 | ((type.t & VT_ARRAY) && (type.t & VT_STATIC) && |
| 5148 | !has_init && l == VT_CONST && type.ref->c < 0)) { | 5148 | !has_init && l == VT_CONST && type.ref->c < 0)) { |
| 5149 | /* external variable */ | 5149 | /* external variable */ |
| @@ -5163,7 +5163,11 @@ static void decl(int l) · 13 unmodified lines | |||
| 5163 | r |= l; | 5163 | r |= l; |
| 5164 | if (has_init) | 5164 | if (has_init) |
| 5165 | next(); | 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 | has_init, v, l); | 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 | struct pe_sort_sym | 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 | #endif | 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 | ST_FN int read_mem(FILE *fp, unsigned offset, void *buffer, unsigned len) | 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 | int v, t, ft, fc, fr; | 312 | int v, t, ft, fc, fr; |
| 313 | SValue v1; | 313 | SValue v1; |
| 314 | 314 | ||
| 315 | #ifdef TCC_TARGET_PE | ||
| 316 | if (pe_dllimport(r, sv, load)) | ||
| 317 | return; | ||
| 318 | #endif | ||
| 319 | |||
| 315 | fr = sv->r; | 320 | fr = sv->r; |
| 316 | ft = sv->type.t; | 321 | ft = sv->type.t; |
| 317 | fc = sv->c.ul; | 322 | fc = sv->c.ul; |
| @@ -439,6 +444,11 @@ void store(int r, SValue *v) · 121 unmodified lines | |||
| 439 | /* store the REX prefix in this variable when PIC is enabled */ | 444 | /* store the REX prefix in this variable when PIC is enabled */ |
| 440 | int pic = 0; | 445 | int pic = 0; |
| 441 | 446 | ||
| 447 | #ifdef TCC_TARGET_PE | ||
| 448 | if (pe_dllimport(r, v, store)) | ||
| 449 | return; | ||
| 450 | #endif | ||
| 451 | |||
| 442 | ft = v->type.t; | 452 | ft = v->type.t; |
| 443 | fc = v->c.ul; | 453 | fc = v->c.ul; |
| 444 | fr = v->r & VT_VALMASK; | 454 | fr = v->r & VT_VALMASK; |