History

macOS 11: link using dyld shared cache

Supports linking using .tbd definitions found in the default installed command-line tools SDK or Xcode.app SDK. Only for creating executables (not yet for `tcc -run`).

Sushant Pandurangi committed 5 years ago

Commit f6fb4d01 parent e3a0eb53 files · +103 −20Browse files

Unified · Split

3 files
  1. libtcc.c +5 −3
  2. tcc.h +17 −1
  3. tccmacho.c +81 −16
libtcc.c+5−3
@@ -1006,7 +1006,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 1005 unmodified lines
1006 lseek(fd, 0, SEEK_SET);1006 lseek(fd, 0, SEEK_SET);
1007 1007
1008#ifdef TCC_TARGET_MACHO1008#ifdef TCC_TARGET_MACHO
1009 if (0 == obj_type && 0 == strcmp(tcc_fileextension(filename), ".dylib"))1009 if (0 == obj_type
1010 && (0 == strcmp(tcc_fileextension(filename), ".dylib")
1011 || 0 == strcmp(tcc_fileextension(filename), ".tbd")))
1010 obj_type = AFF_BINTYPE_DYN;1012 obj_type = AFF_BINTYPE_DYN;
1011#endif1013#endif
1012 1014
@@ -1142,8 +1144,8 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) · 129 unmodified lines
1142 static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };1144 static const char * const libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
1143 const char * const *pp = s->static_link ? libs + 4 : libs;1145 const char * const *pp = s->static_link ? libs + 4 : libs;
1144#elif defined TCC_TARGET_MACHO1146#elif defined TCC_TARGET_MACHO
1145 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.a", NULL };1147 static const char * const libs[] = { "%s/lib%s.dylib", "%s/lib%s.tbd", "%s/lib%s.a", NULL };
1146 const char * const *pp = s->static_link ? libs + 1 : libs;1148 const char * const *pp = s->static_link ? libs + 2 : libs;
1147#elif defined TARGETOS_OpenBSD1149#elif defined TARGETOS_OpenBSD
1148 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };1150 static const char * const libs[] = { "%s/lib%s.so.*", "%s/lib%s.a", NULL };
1149 const char * const *pp = s->static_link ? libs + 1 : libs;1151 const char * const *pp = s->static_link ? libs + 1 : libs;
tcc.h+17−1
@@ -42,6 +42,7 @@ · 41 unmodified lines
42#ifndef _WIN3242#ifndef _WIN32
43# include <unistd.h>43# include <unistd.h>
44# include <sys/time.h>44# include <sys/time.h>
45# include <sys/stat.h>
45# ifndef CONFIG_TCC_STATIC46# ifndef CONFIG_TCC_STATIC
46# include <dlfcn.h>47# include <dlfcn.h>
47# endif48# endif
@@ -246,6 +247,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 198 unmodified lines
246# define ALSO_TRIPLET(s) s247# define ALSO_TRIPLET(s) s
247#endif248#endif
248 249
250// FIXME: do this at runtime instead; check output of `xcode-select -p`. libxcselect provides this stuff
251#ifndef CONFIG_OSX_SDK1
252# define CONFIG_OSX_SDK1 "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"
253# define CONFIG_OSX_SDK2 "/Applications/Xcode.app/Developer/SDKs/MacOSX.sdk"
254#endif
255
249/* path to find crt1.o, crti.o and crtn.o */256/* path to find crt1.o, crti.o and crtn.o */
250#ifndef CONFIG_TCC_CRTPREFIX257#ifndef CONFIG_TCC_CRTPREFIX
251# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)258# define CONFIG_TCC_CRTPREFIX USE_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR)
@@ -274,10 +281,19 @@ extern long double strtold (const char *__nptr, char **__endptr); · 22 unmodified lines
274# ifdef TCC_TARGET_PE281# ifdef TCC_TARGET_PE
275# define CONFIG_TCC_LIBPATHS "{B}/lib"282# define CONFIG_TCC_LIBPATHS "{B}/lib"
276# else283# else
277# define CONFIG_TCC_LIBPATHS \284# ifdef TCC_TARGET_MACHO
285# define CONFIG_TCC_LIBPATHS \
286 ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
287 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
288 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)\
289 ":" ALSO_TRIPLET(CONFIG_OSX_SDK1 "/usr/" CONFIG_LDDIR) \
290 ":" ALSO_TRIPLET(CONFIG_OSX_SDK2 "/usr/" CONFIG_LDDIR)
291# else
292# define CONFIG_TCC_LIBPATHS \
278 ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \293 ALSO_TRIPLET(CONFIG_SYSROOT "/usr/" CONFIG_LDDIR) \
279 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \294 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/" CONFIG_LDDIR) \
280 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)295 ":" ALSO_TRIPLET(CONFIG_SYSROOT "/usr/local/" CONFIG_LDDIR)
296# endif
281# endif297# endif
282#endif298#endif
283 299
tccmacho.c+81−16
@@ -837,7 +837,78 @@ static uint32_t macho_swap32(uint32_t x) · 836 unmodified lines
837}837}
838#define SWAP(x) (swap ? macho_swap32(x) : (x))838#define SWAP(x) (swap ? macho_swap32(x) : (x))
839 839
840ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev)840ST_FUNC int macho_add_dllref(TCCState* s1, int lev, const char* soname)
841{
842 /* if the dll is already loaded, do not load it */
843 DLLReference *dllref;
844 for(int i = 0; i < s1->nb_loaded_dlls; i++) {
845 dllref = s1->loaded_dlls[i];
846 if (!strcmp(soname, dllref->name)) {
847 /* but update level if needed */
848 if (lev < dllref->level)
849 dllref->level = lev;
850 return -1;
851 }
852 }
853 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
854 dllref->level = lev;
855 strcpy(dllref->name, soname);
856 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
857 return 0;
858}
859
860#define tbd_parse_movepast(s) \
861 (pos = (pos = strstr(pos, s)) ? pos + strlen(s) : NULL)
862#define tbd_parse_movetoany(cs) (pos = strpbrk(pos, cs))
863#define tbd_parse_skipws while (*pos && (*pos==' '||*pos=='\n')) ++pos
864#define tbd_parse_tramplequote if(*pos=='\''||*pos=='"') tbd_parse_trample
865#define tbd_parse_tramplespace if(*pos==' ') tbd_parse_trample
866#define tbd_parse_trample *pos++=0
867
868ST_FUNC int macho_load_tbd(TCCState* s1, int fd, const char* filename, int lev)
869{
870 char* soname;
871
872 struct stat sb;
873 fstat(fd,&sb);
874 char* data = load_data(fd, 0, sb.st_size+1);
875 data[sb.st_size]=0;
876 char* pos = data;
877
878 if (!tbd_parse_movepast("install-name: ")) return -1;
879 tbd_parse_skipws;
880 tbd_parse_tramplequote;
881 soname = pos;
882 if (!tbd_parse_movetoany("\n \"'")) return -1;
883 tbd_parse_trample;
884 if (macho_add_dllref(s1, lev, soname) != 0) goto the_end;
885
886 while(pos) {
887 char* sym = NULL;
888 if (!tbd_parse_movepast("symbols: ")) break;
889 if (!tbd_parse_movepast("[")) break;
890 int cont = 1;
891 while (cont) {
892 tbd_parse_skipws;
893 tbd_parse_tramplequote;
894 sym = pos;
895 if (!tbd_parse_movetoany(",] \"'")) break;
896 tbd_parse_tramplequote;
897 tbd_parse_tramplespace;
898 tbd_parse_skipws;
899 if (*pos==0||*pos==']') cont=0;
900 tbd_parse_trample;
901 set_elf_sym(s1->dynsymtab_section, 0, 0,
902 ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0, SHN_UNDEF, sym);
903 }
904 }
905
906the_end:
907 tcc_free(data);
908 return 0;
909}
910
911ST_FUNC int macho_load_dylib(TCCState * s1, int fd, const char* filename, int lev)
841{912{
842 unsigned char buf[sizeof(struct mach_header_64)];913 unsigned char buf[sizeof(struct mach_header_64)];
843 void *buf2;914 void *buf2;
@@ -853,7 +924,6 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev) · 9 unmodified lines
853 uint32_t strsize = 0;924 uint32_t strsize = 0;
854 uint32_t iextdef = 0;925 uint32_t iextdef = 0;
855 uint32_t nextdef = 0;926 uint32_t nextdef = 0;
856 DLLReference *dllref;
857 927
858 again:928 again:
859 if (full_read(fd, buf, sizeof(buf)) != sizeof(buf))929 if (full_read(fd, buf, sizeof(buf)) != sizeof(buf))
@@ -934,20 +1004,8 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev) · 74 unmodified lines
934 lc = (struct load_command*) ((char*)lc + lc->cmdsize);1004 lc = (struct load_command*) ((char*)lc + lc->cmdsize);
935 }1005 }
936 1006
937 /* if the dll is already loaded, do not load it */1007 if (0 != macho_add_dllref(s1, lev, soname))
938 for(i = 0; i < s1->nb_loaded_dlls; i++) {1008 goto the_end;
939 dllref = s1->loaded_dlls[i];
940 if (!strcmp(soname, dllref->name)) {
941 /* but update level if needed */
942 if (lev < dllref->level)
943 dllref->level = lev;
944 goto the_end;
945 }
946 }
947 dllref = tcc_mallocz(sizeof(DLLReference) + strlen(soname));
948 dllref->level = lev;
949 strcpy(dllref->name, soname);
950 dynarray_add(&s1->loaded_dlls, &s1->nb_loaded_dlls, dllref);
951 1009
952 if (!nsyms || !nextdef)1010 if (!nsyms || !nextdef)
953 tcc_warning("%s doesn't export any symbols?", filename);1011 tcc_warning("%s doesn't export any symbols?", filename);
@@ -972,3 +1030,10 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev) · 18 unmodified lines
972 tcc_free(buf2);1030 tcc_free(buf2);
973 return 0;1031 return 0;
974}1032}
1033
1034ST_FUNC int macho_load_dll(TCCState * s1, int fd, const char* filename, int lev)
1035{
1036 return strcmp(tcc_fileextension(filename), ".tbd") == 0
1037 ? macho_load_tbd(s1, fd, filename, lev)
1038 : macho_load_dylib(s1, fd, filename, lev);
1039}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t