mirror of
git://repo.or.cz/tinycc.git
synced 2026-11-06 22:07:45 +08:00
macos: handle undefined symbols a bit
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;
}
This commit is contained in:
parent
fab8787b23
commit
d82e64c163
17
tccmacho.c
17
tccmacho.c
@ -220,6 +220,7 @@ struct macho {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define SHT_LINKEDIT (SHT_LOOS + 42)
|
#define SHT_LINKEDIT (SHT_LOOS + 42)
|
||||||
|
#define SHN_FROMDLL (SHN_LOOS + 2) /* Symbol is undefined, comes from a DLL */
|
||||||
|
|
||||||
#define LC_REQ_DYLD 0x80000000
|
#define LC_REQ_DYLD 0x80000000
|
||||||
#define LC_SYMTAB 0x2
|
#define LC_SYMTAB 0x2
|
||||||
@ -371,8 +372,18 @@ static int check_symbols(TCCState *s1, struct macho *mo)
|
|||||||
mo->iundef = sym_index - 1;
|
mo->iundef = sym_index - 1;
|
||||||
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
|
||||||
continue;
|
continue;
|
||||||
if (get_sym_attr(s1, elf_index, 0))
|
if (get_sym_attr(s1, elf_index, 0)) {
|
||||||
|
/* Mark the symbol as coming from a dylib so that
|
||||||
|
relocate_syms doesn't complain. Normally we would have
|
||||||
|
checked that any dylib in fact exports this one, and listed
|
||||||
|
those in s1->dynsymtab, which would cause us to enter this
|
||||||
|
symbol into s1->dynsym, which is checked by relocate_syms.
|
||||||
|
But for now we fake this and regard all undefined as
|
||||||
|
coming from a dylib, and we don't use the dynsymtab/dynsym
|
||||||
|
scheme. */
|
||||||
|
sym->st_shndx = SHN_FROMDLL;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
tcc_error_noabort("undefined symbol '%s'", name);
|
tcc_error_noabort("undefined symbol '%s'", name);
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
@ -399,6 +410,8 @@ static void convert_symbol(TCCState *s1, struct macho *mo, struct nlist_64 *pn)
|
|||||||
ELFW(ST_TYPE)(sym->st_info), name);
|
ELFW(ST_TYPE)(sym->st_info), name);
|
||||||
}
|
}
|
||||||
if (sym->st_shndx == SHN_UNDEF)
|
if (sym->st_shndx == SHN_UNDEF)
|
||||||
|
tcc_error("should have been rewritten to SHN_FROMDLL");
|
||||||
|
else if (sym->st_shndx == SHN_FROMDLL)
|
||||||
n.n_type = 0 /* N_UNDF */, n.n_sect = 0;
|
n.n_type = 0 /* N_UNDF */, n.n_sect = 0;
|
||||||
else if (sym->st_shndx == SHN_ABS)
|
else if (sym->st_shndx == SHN_ABS)
|
||||||
n.n_type = 2 /* N_ABS */, n.n_sect = 0;
|
n.n_type = 2 /* N_ABS */, n.n_sect = 0;
|
||||||
@ -441,7 +454,7 @@ static int machosymcmp(const void *_a, const void *_b)
|
|||||||
- (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL);
|
- (ELFW(ST_BIND)(sa->st_info) == STB_LOCAL);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
r = (sb->st_shndx == SHN_UNDEF) - (sa->st_shndx == SHN_UNDEF);
|
r = (sa->st_shndx == SHN_UNDEF) - (sb->st_shndx == SHN_UNDEF);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) {
|
if (ELFW(ST_BIND)(sa->st_info) != STB_LOCAL) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user