Skip to content
GitLab
菜单
项目
群组
代码片段
帮助
帮助
支持
社区论坛
快捷键
?
提交反馈
登录/注册
切换导航
菜单
打开侧边栏
Panda
TinyCC
提交
588d64c5
提交
588d64c5
编辑于
7月 06, 2021
作者:
Sushant Pandurangi
浏览文件
(merge) macOS11+ dynamic linker support
上级
c4a2c524
cca4ece0
变更
3
Hide whitespace changes
Inline
Side-by-side
libtcc.c
浏览文件 @
588d64c5
...
...
@@ -855,6 +855,29 @@ LIBTCCAPI void tcc_delete(TCCState *s1)
#endif
}
/* Looks for the active developer SDK set by xcode-select (or the default
one set during installation.) */
#define SZPAIR(s) s "", sizeof(s)-1
ST_FUNC
int
tcc_add_macos_sdkpath
(
TCCState
*
s
)
{
char
*
sdkroot
=
NULL
,
*
pos
=
NULL
;
void
*
xcs
=
dlopen
(
"libxcselect.dylib"
,
RTLD_GLOBAL
|
RTLD_LAZY
);
CString
path
=
{};
int
(
*
f
)(
unsigned
int
,
char
**
)
=
dlsym
(
xcs
,
"xcselect_host_sdk_path"
);
if
(
f
)
f
(
1
,
&
sdkroot
);
if
(
!
sdkroot
)
return
-
1
;
pos
=
strstr
(
sdkroot
,
"SDKs/MacOSX"
);
if
(
!
pos
)
return
-
1
;
cstr_cat
(
&
path
,
sdkroot
,
pos
-
sdkroot
);
cstr_cat
(
&
path
,
SZPAIR
(
"SDKs/MacOSX.sdk/usr/lib
\0
"
)
);
tcc_add_library_path
(
s
,
(
char
*
)
path
.
data
);
cstr_free
(
&
path
);
tcc_free
(
sdkroot
);
return
0
;
}
#undef SZPAIR
LIBTCCAPI
int
tcc_set_output_type
(
TCCState
*
s
,
int
output_type
)
{
s
->
output_type
=
output_type
;
...
...
@@ -881,7 +904,11 @@ LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
}
tcc_add_library_path
(
s
,
CONFIG_TCC_LIBPATHS
);
#ifdef TCC_TARGET_MACHO
if
(
tcc_add_macos_sdkpath
(
s
)
!=
0
)
{
tcc_add_library_path
(
s
,
CONFIG_OSX_SDK_FALLBACK
);
}
#endif
#ifdef TCC_TARGET_PE
# ifdef _WIN32
if
(
!
s
->
nostdlib
&&
output_type
!=
TCC_OUTPUT_OBJ
)
...
...
@@ -979,6 +1006,10 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size)
}
#endif
#ifdef TCC_TARGET_MACHO
ST_FUNC
const
char
*
macho_tbd_soname
(
const
char
*
filename
);
#endif
ST_FUNC
int
tcc_add_file_internal
(
TCCState
*
s1
,
const
char
*
filename
,
int
flags
)
{
int
fd
,
ret
=
-
1
;
...
...
@@ -1006,7 +1037,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
lseek
(
fd
,
0
,
SEEK_SET
);
#ifdef TCC_TARGET_MACHO
if
(
0
==
obj_type
&&
0
==
strcmp
(
tcc_fileextension
(
filename
),
".dylib"
))
if
(
0
==
obj_type
&&
(
0
==
strcmp
(
tcc_fileextension
(
filename
),
".dylib"
)
||
0
==
strcmp
(
tcc_fileextension
(
filename
),
".tbd"
)))
obj_type
=
AFF_BINTYPE_DYN
;
#endif
...
...
@@ -1027,9 +1060,15 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
case
AFF_BINTYPE_DYN
:
if
(
s1
->
output_type
==
TCC_OUTPUT_MEMORY
)
{
#ifdef TCC_IS_NATIVE
void
*
dl
=
dlopen
(
filename
,
RTLD_GLOBAL
|
RTLD_LAZY
);
void
*
dl
;
const
char
*
soname
=
filename
;
# ifdef TCC_TARGET_MACHO
if
(
!
strcmp
(
tcc_fileextension
(
filename
),
".tbd"
))
soname
=
macho_tbd_soname
(
filename
);
# endif
dl
=
dlopen
(
soname
,
RTLD_GLOBAL
|
RTLD_LAZY
);
if
(
dl
)
{
tcc_add_dllref
(
s1
,
file
name
)
->
handle
=
dl
;
tcc_add_dllref
(
s1
,
so
name
)
->
handle
=
dl
;
ret
=
0
;
}
#endif
...
...
@@ -1142,8 +1181,8 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
static
const
char
*
const
libs
[]
=
{
"%s/%s.def"
,
"%s/lib%s.def"
,
"%s/%s.dll"
,
"%s/lib%s.dll"
,
"%s/lib%s.a"
,
NULL
};
const
char
*
const
*
pp
=
s
->
static_link
?
libs
+
4
:
libs
;
#elif defined TCC_TARGET_MACHO
static
const
char
*
const
libs
[]
=
{
"%s/lib%s.dylib"
,
"%s/lib%s.a"
,
NULL
};
const
char
*
const
*
pp
=
s
->
static_link
?
libs
+
1
:
libs
;
static
const
char
*
const
libs
[]
=
{
"%s/lib%s.dylib"
,
"%s/lib%s.tbd"
,
"%s/lib%s.a"
,
NULL
};
const
char
*
const
*
pp
=
s
->
static_link
?
libs
+
2
:
libs
;
#elif defined TARGETOS_OpenBSD
static
const
char
*
const
libs
[]
=
{
"%s/lib%s.so.*"
,
"%s/lib%s.a"
,
NULL
};
const
char
*
const
*
pp
=
s
->
static_link
?
libs
+
1
:
libs
;
...
...
tcc.h
浏览文件 @
588d64c5
...
...
@@ -42,6 +42,7 @@
#ifndef _WIN32
# include <unistd.h>
# include <sys/time.h>
# include <sys/stat.h>
# ifndef CONFIG_TCC_STATIC
# include <dlfcn.h>
# endif
...
...
@@ -278,6 +279,15 @@ extern long double strtold (const char *__nptr, char **__endptr);
ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
# ifdef TCC_TARGET_MACHO
# define CONFIG_OSX_SDK1 \
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
# define CONFIG_OSX_SDK2 \
"/Applications/Xcode.app/Developer/SDKs/MacOSX.sdk"
# define CONFIG_OSX_SDK_FALLBACK \
ALSO_TRIPLET(CONFIG_OSX_SDK1 "/usr/" CONFIG_LDDIR) \
":" ALSO_TRIPLET(CONFIG_OSX_SDK2 "/usr/" CONFIG_LDDIR)
# endif
# endif
#endif
...
...
tccmacho.c
浏览文件 @
588d64c5
...
...
@@ -837,7 +837,102 @@ static uint32_t macho_swap32(uint32_t x)
}
#define SWAP(x) (swap ? macho_swap32(x) : (x))
ST_FUNC
int
macho_load_dll
(
TCCState
*
s1
,
int
fd
,
const
char
*
filename
,
int
lev
)
ST_FUNC
int
macho_add_dllref
(
TCCState
*
s1
,
int
lev
,
const
char
*
soname
)
{
/* if the dll is already loaded, do not load it */
DLLReference
*
dllref
;
int
i
;
for
(
i
=
0
;
i
<
s1
->
nb_loaded_dlls
;
i
++
)
{
dllref
=
s1
->
loaded_dlls
[
i
];
if
(
!
strcmp
(
soname
,
dllref
->
name
))
{
/* but update level if needed */
if
(
lev
<
dllref
->
level
)
dllref
->
level
=
lev
;
return
-
1
;
}
}
dllref
=
tcc_mallocz
(
sizeof
(
DLLReference
)
+
strlen
(
soname
));
dllref
->
level
=
lev
;
strcpy
(
dllref
->
name
,
soname
);
dynarray_add
(
&
s1
->
loaded_dlls
,
&
s1
->
nb_loaded_dlls
,
dllref
);
return
0
;
}
#define tbd_parse_movepast(s) \
(pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
#define tbd_parse_movetoany(cs) (pos = strpbrk(pos, cs))
#define tbd_parse_skipws while (*pos && (*pos==' '||*pos=='\n')) ++pos
#define tbd_parse_tramplequote if(*pos=='\''||*pos=='"') tbd_parse_trample
#define tbd_parse_tramplespace if(*pos==' ') tbd_parse_trample
#define tbd_parse_trample *pos++=0
ST_FUNC
const
char
*
macho_tbd_soname
(
const
char
*
filename
)
{
char
*
soname
,
*
data
,
*
pos
,
*
ret
;
struct
stat
sb
;
int
fd
=
open
(
filename
,
O_RDONLY
);
if
(
fd
<
0
)
return
filename
;
fstat
(
fd
,
&
sb
);
data
=
load_data
(
fd
,
0
,
sb
.
st_size
+
1
);
data
[
sb
.
st_size
]
=
0
;
pos
=
data
;
if
(
!
tbd_parse_movepast
(
"install-name: "
))
return
filename
;
tbd_parse_skipws
;
tbd_parse_tramplequote
;
soname
=
pos
;
if
(
!
tbd_parse_movetoany
(
"
\n
\"
'"
))
return
filename
;
tbd_parse_trample
;
ret
=
tcc_mallocz
(
strlen
(
soname
)
+
1
);
strcpy
(
ret
,
soname
);
// soname = strdup(soname);
tcc_free
(
data
);
return
ret
;
}
ST_FUNC
int
macho_load_tbd
(
TCCState
*
s1
,
int
fd
,
const
char
*
filename
,
int
lev
)
{
char
*
soname
,
*
data
,
*
pos
;
struct
stat
sb
;
fstat
(
fd
,
&
sb
);
data
=
load_data
(
fd
,
0
,
sb
.
st_size
+
1
);
data
[
sb
.
st_size
]
=
0
;
pos
=
data
;
if
(
!
tbd_parse_movepast
(
"install-name: "
))
return
-
1
;
tbd_parse_skipws
;
tbd_parse_tramplequote
;
soname
=
pos
;
if
(
!
tbd_parse_movetoany
(
"
\n
\"
'"
))
return
-
1
;
tbd_parse_trample
;
if
(
macho_add_dllref
(
s1
,
lev
,
soname
)
!=
0
)
goto
the_end
;
while
(
pos
)
{
char
*
sym
=
NULL
;
int
cont
=
1
;
if
(
!
tbd_parse_movepast
(
"symbols: "
))
break
;
if
(
!
tbd_parse_movepast
(
"["
))
break
;
while
(
cont
)
{
tbd_parse_skipws
;
tbd_parse_tramplequote
;
sym
=
pos
;
if
(
!
tbd_parse_movetoany
(
",]
\"
'"
))
break
;
tbd_parse_tramplequote
;
tbd_parse_tramplespace
;
tbd_parse_skipws
;
if
(
*
pos
==
0
||*
pos
==
']'
)
cont
=
0
;
tbd_parse_trample
;
set_elf_sym
(
s1
->
dynsymtab_section
,
0
,
0
,
ELFW
(
ST_INFO
)(
STB_GLOBAL
,
STT_NOTYPE
),
0
,
SHN_UNDEF
,
sym
);
}
}
the_end:
tcc_free
(
data
);
return
0
;
}
ST_FUNC
int
macho_load_dylib
(
TCCState
*
s1
,
int
fd
,
const
char
*
filename
,
int
lev
)
{
unsigned
char
buf
[
sizeof
(
struct
mach_header_64
)];
void
*
buf2
;
...
...
@@ -853,7 +948,6 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev)
uint32_t
strsize
=
0
;
uint32_t
iextdef
=
0
;
uint32_t
nextdef
=
0
;
DLLReference
*
dllref
;
again:
if
(
full_read
(
fd
,
buf
,
sizeof
(
buf
))
!=
sizeof
(
buf
))
...
...
@@ -934,20 +1028,8 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev)
lc
=
(
struct
load_command
*
)
((
char
*
)
lc
+
lc
->
cmdsize
);
}
/* if the dll is already loaded, do not load it */
for
(
i
=
0
;
i
<
s1
->
nb_loaded_dlls
;
i
++
)
{
dllref
=
s1
->
loaded_dlls
[
i
];
if
(
!
strcmp
(
soname
,
dllref
->
name
))
{
/* but update level if needed */
if
(
lev
<
dllref
->
level
)
dllref
->
level
=
lev
;
goto
the_end
;
}
}
dllref
=
tcc_mallocz
(
sizeof
(
DLLReference
)
+
strlen
(
soname
));
dllref
->
level
=
lev
;
strcpy
(
dllref
->
name
,
soname
);
dynarray_add
(
&
s1
->
loaded_dlls
,
&
s1
->
nb_loaded_dlls
,
dllref
);
if
(
0
!=
macho_add_dllref
(
s1
,
lev
,
soname
))
goto
the_end
;
if
(
!
nsyms
||
!
nextdef
)
tcc_warning
(
"%s doesn't export any symbols?"
,
filename
);
...
...
@@ -972,3 +1054,10 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev)
tcc_free
(
buf2
);
return
0
;
}
ST_FUNC
int
macho_load_dll
(
TCCState
*
s1
,
int
fd
,
const
char
*
filename
,
int
lev
)
{
return
strcmp
(
tcc_fileextension
(
filename
),
".tbd"
)
==
0
?
macho_load_tbd
(
s1
,
fd
,
filename
,
lev
)
:
macho_load_dylib
(
s1
,
fd
,
filename
,
lev
);
}
编辑
预览
Supports
Markdown
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录