at least data symbols coming from dylibs can be used now, as in the below. Note in the example that optind is defined in libc (really in libsystem_c.dylib, reexported from libSystem.B.dylib): static int loc; extern int _optind; int _start(void) { _optind = 0; loc = 42 + _optind; return loc - 42; }
Unified · Split
| @@ -220,6 +220,7 @@ struct macho { · 219 unmodified lines | |||
| 220 | }; | 220 | }; |
| 221 | 221 | ||
| 222 | #define SHT_LINKEDIT (SHT_LOOS + 42) | 222 | #define SHT_LINKEDIT (SHT_LOOS + 42) |
| 223 | #define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */ | ||
| 223 | 224 | ||
| 224 | #define LC_REQ_DYLD 0x80000000 | 225 | #define LC_REQ_DYLD 0x80000000 |
| 225 | #define LC_SYMTAB 0x2 | 226 | #define LC_SYMTAB 0x2 |
| @@ -371,8 +372,18 @@ static int check_symbols(TCCState *s1, struct macho *mo) · 145 unmodified lines | |||
| 371 | mo->iundef = sym_index - 1; | 372 | mo->iundef = sym_index - 1; |
| 372 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) | 373 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) |
| 373 | continue; | 374 | continue; |
| 374 | if (get_sym_attr(s1, elf_index, 0)) | 375 | if (get_sym_attr(s1, elf_index, 0)) { |
| 376 | /* Mark the symbol as coming from a dylib so that | ||
| 377 | relocate_syms doesn't complain. Normally we would have | ||
| 378 | checked that any dylib in fact exports this one, and listed | ||
| 379 | those in s1->dynsymtab, which would cause us to enter this | ||
| 380 | symbol into s1->dynsym, which is checked by relocate_syms. | ||
| 381 | But for now we fake this and regard all undefined as | ||
| 382 | coming from a dylib, and we don't use the dynsymtab/dynsym | ||
| 383 | scheme. */ | ||
| 384 | sym->st_shndx = SHN_FROMDLL; | ||
| 375 | continue; | 385 | continue; |
| 386 | } | ||
| 376 | tcc_error_noabort("undefined symbol '%s'", name); | 387 | tcc_error_noabort("undefined symbol '%s'", name); |
| 377 | ret = -1; | 388 | ret = -1; |
| 378 | } | 389 | } |
| @@ -399,6 +410,8 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn) · 20 unmodified lines | |||
| 399 | ELFW(ST_TYPE)(sym->st_info), name); | 410 | ELFW(ST_TYPE)(sym->st_info), name); |
| 400 | } | 411 | } |
| 401 | if (sym->st_shndx == SHN_UNDEF) | 412 | if (sym->st_shndx == SHN_UNDEF) |
| 413 | tcc_error("should have been rewritten to SHN_FROMDLL"); | ||
| 414 | else if (sym->st_shndx == SHN_FROMDLL) | ||
| 402 | n.n_type = 0 /* N_UNDF */, n.n_sect = 0; | 415 | n.n_type = 0 /* N_UNDF */, n.n_sect = 0; |
| 403 | else if (sym->st_shndx == SHN_ABS) | 416 | else if (sym->st_shndx == SHN_ABS) |
| 404 | n.n_type = 2 /* N_ABS */, n.n_sect = 0; | 417 | n.n_type = 2 /* N_ABS */, n.n_sect = 0; |
| @@ -441,7 +454,7 @@ static int machosymcmp(const void *_a, const void *_b) · 36 unmodified lines | |||
| 441 | - (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL); | 454 | - (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL); |
| 442 | if (r) | 455 | if (r) |
| 443 | return r; | 456 | return r; |
| 444 | r = (sb->st_shndx == SHN_UNDEF) - (sa->st_shndx == SHN_UNDEF); | 457 | r = (sa->st_shndx == SHN_UNDEF) - (sb->st_shndx == SHN_UNDEF); |
| 445 | if (r) | 458 | if (r) |
| 446 | return r; | 459 | return r; |
| 447 | if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) { | 460 | if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) { |