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 | 222 | #define SHT_LINKEDIT (SHT_LOOS + 42) |
| 223 | +#define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */ | |
| 223 | 224 | |
| 224 | 225 | #define LC_REQ_DYLD 0x80000000 |
| 225 | 226 | #define LC_SYMTAB 0x2 |
| @@ -371,8 +372,18 @@ static int check_symbols(TCCState *s1, struct macho *mo) · 145 unmodified lines | ||
| 371 | 372 | mo->iundef = sym_index - 1; |
| 372 | 373 | if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) |
| 373 | 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 | 385 | continue; |
| 386 | + } | |
| 376 | 387 | tcc_error_noabort("undefined symbol '%s'", name); |
| 377 | 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 | 410 | ELFW(ST_TYPE)(sym->st_info), name); |
| 400 | 411 | } |
| 401 | 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 | 415 | n.n_type = 0 /* N_UNDF */, n.n_sect = 0; |
| 403 | 416 | else if (sym->st_shndx == SHN_ABS) |
| 404 | 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 | 454 | - (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL); |
| 442 | 455 | if (r) |
| 443 | 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 | 458 | if (r) |
| 446 | 459 | return r; |
| 447 | 460 | if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) { |