History

linker options & tcc_load_ldscript() reworked

cleanup libtcc.c:tcc_set_linker() cleanup tccelf.c:tcc_load_ldscript() Also - tccrun.c, tccelf.c:relocate_syms(): with tcc -run -nostdlib, do resolve but only from explicitly on the command-line given libraries. - tccgen.c: optimize UMOD x % c -> x & (c-1) for c = 2^n - tcc-doc.texi: cleanup - tcc.h, tccpp.c, libtcc.c: add 'size' arg to pstrncpy() Also reorder functions in libtcc.c a bit. 9 files changed, 556 insertions(+), 617 deletions(-)

grischka committed 1 year ago

Commit f10ab131 parent b3381269 files · +556 −617Browse files

Unified · Split

9 files
  1. libtcc.c +418 −465
  2. tcc-doc.texi +12 −10
  3. tcc.c +6 −4
  4. tcc.h +12 −11
  5. tccelf.c +94 −114
  6. tccgen.c +6 −1
  7. tccmacho.c +4 −8
  8. tccpp.c +2 −2
  9. tccrun.c +2 −2
libtcc.c+418−465
@@ -175,9 +175,11 @@ ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s) · 174 unmodified lines
175 return buf;175 return buf;
176}176}
177 177
178ST_FUNC char *pstrncpy(char *out, const char *in, size_t num)178ST_FUNC char *pstrncpy(char *out, size_t buf_size, const char *s, size_t num)
179{179{
180 memcpy(out, in, num);180 if (num >= buf_size)
181 num = buf_size - 1;
182 memcpy(out, s, num);
181 out[num] = '\0';183 out[num] = '\0';
182 return out;184 return out;
183}185}
@@ -206,11 +208,26 @@ ST_FUNC char *tcc_load_text(int fd) · 22 unmodified lines
206{208{
207 int len = lseek(fd, 0, SEEK_END);209 int len = lseek(fd, 0, SEEK_END);
208 char *buf = load_data(fd, 0, len + 1);210 char *buf = load_data(fd, 0, len + 1);
209 if (buf)211 buf[len] = 0;
210 buf[len] = 0;
211 return buf;212 return buf;
212}213}
213 214
215/* replace *pp by copy of 'str' or NULL */
216static void tcc_set_str(char **pp, const char *str)
217{
218 tcc_free(*pp);
219 *pp = str ? tcc_strdup(str) : NULL;
220}
221
222/* set/append 'str' to *pp (separated by 'sep' unless 0) */
223static void tcc_concat_str(char **pp, const char *str, int sep)
224{
225 int l = *pp ? strlen(*pp) + !!sep : 0;
226 *pp = tcc_realloc(*pp, l + strlen(str) + 1);
227 if (l && sep) ((*pp)[l - 1] = sep);
228 strcpy(*pp + l, str);
229}
230
214/********************************************************/231/********************************************************/
215/* memory management */232/* memory management */
216 233
@@ -519,6 +536,41 @@ ST_FUNC void dynarray_reset(void *pp, int *n) · 302 unmodified lines
519 *(void**)pp = NULL;536 *(void**)pp = NULL;
520}537}
521 538
539static void dynarray_split(char ***argv, int *argc, const char *p, int sep)
540{
541 int qot, c;
542 CString str;
543 for(;;) {
544 while (c = (unsigned char)*p, c <= ' ' && c != '\0')
545 ++p;
546 if (c == '\0')
547 break;
548 cstr_new(&str);
549 qot = 0;
550 do {
551 ++p;
552 if (sep) { /* e.g. to split -Wl,-opt,arg */
553 if (c == sep)
554 break;
555 } else {
556 /* e.g. for tcc_set_options() or "tcc @listfile" */
557 if (c == '\\' && (*p == '"' || *p == '\\')) {
558 c = *p++;
559 } else if (c == '"') {
560 qot ^= 1;
561 continue;
562 } else if (c <= ' ' && !qot) {
563 break;
564 }
565 }
566 cstr_ccat(&str, c);
567 } while (c = (unsigned char)*p, c != '\0');
568 cstr_ccat(&str, '\0');
569 //printf("<%s>\n", str.data);
570 dynarray_add(argv, argc, str.data);
571 }
572}
573
522static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)574static void tcc_split_path(TCCState *s, void *p_ary, int *p_nb_ary, const char *in)
523{575{
524 const char *p;576 const char *p;
@@ -885,9 +937,9 @@ LIBTCCAPI void tcc_delete(TCCState *s1) · 360 unmodified lines
885 dynarray_reset(&s1->target_deps, &s1->nb_target_deps);937 dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
886 dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);938 dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
887 dynarray_reset(&s1->argv, &s1->argc);939 dynarray_reset(&s1->argv, &s1->argc);
940 dynarray_reset(&s1->link_argv, &s1->link_argc);
888 cstr_free(&s1->cmdline_defs);941 cstr_free(&s1->cmdline_defs);
889 cstr_free(&s1->cmdline_incl);942 cstr_free(&s1->cmdline_incl);
890 cstr_free(&s1->linker_arg);
891 tcc_free(s1->dState);943 tcc_free(s1->dState);
892#ifdef TCC_IS_NATIVE944#ifdef TCC_IS_NATIVE
893 /* free runtime memory */945 /* free runtime memory */
@@ -962,6 +1014,17 @@ LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname) · 68 unmodified lines
962 return 0;1014 return 0;
963}1015}
964 1016
1017LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
1018{
1019 tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
1020 return 0;
1021}
1022
1023LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
1024{
1025 tcc_set_str(&s->tcc_lib_path, path);
1026}
1027
965/* add/update a 'DLLReference', Just find if level == -1 */1028/* add/update a 'DLLReference', Just find if level == -1 */
966ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level)1029ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int level)
967{1030{
@@ -988,6 +1051,109 @@ ST_FUNC DLLReference *tcc_add_dllref(TCCState *s1, const char *dllname, int leve · 20 unmodified lines
988 return ref;1051 return ref;
989}1052}
990 1053
1054static int tcc_add_binary(TCCState *s1, int flags, const char *filename, int fd)
1055{
1056 ElfW(Ehdr) ehdr;
1057 int obj_type;
1058 const char *saved_filename = s1->current_filename;
1059 int ret = 0;
1060
1061 s1->current_filename = filename;
1062 obj_type = tcc_object_type(fd, &ehdr);
1063 lseek(fd, 0, SEEK_SET);
1064
1065 switch (obj_type) {
1066
1067 case AFF_BINTYPE_REL:
1068 ret = tcc_load_object_file(s1, fd, 0);
1069 break;
1070
1071 case AFF_BINTYPE_AR:
1072 ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
1073 break;
1074
1075#if defined TCC_TARGET_UNIX
1076 case AFF_BINTYPE_DYN:
1077 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1078#ifdef TCC_IS_NATIVE
1079 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1080 if (dl)
1081 tcc_add_dllref(s1, filename, 0)->handle = dl;
1082 else
1083 ret = FILE_NOT_RECOGNIZED;
1084#endif
1085 } else
1086 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1087 break;
1088
1089 default:
1090 /* as GNU ld, consider it is an ld script if not recognized */
1091 ret = tcc_load_ldscript(s1, fd);
1092 break;
1093
1094#elif defined TCC_TARGET_MACHO
1095 case AFF_BINTYPE_DYN:
1096 case_dyn_or_tbd:
1097 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1098#ifdef TCC_IS_NATIVE
1099 void* dl;
1100 const char* soname = filename;
1101 char *tmp = 0;
1102 if (obj_type != AFF_BINTYPE_DYN) {
1103 tmp = macho_tbd_soname(fd);
1104 if (tmp)
1105 soname = tmp;
1106 }
1107 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
1108 if (dl)
1109 tcc_add_dllref(s1, soname, 0)->handle = dl;
1110 else
1111 ret = FILE_NOT_RECOGNIZED;
1112 tcc_free(tmp);
1113#endif
1114 } else if (obj_type == AFF_BINTYPE_DYN) {
1115 ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1116 } else {
1117 ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1118 }
1119 if (ret)
1120 ret = FILE_NOT_RECOGNIZED;
1121 break;
1122
1123 default:
1124 {
1125 const char *ext = tcc_fileextension(filename);
1126 if (!strcmp(ext, ".tbd"))
1127 goto case_dyn_or_tbd;
1128 if (!strcmp(ext, ".dylib")) {
1129 obj_type = AFF_BINTYPE_DYN;
1130 goto case_dyn_or_tbd;
1131 }
1132 ret = FILE_NOT_RECOGNIZED;
1133 break;
1134 }
1135
1136#elif defined TCC_TARGET_PE
1137 default:
1138 if (pe_load_file(s1, fd, filename))
1139 ret = FILE_NOT_RECOGNIZED;
1140 break;
1141#endif
1142
1143#ifdef TCC_TARGET_COFF
1144 case AFF_BINTYPE_C67:
1145 ret = tcc_load_coff(s1, fd);
1146 break;
1147#endif
1148 }
1149
1150 close(fd);
1151 s1->current_filename = saved_filename;
1152 if (ret == FILE_NOT_RECOGNIZED)
1153 return tcc_error_noabort("%s: unrecognized file type", filename);
1154 return ret;
1155}
1156
991/* OpenBSD: choose latest from libxxx.so.x.y versions */1157/* OpenBSD: choose latest from libxxx.so.x.y versions */
992#if defined TARGETOS_OpenBSD && !defined _WIN321158#if defined TARGETOS_OpenBSD && !defined _WIN32
993#include <glob.h>1159#include <glob.h>
@@ -1013,11 +1179,34 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) · 19 unmodified lines
1013}1179}
1014#endif1180#endif
1015 1181
1016static int guess_filetype(const char *filename);1182static int guess_filetype(const char *filename)
1183{
1184 int filetype = 0;
1185 if (1) {
1186 /* use a file extension to detect a filetype */
1187 const char *ext = tcc_fileextension(filename);
1188 if (ext[0]) {
1189 ext++;
1190 if (!strcmp(ext, "S"))
1191 filetype = AFF_TYPE_ASMPP;
1192 else if (!strcmp(ext, "s"))
1193 filetype = AFF_TYPE_ASM;
1194 else if (!PATHCMP(ext, "c")
1195 || !PATHCMP(ext, "h")
1196 || !PATHCMP(ext, "i"))
1197 filetype = AFF_TYPE_C;
1198 else
1199 filetype |= AFF_TYPE_BIN;
1200 } else {
1201 filetype = AFF_TYPE_C;
1202 }
1203 }
1204 return filetype;
1205}
1017 1206
1018ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)1207ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
1019{1208{
1020 int fd, ret = -1;1209 int fd;
1021 1210
1022#if defined TARGETOS_OpenBSD && !defined _WIN321211#if defined TARGETOS_OpenBSD && !defined _WIN32
1023 char buf[1024];1212 char buf[1024];
@@ -1041,125 +1230,11 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 17 unmodified lines
1041 return FILE_NOT_FOUND;1230 return FILE_NOT_FOUND;
1042 }1231 }
1043 1232
1044 s1->current_filename = filename;1233 if (flags & AFF_TYPE_BIN)
1045 if (flags & AFF_TYPE_BIN) {1234 return tcc_add_binary(s1, flags, filename, fd);
1046 ElfW(Ehdr) ehdr;
1047 int obj_type;
1048
1049 obj_type = tcc_object_type(fd, &ehdr);
1050 lseek(fd, 0, SEEK_SET);
1051
1052 switch (obj_type) {
1053
1054 case AFF_BINTYPE_REL:
1055 ret = tcc_load_object_file(s1, fd, 0);
1056 break;
1057
1058 case AFF_BINTYPE_AR:
1059 ret = tcc_load_archive(s1, fd, !(flags & AFF_WHOLE_ARCHIVE));
1060 break;
1061
1062#ifdef TCC_TARGET_PE
1063 default:
1064 ret = pe_load_file(s1, fd, filename);
1065 goto check_success;
1066
1067#elif defined TCC_TARGET_MACHO
1068 case AFF_BINTYPE_DYN:
1069 case_dyn_or_tbd:
1070 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1071#ifdef TCC_IS_NATIVE
1072 void* dl;
1073 const char* soname = filename;
1074 if (obj_type != AFF_BINTYPE_DYN)
1075 soname = macho_tbd_soname(filename);
1076 dl = dlopen(soname, RTLD_GLOBAL | RTLD_LAZY);
1077 if (dl)
1078 tcc_add_dllref(s1, soname, 0)->handle = dl, ret = 0;
1079 if (filename != soname)
1080 tcc_free((void *)soname);
1081#endif
1082 } else if (obj_type == AFF_BINTYPE_DYN) {
1083 ret = macho_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1084 } else {
1085 ret = macho_load_tbd(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1086 }
1087 goto check_success;
1088 default:
1089 {
1090 const char *ext = tcc_fileextension(filename);
1091 if (!strcmp(ext, ".tbd"))
1092 goto case_dyn_or_tbd;
1093 if (!strcmp(ext, ".dylib")) {
1094 obj_type = AFF_BINTYPE_DYN;
1095 goto case_dyn_or_tbd;
1096 }
1097 goto check_success;
1098 }
1099
1100#else /* unix */
1101 case AFF_BINTYPE_DYN:
1102 if (s1->output_type == TCC_OUTPUT_MEMORY) {
1103#ifdef TCC_IS_NATIVE
1104 void* dl = dlopen(filename, RTLD_GLOBAL | RTLD_LAZY);
1105 if (dl)
1106 tcc_add_dllref(s1, filename, 0)->handle = dl, ret = 0;
1107#endif
1108 } else
1109 ret = tcc_load_dll(s1, fd, filename, (flags & AFF_REFERENCED_DLL) != 0);
1110 break;
1111
1112 default:
1113 /* as GNU ld, consider it is an ld script if not recognized */
1114 ret = tcc_load_ldscript(s1, fd);
1115 goto check_success;
1116 1235
1117#endif /* pe / macos / unix */1236 dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename));
1118 1237 return tcc_compile(s1, flags, filename, fd);
1119check_success:
1120 if (ret < 0)
1121 tcc_error_noabort("%s: unrecognized file type", filename);
1122 break;
1123
1124#ifdef TCC_TARGET_COFF
1125 case AFF_BINTYPE_C67:
1126 ret = tcc_load_coff(s1, fd);
1127 break;
1128#endif
1129 }
1130 close(fd);
1131 } else {
1132 /* update target deps */
1133 dynarray_add(&s1->target_deps, &s1->nb_target_deps, tcc_strdup(filename));
1134 ret = tcc_compile(s1, flags, filename, fd);
1135 }
1136 s1->current_filename = NULL;
1137 return ret;
1138}
1139
1140static int guess_filetype(const char *filename)
1141{
1142 int filetype = 0;
1143 if (1) {
1144 /* use a file extension to detect a filetype */
1145 const char *ext = tcc_fileextension(filename);
1146 if (ext[0]) {
1147 ext++;
1148 if (!strcmp(ext, "S"))
1149 filetype = AFF_TYPE_ASMPP;
1150 else if (!strcmp(ext, "s"))
1151 filetype = AFF_TYPE_ASM;
1152 else if (!PATHCMP(ext, "c")
1153 || !PATHCMP(ext, "h")
1154 || !PATHCMP(ext, "i"))
1155 filetype = AFF_TYPE_C;
1156 else
1157 filetype |= AFF_TYPE_BIN;
1158 } else {
1159 filetype = AFF_TYPE_C;
1160 }
1161 }
1162 return filetype;
1163}1238}
1164 1239
1165LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)1240LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
@@ -1167,12 +1242,6 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) · 1 unmodified line
1167 return tcc_add_file_internal(s, filename, s->filetype | AFF_PRINT_ERROR);1242 return tcc_add_file_internal(s, filename, s->filetype | AFF_PRINT_ERROR);
1168}1243}
1169 1244
1170LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
1171{
1172 tcc_split_path(s, &s->library_paths, &s->nb_library_paths, pathname);
1173 return 0;
1174}
1175
1176static int tcc_add_library_internal(TCCState *s1, const char *fmt,1245static int tcc_add_library_internal(TCCState *s1, const char *fmt,
1177 const char *filename, int flags, char **paths, int nb_paths)1246 const char *filename, int flags, char **paths, int nb_paths)
1178{1247{
@@ -1186,7 +1255,8 @@ static int tcc_add_library_internal(TCCState *s1, const char *fmt, · 7 unmodified lines
1186 return ret;1255 return ret;
1187 }1256 }
1188 if (flags & AFF_PRINT_ERROR)1257 if (flags & AFF_PRINT_ERROR)
1189 tcc_error_noabort("library '%s' not found", filename);1258 tcc_error_noabort("%s '%s' not found",
1259 flags & AFF_TYPE_LIB ? "library" : "file", filename);
1190 return FILE_NOT_FOUND;1260 return FILE_NOT_FOUND;
1191}1261}
1192 1262
@@ -1206,7 +1276,7 @@ ST_FUNC int tcc_add_support(TCCState *s1, const char *filename) · 13 unmodified lines
1206 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);1276 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);
1207}1277}
1208 1278
1209#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO1279#ifdef TCC_TARGET_UNIX
1210ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)1280ST_FUNC int tcc_add_crt(TCCState *s1, const char *filename)
1211{1281{
1212 return tcc_add_library_internal(s1, "%s/%s",1282 return tcc_add_library_internal(s1, "%s/%s",
@@ -1230,12 +1300,12 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) · 17 unmodified lines
1230 "%s/lib%s.a",1300 "%s/lib%s.a",
1231 NULL1301 NULL
1232 };1302 };
1303 int flags = AFF_TYPE_LIB | (s->filetype & AFF_WHOLE_ARCHIVE);
1233 /* if libraryname begins with a colon, it means search lib paths for1304 /* if libraryname begins with a colon, it means search lib paths for
1234 exactly the following file, without lib prefix or anything */1305 exactly the following file, without lib prefix or anything */
1235 if (*libraryname == ':') {1306 if (*libraryname == ':') {
1236 libraryname++;1307 libraryname++;
1237 } else {1308 } else {
1238 int flags = s->filetype & AFF_WHOLE_ARCHIVE;
1239 const char * const *pp = libs;1309 const char * const *pp = libs;
1240 if (s->static_link)1310 if (s->static_link)
1241 pp += sizeof(libs) / sizeof(*libs) - 2; /* only "%s/lib%s.a" */1311 pp += sizeof(libs) / sizeof(*libs) - 2; /* only "%s/lib%s.a" */
@@ -1247,7 +1317,8 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) · 5 unmodified lines
1247 ++pp;1317 ++pp;
1248 }1318 }
1249 }1319 }
1250 return tcc_add_dll(s, libraryname, AFF_PRINT_ERROR);1320 /* fallback to try file without pre- or sufffix */
1321 return tcc_add_dll(s, libraryname, flags | AFF_PRINT_ERROR);
1251}1322}
1252 1323
1253/* handle #pragma comment(lib,) */1324/* handle #pragma comment(lib,) */
@@ -1258,30 +1329,6 @@ ST_FUNC void tcc_add_pragma_libs(TCCState *s1) · 4 unmodified lines
1258 tcc_add_library(s1, s1->pragma_libs[i]);1329 tcc_add_library(s1, s1->pragma_libs[i]);
1259}1330}
1260 1331
1261LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
1262{
1263#ifdef TCC_TARGET_PE
1264 /* On x86_64 'val' might not be reachable with a 32bit offset.
1265 So it is handled here as if it were in a DLL. */
1266 pe_putimport(s1, 0, name, (uintptr_t)val);
1267#else
1268 char buf[256];
1269 if (s1->leading_underscore) {
1270 buf[0] = '_';
1271 pstrcpy(buf + 1, sizeof(buf) - 1, name);
1272 name = buf;
1273 }
1274 set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */
1275#endif
1276 return 0;
1277}
1278
1279LIBTCCAPI void tcc_set_lib_path(TCCState *s, const char *path)
1280{
1281 tcc_free(s->tcc_lib_path);
1282 s->tcc_lib_path = tcc_strdup(path);
1283}
1284
1285/********************************************************/1332/********************************************************/
1286/* options parser */1333/* options parser */
1287 1334
@@ -1300,224 +1347,177 @@ static int strstart(const char *val, const char **str) · 12 unmodified lines
1300 return 1;1347 return 1;
1301}1348}
1302 1349
1303/* Like strstart, but automatically takes into account that ld options can1350struct lopt {
1304 *1351 TCCState *s;
1305 * - start with double or single dash (e.g. '--soname' or '-soname')1352 const char *opt, *arg;
1306 * - arguments can be given as separate or after '=' (e.g. '-Wl,-soname,x.so'1353 int match;
1307 * or '-Wl,-soname=x.so')1354};
1308 *1355
1309 * you provide `val` always in 'option[=]' form (no leading -)1356/* match linker option */
1310 */1357static int link_option(struct lopt *o, const char *q)
1311static int link_option(const char *str, const char *val, const char **ptr)
1312{1358{
1313 const char *p, *q;1359 const char *p = o->opt;
1314 int ret;1360 int c;
1315 1361
1316 /* there should be 1 or 2 dashes */1362 /* there should be 1 or 2 dashes */
1317 if (*str++ != '-')1363 if (*p++ != '-')
1318 return 0;1364 return 0;
1319 if (*str == '-')1365 if (*p == '-')
1320 str++;
1321
1322 /* then str & val should match (potentially up to '=') */
1323 p = str;
1324 q = val;
1325
1326 ret = 1;
1327 if (q[0] == '?') {
1328 ++q;
1329 if (strstart("no-", &p))
1330 ret = -1;
1331 }
1332
1333 while (*q != '\0' && *q != '=') {
1334 if (*p != *q)
1335 return 0;
1336 p++;1366 p++;
1337 q++;1367 while ((c = *q) == *p) {
1368 if (c == '\0')
1369 goto succ; /* -Wl,-opt */
1370 ++p;
1371 if (c == '=')
1372 goto succ; /* -Wl,-opt=arg */
1373 ++q;
1338 }1374 }
1339 1375 if (c == '=' || c == ':') {
1340 /* '=' near eos means ',' or '=' is ok */1376 if (*p == '\0') {
1341 if (*q == '=') {1377 if (o->s->link_optind + 1 < o->s->link_argc) {
1342 if (*p == 0)1378 p = o->s->link_argv[++o->s->link_optind];
1343 *ptr = p;1379 goto succ; /* -Wl,-opt,arg */
1344 if (*p != ',' && *p != '=')1380 }
1345 return 0;1381 o->match = 1; /* -Wl,-opt -Wl,arg */
1346 p++;1382 } else if (c == ':')
1347 } else if (*p && *p != ',') {1383 goto succ; /* -Wl,-Iarg */
1348 return 0;
1349 }1384 }
1350 *ptr = p;1385 return 0;
1351 return ret;1386succ:
1352}1387 o->arg = p;
1353 1388 //printf("set %s '%s'\n", o->opt, o->arg);
1354static int link_arg(const char *opt, const char *str)1389 return 1;
1355{
1356 int l = strlen(opt);
1357 return 0 == strncmp(opt, str, l) && (str[l] == '\0' || str[l] == ',');
1358}1390}
1359 1391
1360static const char *skip_linker_arg(const char **str)1392static void args_parser_add_file(TCCState *s, const char* filename, int filetype);
1361{
1362 const char *s1 = *str;
1363 const char *s2 = strchr(s1, ',');
1364 *str = s2 ? s2++ : (s2 = s1 + strlen(s1));
1365 return s2;
1366}
1367
1368static void copy_linker_arg(char **pp, const char *s, int sep)
1369{
1370 const char *q = s;
1371 char *p = *pp;
1372 int l = 0;
1373 if (p && sep)
1374 p[l = strlen(p)] = sep, ++l;
1375 skip_linker_arg(&q);
1376 pstrncpy(l + (*pp = tcc_realloc(p, q - s + l + 1)), s, q - s);
1377}
1378
1379static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
1380{
1381 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
1382 f->type = filetype;
1383 strcpy(f->name, filename);
1384 dynarray_add(&s->files, &s->nb_files, f);
1385}
1386 1393
1387/* set linker options */1394/* set linker options */
1388static int tcc_set_linker(TCCState *s, const char *option)1395static int tcc_set_linker(TCCState *s, const char *optarg)
1389{1396{
1390 TCCState *s1 = s;1397 TCCState *s1 = s;
1391 while (*option) {
1392 1398
1393 const char *p = NULL;1399 dynarray_split(&s1->link_argv, &s1->link_argc, optarg, ',');
1400
1401 while (s->link_optind < s->link_argc) {
1394 char *end = NULL;1402 char *end = NULL;
1395 int ignoring = 0;1403 int ignoring = 0;
1396 int ret;1404 struct lopt o = {0};
1405 o.s = s;
1406 o.opt = s->link_argv[s->link_optind];
1397 1407
1398 if (link_option(option, "Bsymbolic", &p)) {1408 if (link_option(&o, "Bsymbolic")) {
1399 s->symbolic = 1;1409 s->symbolic = 1;
1400 } else if (link_option(option, "nostdlib", &p)) {1410 } else if (link_option(&o, "nostdlib")) {
1401 s->nostdlib_paths = 1;1411 s->nostdlib_paths = 1;
1402 } else if (link_option(option, "e=", &p)1412 } else if (link_option(&o, "e=") || link_option(&o, "entry=")) {
1403 || link_option(option, "entry=", &p)) {1413 tcc_set_str(&s->elf_entryname, o.arg);
1404 copy_linker_arg(&s->elf_entryname, p, 0);1414 } else if (link_option(&o, "image-base=") || link_option(&o, "Ttext=")) {
1405 } else if (link_option(option, "fini=", &p)) {1415 s->text_addr = strtoull(o.arg, &end, 16);
1406 copy_linker_arg(&s->fini_symbol, p, 0);
1407 ignoring = 1;
1408 } else if (link_option(option, "image-base=", &p)
1409 || link_option(option, "Ttext=", &p)) {
1410 s->text_addr = strtoull(p, &end, 16);
1411 s->has_text_addr = 1;1416 s->has_text_addr = 1;
1412 } else if (link_option(option, "init=", &p)) {1417 } else if (link_option(&o, "init=")) {
1413 copy_linker_arg(&s->init_symbol, p, 0);1418 tcc_set_str(&s->init_symbol, o.arg);
1419 ignoring = 1;
1420 } else if (link_option(&o, "fini=")) {
1421 tcc_set_str(&s->fini_symbol, o.arg);
1414 ignoring = 1;1422 ignoring = 1;
1415 } else if (link_option(option, "Map=", &p)) {1423 } else if (link_option(&o, "Map=")) {
1416 copy_linker_arg(&s->mapfile, p, 0);1424 tcc_set_str(&s->mapfile, o.arg);
1417 ignoring = 1;1425 ignoring = 1;
1418 } else if (link_option(option, "oformat=", &p)) {1426 } else if (link_option(&o, "oformat=")) {
1419#if defined(TCC_TARGET_PE)1427#if defined TCC_TARGET_PE
1420 if (strstart("pe-", &p)) {1428 if (0 == strncmp("pe-", o.arg, 3))
1421#elif PTR_SIZE == 81429#elif PTR_SIZE == 8
1422 if (strstart("elf64-", &p)) {1430 if (0 == strncmp("elf64-", o.arg, 6))
1423#else1431#else
1424 if (strstart("elf32-", &p)) {1432 if (0 == strncmp("elf32-", o.arg, 6))
1425#endif1433#endif
1426 s->output_format = TCC_OUTPUT_FORMAT_ELF;1434 s->output_format = TCC_OUTPUT_FORMAT_ELF;
1427 } else if (link_arg("binary", p)) {1435 else if (0==strcmp("binary", o.arg))
1428 s->output_format = TCC_OUTPUT_FORMAT_BINARY;1436 s->output_format = TCC_OUTPUT_FORMAT_BINARY;
1429#ifdef TCC_TARGET_COFF1437#if defined TCC_TARGET_COFF
1430 } else if (link_arg("coff", p)) {1438 else if (0==strcmp("coff", o.arg))
1431 s->output_format = TCC_OUTPUT_FORMAT_COFF;1439 s->output_format = TCC_OUTPUT_FORMAT_COFF;
1432#endif1440#endif
1433 } else1441 else
1434 goto err;1442 goto err;
1435 1443 } else if (link_option(&o, "export-all-symbols")
1436 } else if (link_option(option, "as-needed", &p)) {1444 || link_option(&o, "export-dynamic")) {
1437 ignoring = 1;
1438 } else if (link_option(option, "O", &p)) {
1439 ignoring = 1;
1440 } else if (link_option(option, "export-all-symbols", &p)) {
1441 s->rdynamic = 1;
1442 } else if (link_option(option, "export-dynamic", &p)) {
1443 s->rdynamic = 1;1445 s->rdynamic = 1;
1444 } else if (link_option(option, "rpath=", &p)) {1446 } else if (link_option(&o, "rpath=")) {
1445 copy_linker_arg(&s->rpath, p, ':');1447 tcc_concat_str(&s->rpath, o.arg, ':');
1446 } else if (link_option(option, "dynamic-linker=", &p)1448 } else if (link_option(&o, "dynamic-linker=") || link_option(&o, "I:")) {
1447 || link_option(option, "I=", &p)) {1449 tcc_set_str(&s->elfint, o.arg);
1448 copy_linker_arg(&s->elfint, p, 0);1450 } else if (link_option(&o, "enable-new-dtags")) {
1449 } else if (strncmp("-I/", option, 3) == 0
1450 || strncmp("-I.", option, 3) == 0) {
1451 p = option;
1452 copy_linker_arg(&s->elfint, option + 2, 0);
1453 } else if (link_option(option, "enable-new-dtags", &p)) {
1454 s->enable_new_dtags = 1;1451 s->enable_new_dtags = 1;
1455 } else if (link_option(option, "section-alignment=", &p)) {1452 } else if (link_option(&o, "section-alignment=")) {
1456 s->section_align = strtoul(p, &end, 16);1453 s->section_align = strtoul(o.arg, &end, 16);
1457 } else if (link_option(option, "soname=", &p)) {1454 } else if (link_option(&o, "soname=") || link_option(&o, "install_name=")) {
1458 copy_linker_arg(&s->soname, p, 0);1455 tcc_set_str(&s->soname, o.arg);
1459 } else if (link_option(option, "install_name=", &p)) {1456 } else if (link_option(&o, "whole-archive")) {
1460 copy_linker_arg(&s->soname, p, 0);1457 s->filetype |= AFF_WHOLE_ARCHIVE;
1458 } else if (link_option(&o, "no-whole-archive")) {
1459 s->filetype &= ~AFF_WHOLE_ARCHIVE;
1461#ifdef TCC_TARGET_PE1460#ifdef TCC_TARGET_PE
1462 } else if (link_option(option, "large-address-aware", &p)) {1461 } else if (link_option(&o, "large-address-aware")) {
1463 s->pe_characteristics |= 0x20;1462 s->pe_characteristics |= 0x20;
1464 } else if (link_option(option, "file-alignment=", &p)) {1463 } else if (link_option(&o, "file-alignment=")) {
1465 s->pe_file_align = strtoul(p, &end, 16);1464 s->pe_file_align = strtoul(o.arg, &end, 16);
1466 } else if (link_option(option, "stack=", &p)) {1465 } else if (link_option(&o, "stack=")) {
1467 s->pe_stack_size = strtoul(p, &end, 10);1466 s->pe_stack_size = strtoul(o.arg, &end, 10);
1468 } else if (link_option(option, "subsystem=", &p)) {1467 } else if (link_option(&o, "subsystem=")) {
1469#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)1468#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
1470 if (link_arg("native", p)) {1469 if (0==strcmp("native", o.arg)) {
1471 s->pe_subsystem = 1;1470 s->pe_subsystem = 1;
1472 } else if (link_arg("console", p)) {1471 } else if (0==strcmp("console", o.arg)) {
1473 s->pe_subsystem = 3;1472 s->pe_subsystem = 3;
1474 } else if (link_arg("gui", p) || link_arg("windows", p)) {1473 } else if (0==strcmp("gui", o.arg) || 0==strcmp("windows", o.arg)) {
1475 s->pe_subsystem = 2;1474 s->pe_subsystem = 2;
1476 } else if (link_arg("posix", p)) {1475 } else if (0==strcmp("posix", o.arg)) {
1477 s->pe_subsystem = 7;1476 s->pe_subsystem = 7;
1478 } else if (link_arg("efiapp", p)) {1477 } else if (0==strcmp("efiapp", o.arg)) {
1479 s->pe_subsystem = 10;1478 s->pe_subsystem = 10;
1480 } else if (link_arg("efiboot", p)) {1479 } else if (0==strcmp("efiboot", o.arg)) {
1481 s->pe_subsystem = 11;1480 s->pe_subsystem = 11;
1482 } else if (link_arg("efiruntime", p)) {1481 } else if (0==strcmp("efiruntime", o.arg)) {
1483 s->pe_subsystem = 12;1482 s->pe_subsystem = 12;
1484 } else if (link_arg("efirom", p)) {1483 } else if (0==strcmp("efirom", o.arg)) {
1485 s->pe_subsystem = 13;1484 s->pe_subsystem = 13;
1486#elif defined(TCC_TARGET_ARM)1485#elif defined(TCC_TARGET_ARM)
1487 if (link_arg("wince", p)) {1486 if (0==strcmp("wince", o.arg)) {
1488 s->pe_subsystem = 9;1487 s->pe_subsystem = 9;
1489#endif1488#endif
1490 } else1489 } else
1491 goto err;1490 goto err;
1492#endif1491#endif /* PE */
1493#ifdef TCC_TARGET_MACHO1492#ifdef TCC_TARGET_MACHO
1494 } else if (link_option(option, "all_load", &p)) {1493 } else if (link_option(&o, "all_load")) {
1495 s->filetype |= AFF_WHOLE_ARCHIVE;
1496 } else if (link_option(option, "force_load", &p)) {
1497 s->filetype |= AFF_WHOLE_ARCHIVE;1494 s->filetype |= AFF_WHOLE_ARCHIVE;
1498 args_parser_add_file(s, p, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));1495 } else if (link_option(&o, "force_load=")) {
1499 s->nb_libraries++;1496 args_parser_add_file(s, o.arg, AFF_TYPE_LIB | AFF_WHOLE_ARCHIVE);
1500 } else if (link_option(option, "single_module", &p)) {1497 } else if (link_option(&o, "single_module")) {
1501 ignoring = 1;1498 ignoring = 1;
1502#endif1499#endif
1503 } else if (ret = link_option(option, "?whole-archive", &p), ret) {1500 } else if (link_option(&o, "as-needed")) {
1504 if (ret > 0)
1505 s->filetype |= AFF_WHOLE_ARCHIVE;
1506 else
1507 s->filetype &= ~AFF_WHOLE_ARCHIVE;
1508 } else if (link_option(option, "z=", &p)) {
1509 ignoring = 1;1501 ignoring = 1;
1510 } else if (p) {1502 } else if (link_option(&o, "O")) {
1511 return 0;1503 ignoring = 1;
1504 } else if (link_option(&o, "z=")) {
1505 ignoring = 1;
1506 } else if (link_option(&o, "L:")) {
1507 tcc_add_library_path(s, o.arg);
1508 } else if (link_option(&o, "l:")) {
1509 args_parser_add_file(s, o.arg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));
1510 } else if (o.match) {
1511 return 0; /* expecting argument with next '-Wl,' */
1512 } else {1512 } else {
1513 err:1513 err:
1514 return tcc_error_noabort("unsupported linker option '%s'", option);1514 return tcc_error_noabort("unsupported linker option '%s'", o.opt);
1515 }1515 }
1516 if (ignoring)1516 if (ignoring)
1517 tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", option);1517 tcc_warning_c(warn_unsupported)("unsupported linker option '%s'", o.opt);
1518 option = skip_linker_arg(&p);1518 ++s->link_optind;
1519 }1519 }
1520 return 1;1520 return 0;
1521}1521}
1522 1522
1523typedef struct TCCOption {1523typedef struct TCCOption {
@@ -1541,7 +1541,6 @@ enum { · 17 unmodified lines
1541 TCC_OPTION_bench,1541 TCC_OPTION_bench,
1542 TCC_OPTION_bt,1542 TCC_OPTION_bt,
1543 TCC_OPTION_b,1543 TCC_OPTION_b,
1544 TCC_OPTION_ba,
1545 TCC_OPTION_g,1544 TCC_OPTION_g,
1546 TCC_OPTION_c,1545 TCC_OPTION_c,
1547 TCC_OPTION_dumpmachine,1546 TCC_OPTION_dumpmachine,
@@ -1580,6 +1579,7 @@ enum { · 32 unmodified lines
1580 TCC_OPTION_x,1579 TCC_OPTION_x,
1581 TCC_OPTION_ar,1580 TCC_OPTION_ar,
1582 TCC_OPTION_impdef,1581 TCC_OPTION_impdef,
1582 /* macho */
1583 TCC_OPTION_dynamiclib,1583 TCC_OPTION_dynamiclib,
1584 TCC_OPTION_flat_namespace,1584 TCC_OPTION_flat_namespace,
1585 TCC_OPTION_two_levelnamespace,1585 TCC_OPTION_two_levelnamespace,
@@ -1617,11 +1617,13 @@ static const TCCOption tcc_options[] = { · 31 unmodified lines
1617#ifdef TCC_TARGET_MACHO1617#ifdef TCC_TARGET_MACHO
1618 { "compatibility_version", TCC_OPTION_compatibility_version, TCC_OPTION_HAS_ARG },1618 { "compatibility_version", TCC_OPTION_compatibility_version, TCC_OPTION_HAS_ARG },
1619 { "current_version", TCC_OPTION_current_version, TCC_OPTION_HAS_ARG },1619 { "current_version", TCC_OPTION_current_version, TCC_OPTION_HAS_ARG },
1620#endif
1621 { "c", TCC_OPTION_c, 0 },
1622#ifdef TCC_TARGET_MACHO
1623 { "dynamiclib", TCC_OPTION_dynamiclib, 0 },1620 { "dynamiclib", TCC_OPTION_dynamiclib, 0 },
1621 { "flat_namespace", TCC_OPTION_flat_namespace, 0 },
1622 { "install_name", TCC_OPTION_install_name, TCC_OPTION_HAS_ARG },
1623 { "two_levelnamespace", TCC_OPTION_two_levelnamespace, 0 },
1624 { "undefined", TCC_OPTION_undefined, TCC_OPTION_HAS_ARG },
1624#endif1625#endif
1626 { "c", TCC_OPTION_c, 0 },
1625 { "dumpmachine", TCC_OPTION_dumpmachine, 0},1627 { "dumpmachine", TCC_OPTION_dumpmachine, 0},
1626 { "dumpversion", TCC_OPTION_dumpversion, 0},1628 { "dumpversion", TCC_OPTION_dumpversion, 0},
1627 { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },1629 { "d", TCC_OPTION_d, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
@@ -1642,9 +1644,6 @@ static const TCCOption tcc_options[] = { · 14 unmodified lines
1642 { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },1644 { "mfloat-abi", TCC_OPTION_mfloat_abi, TCC_OPTION_HAS_ARG },
1643#endif1645#endif
1644 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },1646 { "m", TCC_OPTION_m, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1645#ifdef TCC_TARGET_MACHO
1646 { "flat_namespace", TCC_OPTION_flat_namespace, 0 },
1647#endif
1648 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },1647 { "f", TCC_OPTION_f, TCC_OPTION_HAS_ARG | TCC_OPTION_NOSEP },
1649 { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },1648 { "isystem", TCC_OPTION_isystem, TCC_OPTION_HAS_ARG },
1650 { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },1649 { "include", TCC_OPTION_include, TCC_OPTION_HAS_ARG },
@@ -1660,14 +1659,10 @@ static const TCCOption tcc_options[] = { · 9 unmodified lines
1660 { "MMD", TCC_OPTION_MMD, 0},1659 { "MMD", TCC_OPTION_MMD, 0},
1661 { "MP", TCC_OPTION_MP, 0},1660 { "MP", TCC_OPTION_MP, 0},
1662 { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },1661 { "x", TCC_OPTION_x, TCC_OPTION_HAS_ARG },
1662 /* tcctools */
1663 { "ar", TCC_OPTION_ar, 0},1663 { "ar", TCC_OPTION_ar, 0},
1664#ifdef TCC_TARGET_PE1664#ifdef TCC_TARGET_PE
1665 { "impdef", TCC_OPTION_impdef, 0},1665 { "impdef", TCC_OPTION_impdef, 0},
1666#endif
1667#ifdef TCC_TARGET_MACHO
1668 { "install_name", TCC_OPTION_install_name, TCC_OPTION_HAS_ARG },
1669 { "two_levelnamespace", TCC_OPTION_two_levelnamespace, 0 },
1670 { "undefined", TCC_OPTION_undefined, TCC_OPTION_HAS_ARG },
1671#endif1666#endif
1672 /* ignored (silently, except after -Wunsupported) */1667 /* ignored (silently, except after -Wunsupported) */
1673 { "arch", 0, TCC_OPTION_HAS_ARG},1668 { "arch", 0, TCC_OPTION_HAS_ARG},
@@ -1788,65 +1783,6 @@ static const char dumpmachine_str[] = · 114 unmodified lines
1788#endif1783#endif
1789;1784;
1790 1785
1791static int args_parser_make_argv(const char *r, int *argc, char ***argv)
1792{
1793 int ret = 0, q, c;
1794 CString str;
1795 for(;;) {
1796 while (c = (unsigned char)*r, c && c <= ' ')
1797 ++r;
1798 if (c == 0)
1799 break;
1800 q = 0;
1801 cstr_new(&str);
1802 while (c = (unsigned char)*r, c) {
1803 ++r;
1804 if (c == '\\' && (*r == '"' || *r == '\\')) {
1805 c = *r++;
1806 } else if (c == '"') {
1807 q = !q;
1808 continue;
1809 } else if (q == 0 && c <= ' ') {
1810 break;
1811 }
1812 cstr_ccat(&str, c);
1813 }
1814 cstr_ccat(&str, 0);
1815 //printf("<%s>\n", str.data), fflush(stdout);
1816 dynarray_add(argv, argc, tcc_strdup(str.data));
1817 cstr_free(&str);
1818 ++ret;
1819 }
1820 return ret;
1821}
1822
1823/* read list file */
1824static int args_parser_listfile(TCCState *s,
1825 const char *filename, int optind, int *pargc, char ***pargv)
1826{
1827 TCCState *s1 = s;
1828 int fd, i;
1829 char *p;
1830 int argc = 0;
1831 char **argv = NULL;
1832
1833 fd = open(filename, O_RDONLY | O_BINARY);
1834 if (fd < 0)
1835 return tcc_error_noabort("listfile '%s' not found", filename);
1836
1837 p = tcc_load_text(fd);
1838 for (i = 0; i < *pargc; ++i)
1839 if (i == optind)
1840 args_parser_make_argv(p, &argc, &argv);
1841 else
1842 dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
1843
1844 tcc_free(p);
1845 dynarray_reset(&s->argv, &s->argc);
1846 *pargc = s->argc = argc, *pargv = s->argv = argv;
1847 return 0;
1848}
1849
1850#if defined TCC_TARGET_MACHO1786#if defined TCC_TARGET_MACHO
1851static uint32_t parse_version(TCCState *s1, const char *version)1787static uint32_t parse_version(TCCState *s1, const char *version)
1852{1788{
@@ -1867,46 +1803,79 @@ static uint32_t parse_version(TCCState *s1, const char *version) · 14 unmodified lines
1867}1803}
1868#endif1804#endif
1869 1805
1870PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv, int optind)1806/* insert args from 'p' (separated by sep or ' ') into argv at position 'optind' */
1807static void insert_args(TCCState *s1, char ***pargv, int *pargc, int optind, const char *p, int sep)
1808{
1809 int argc = 0;
1810 char **argv = NULL;
1811 int i;
1812 for (i = 0; i < *pargc; ++i)
1813 if (i == optind)
1814 dynarray_split(&argv, &argc, p, sep);
1815 else
1816 dynarray_add(&argv, &argc, tcc_strdup((*pargv)[i]));
1817 dynarray_reset(&s1->argv, &s1->argc);
1818 *pargc = s1->argc = argc;
1819 *pargv = s1->argv = argv;
1820}
1821
1822static void args_parser_add_file(TCCState *s, const char* filename, int filetype)
1823{
1824 struct filespec *f = tcc_malloc(sizeof *f + strlen(filename));
1825 f->type = filetype;
1826 strcpy(f->name, filename);
1827 dynarray_add(&s->files, &s->nb_files, f);
1828 if (filetype & AFF_TYPE_LIB)
1829 ++s->nb_libraries;
1830}
1831
1832/* using * to argc/argv to let "tcc -ar" benefit from @listfile expansion */
1833PUB_FUNC int tcc_parse_args(TCCState *s, int *pargc, char ***pargv)
1871{1834{
1872 TCCState *s1 = s;1835 TCCState *s1 = s;
1873 const TCCOption *popt;1836 const TCCOption *popt;
1874 const char *optarg, *r;1837 const char *optarg, *r;
1875 const char *run = NULL;1838 const char *run = NULL;
1876 int x;1839 int x;
1877 int tool = 0, arg_start = 0, noaction = optind;1840 int tool = 0, arg_start = 0, not_empty = 0, optind = 1;
1878 char **argv = *pargv;1841 char **argv = *pargv;
1879 int argc = *pargc;1842 int argc = *pargc;
1880 1843
1881 cstr_reset(&s->linker_arg);1844 s->link_optind = s->link_argc;
1882 1845
1883 while (optind < argc) {1846 while (optind < argc) {
1884 r = argv[optind];1847 r = argv[optind];
1885 if (r[0] == '@' && r[1] != '\0') {1848 if (r[0] == '@' && r[1] != '\0') { /* read @listfile */
1886 if (args_parser_listfile(s, r + 1, optind, &argc, &argv))1849 int fd; char *p;
1887 return -1;1850 fd = open(++r, O_RDONLY | O_BINARY);
1851 if (fd < 0)
1852 return tcc_error_noabort("listfile '%s' not found", r);
1853 p = tcc_load_text(fd);
1854 insert_args(s1, &argv, &argc, optind, p, 0);
1855 close(fd), tcc_free(p);
1888 continue;1856 continue;
1889 }1857 }
1890 optind++;1858 optind++;
1891 if (tool) {1859 if (tool) { /* ignore all except -v and @listfile */
1892 if (r[0] == '-' && r[1] == 'v' && r[2] == 0)1860 s->verbose += !strcmp(r, "-v");
1893 ++s->verbose;
1894 continue;1861 continue;
1895 }1862 }
1896 if (r[0] != '-' || r[1] == '\0') {1863
1864 if (r[0] != '-' || r[1] == '\0') { /* file or '-' (stdin) */
1897 args_parser_add_file(s, r, s->filetype);1865 args_parser_add_file(s, r, s->filetype);
1866 not_empty = 1;
1867 dorun:
1898 if (run) {1868 if (run) {
1899dorun:1869 /* tcc -run <file> <args...> */
1900 if (tcc_set_options(s, run))1870 if (tcc_set_options(s, run))
1901 return -1;1871 return -1;
1902 arg_start = optind - 1;1872 arg_start = optind - 1; /* argv[0] will be <file> */
1903 break;1873 break;
1904 }1874 }
1905 continue;1875 continue;
1906 }1876 }
1907 1877 /* Also allow "tcc <files...> -run -- <args...>" */
1908 /* allow "tcc files... -run -- args ..." */1878 if (r[1] == '-' && r[2] == '\0')
1909 if (r[1] == '-' && r[2] == '\0' && run)
1910 goto dorun;1879 goto dorun;
1911 1880
1912 /* find option in table */1881 /* find option in table */
@@ -1921,7 +1890,6 @@ dorun: · 8 unmodified lines
1921 if (popt->flags & TCC_OPTION_HAS_ARG) {1890 if (popt->flags & TCC_OPTION_HAS_ARG) {
1922 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {1891 if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
1923 if (optind >= argc)1892 if (optind >= argc)
1924 arg_err:
1925 return tcc_error_noabort("argument to '%s' is missing", r);1893 return tcc_error_noabort("argument to '%s' is missing", r);
1926 optarg = argv[optind++];1894 optarg = argv[optind++];
1927 }1895 }
@@ -1931,12 +1899,6 @@ dorun: · 3 unmodified lines
1931 }1899 }
1932 1900
1933 switch(popt->index) {1901 switch(popt->index) {
1934 case TCC_OPTION_HELP:
1935 x = OPT_HELP;
1936 goto extra_action;
1937 case TCC_OPTION_HELP2:
1938 x = OPT_HELP2;
1939 goto extra_action;
1940 case TCC_OPTION_I:1902 case TCC_OPTION_I:
1941 tcc_add_include_path(s, optarg);1903 tcc_add_include_path(s, optarg);
1942 break;1904 break;
@@ -1952,11 +1914,9 @@ dorun: · 9 unmodified lines
1952 case TCC_OPTION_B:1914 case TCC_OPTION_B:
1953 /* set tcc utilities path (mainly for tcc development) */1915 /* set tcc utilities path (mainly for tcc development) */
1954 tcc_set_lib_path(s, optarg);1916 tcc_set_lib_path(s, optarg);
1955 ++noaction;1917 continue;
1956 break;
1957 case TCC_OPTION_l:1918 case TCC_OPTION_l:
1958 args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));1919 args_parser_add_file(s, optarg, AFF_TYPE_LIB | (s->filetype & ~AFF_TYPE_MASK));
1959 s->nb_libraries++;
1960 break;1920 break;
1961 case TCC_OPTION_pthread:1921 case TCC_OPTION_pthread:
1962 s->option_pthread = 1;1922 s->option_pthread = 1;
@@ -2027,14 +1987,14 @@ dorun: · 64 unmodified lines
2027 x = TCC_OUTPUT_DLL;1987 x = TCC_OUTPUT_DLL;
2028 goto set_output_type;1988 goto set_output_type;
2029 case TCC_OPTION_soname:1989 case TCC_OPTION_soname:
2030 s->soname = tcc_strdup(optarg);1990 tcc_set_str(&s->soname, optarg);
2031 break;1991 break;
2032 case TCC_OPTION_o:1992 case TCC_OPTION_o:
2033 if (s->outfile) {1993 if (s->outfile) {
2034 tcc_warning("multiple -o option");1994 tcc_warning("multiple -o option");
2035 tcc_free(s->outfile);1995 tcc_free(s->outfile);
2036 }1996 }
2037 s->outfile = tcc_strdup(optarg);1997 tcc_set_str(&s->outfile, optarg);
2038 break;1998 break;
2039 case TCC_OPTION_r:1999 case TCC_OPTION_r:
2040 /* generate a .o merging several output files */2000 /* generate a .o merging several output files */
@@ -2054,17 +2014,18 @@ dorun: · 13 unmodified lines
2054 s->nostdlib = 1;2014 s->nostdlib = 1;
2055 break;2015 break;
2056 case TCC_OPTION_run:2016 case TCC_OPTION_run:
2057#ifndef TCC_IS_NATIVE2017#ifdef TCC_IS_NATIVE
2058 return tcc_error_noabort("-run is not available in a cross compiler");2018 /* When from script "#!/usr/bin/tcc -run <options>",
2059#else2019 argv[1] is "-run <options>" and argv[2] is <script-name> */
2060 run = optarg;2020 run = optarg;
2061 x = TCC_OUTPUT_MEMORY;2021 x = TCC_OUTPUT_MEMORY;
2062 goto set_output_type;2022 goto set_output_type;
2023#else
2024 return tcc_error_noabort("-run is not available in a cross compiler");
2063#endif2025#endif
2064 case TCC_OPTION_v:2026 case TCC_OPTION_v:
2065 do ++s->verbose; while (*optarg++ == 'v');2027 do ++s->verbose; while (*optarg++ == 'v');
2066 ++noaction;2028 continue;
2067 break;
2068 case TCC_OPTION_f:2029 case TCC_OPTION_f:
2069 if (set_flag(s, options_f, optarg) < 0)2030 if (set_flag(s, options_f, optarg) < 0)
2070 goto unsupported_option;2031 goto unsupported_option;
@@ -2086,7 +2047,7 @@ dorun: · 15 unmodified lines
2086 goto unsupported_option;2047 goto unsupported_option;
2087 if (PTR_SIZE != x/8)2048 if (PTR_SIZE != x/8)
2088 return x;2049 return x;
2089 ++noaction;2050 continue;
2090 }2051 }
2091 break;2052 break;
2092 case TCC_OPTION_W:2053 case TCC_OPTION_W:
@@ -2101,25 +2062,13 @@ dorun: · 8 unmodified lines
2101 s->rdynamic = 1;2062 s->rdynamic = 1;
2102 break;2063 break;
2103 case TCC_OPTION_Wl:2064 case TCC_OPTION_Wl:
2104 if (s->linker_arg.size)2065 if (tcc_set_linker(s, optarg) < 0)
2105 ((char*)s->linker_arg.data)[s->linker_arg.size - 1] = ',';
2106 cstr_cat(&s->linker_arg, optarg, 0);
2107 x = tcc_set_linker(s, s->linker_arg.data);
2108 if (x)
2109 cstr_reset(&s->linker_arg);
2110 if (x < 0)
2111 return -1;2066 return -1;
2112 break;2067 break;
2113 case TCC_OPTION_Wp:2068 case TCC_OPTION_Wp:
2114 {2069 if (argv[0]) /* not with tcc_set_options() */
2115 char *p = tcc_strdup(optarg), *q = p;2070 insert_args(s, &argv, &argc, --optind, optarg, ',');
2116 while (!!(q = strchr(q, ','))) *q++ = ' ';
2117 x = tcc_set_options(s, p);
2118 tcc_free(p);
2119 if (x < 0)
2120 return -1;
2121 break;2071 break;
2122 }
2123 case TCC_OPTION_E:2072 case TCC_OPTION_E:
2124 x = TCC_OUTPUT_PREPROCESS;2073 x = TCC_OUTPUT_PREPROCESS;
2125 goto set_output_type;2074 goto set_output_type;
@@ -2132,7 +2081,7 @@ dorun: · 6 unmodified lines
2132 case TCC_OPTION_MM:2081 case TCC_OPTION_MM:
2133 s->just_deps = 1;2082 s->just_deps = 1;
2134 if(!s->deps_outfile)2083 if(!s->deps_outfile)
2135 s->deps_outfile = tcc_strdup("-");2084 tcc_set_str(&s->deps_outfile, "-");
2136 // fall through2085 // fall through
2137 case TCC_OPTION_MMD:2086 case TCC_OPTION_MMD:
2138 s->gen_deps = 1;2087 s->gen_deps = 1;
@@ -2142,7 +2091,7 @@ dorun: · 3 unmodified lines
2142 s->include_sys_deps = 1;2091 s->include_sys_deps = 1;
2143 break;2092 break;
2144 case TCC_OPTION_MF:2093 case TCC_OPTION_MF:
2145 s->deps_outfile = tcc_strdup(optarg);2094 tcc_set_str(&s->deps_outfile, optarg);
2146 break;2095 break;
2147 case TCC_OPTION_MP:2096 case TCC_OPTION_MP:
2148 s->gen_phony_deps = 1;2097 s->gen_phony_deps = 1;
@@ -2170,12 +2119,6 @@ dorun: · 21 unmodified lines
2170 case TCC_OPTION_O:2119 case TCC_OPTION_O:
2171 s->optimize = isnum(optarg[0]) ? optarg[0]-'0' : 1 /* -O -Os */;2120 s->optimize = isnum(optarg[0]) ? optarg[0]-'0' : 1 /* -O -Os */;
2172 break;2121 break;
2173 case TCC_OPTION_print_search_dirs:
2174 x = OPT_PRINT_DIRS;
2175 goto extra_action;
2176 case TCC_OPTION_impdef:
2177 x = OPT_IMPDEF;
2178 goto extra_action;
2179#if defined TCC_TARGET_MACHO2122#if defined TCC_TARGET_MACHO
2180 case TCC_OPTION_dynamiclib:2123 case TCC_OPTION_dynamiclib:
2181 x = TCC_OUTPUT_DLL;2124 x = TCC_OUTPUT_DLL;
@@ -2187,7 +2130,7 @@ dorun: · 5 unmodified lines
2187 case TCC_OPTION_undefined:2130 case TCC_OPTION_undefined:
2188 break;2131 break;
2189 case TCC_OPTION_install_name:2132 case TCC_OPTION_install_name:
2190 s->install_name = tcc_strdup(optarg);2133 tcc_set_str(&s->install_name, optarg);
2191 break;2134 break;
2192 case TCC_OPTION_compatibility_version:2135 case TCC_OPTION_compatibility_version:
2193 s->compatibility_version = parse_version(s, optarg);2136 s->compatibility_version = parse_version(s, optarg);
@@ -2196,11 +2139,23 @@ dorun: · 2 unmodified lines
2196 s->current_version = parse_version(s, optarg);;2139 s->current_version = parse_version(s, optarg);;
2197 break;2140 break;
2198#endif2141#endif
2142 case TCC_OPTION_HELP:
2143 x = OPT_HELP;
2144 goto extra_action;
2145 case TCC_OPTION_HELP2:
2146 x = OPT_HELP2;
2147 goto extra_action;
2148 case TCC_OPTION_print_search_dirs:
2149 x = OPT_PRINT_DIRS;
2150 goto extra_action;
2151 case TCC_OPTION_impdef:
2152 x = OPT_IMPDEF;
2153 goto extra_action;
2199 case TCC_OPTION_ar:2154 case TCC_OPTION_ar:
2200 x = OPT_AR;2155 x = OPT_AR;
2201 extra_action:2156 extra_action:
2202 arg_start = optind - 1;2157 arg_start = optind - 1;
2203 if (arg_start != noaction)2158 if (not_empty)
2204 return tcc_error_noabort("cannot parse %s here", r);2159 return tcc_error_noabort("cannot parse %s here", r);
2205 tool = x;2160 tool = x;
2206 break;2161 break;
@@ -2209,16 +2164,19 @@ unsupported_option: · 2 unmodified lines
2209 tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);2164 tcc_warning_c(warn_unsupported)("unsupported option '%s'", r);
2210 break;2165 break;
2211 }2166 }
2167 not_empty = 1;
2212 }2168 }
2213 if (s->linker_arg.size) {2169
2214 r = s->linker_arg.data;2170 if (s->link_optind < s->link_argc)
2215 goto arg_err;2171 return tcc_error_noabort("argument to '-Wl,%s' is missing", s->link_argv[s->link_optind]);
2216 }2172 if (NULL == argv[0]) /* from tcc_set_options() */
2217 *pargc = argc - arg_start;2173 return 0;
2218 *pargv = argv + arg_start;2174 if (arg_start) {
2219 if (tool)2175 *pargc = argc - arg_start;
2176 *pargv = argv + arg_start;
2220 return tool;2177 return tool;
2221 if (optind != noaction)2178 }
2179 if (not_empty)
2222 return 0;2180 return 0;
2223 if (s->verbose == 2)2181 if (s->verbose == 2)
2224 return OPT_PRINT_DIRS;2182 return OPT_PRINT_DIRS;
@@ -2231,10 +2189,11 @@ LIBTCCAPI int tcc_set_options(TCCState *s, const char *r) · 6 unmodified lines
2231{2189{
2232 char **argv = NULL;2190 char **argv = NULL;
2233 int argc = 0, ret;2191 int argc = 0, ret;
2234 args_parser_make_argv(r, &argc, &argv);2192 dynarray_add(&argv, &argc, 0);
2235 ret = tcc_parse_args(s, &argc, &argv, 0);2193 dynarray_split(&argv, &argc, r, 0);
2194 ret = tcc_parse_args(s, &argc, &argv);
2236 dynarray_reset(&argv, &argc);2195 dynarray_reset(&argv, &argc);
2237 return ret < 0 ? ret : 0;2196 return ret;
2238}2197}
2239 2198
2240PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)2199PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time)
@@ -2267,9 +2226,3 @@ PUB_FUNC void tcc_print_stats(TCCState *s1, unsigned total_time) · 26 unmodified lines
2267 fprintf(stderr, " %d max (bytes)\n", mem_max_size);2226 fprintf(stderr, " %d max (bytes)\n", mem_max_size);
2268#endif2227#endif
2269}2228}
2270
2271#if ONE_SOURCE
2272# undef malloc
2273# undef realloc
2274# undef free
2275#endif
tcc-doc.texi+12−10
@@ -185,16 +185,6 @@ Show included files. As sole argument, print search dirs. -vvv shows tries too · 184 unmodified lines
185@item -bench185@item -bench
186Display compilation statistics.186Display compilation statistics.
187 187
188@item -pthread
189Preprocess with @option{-D_REENTRANT}, link with @option{-lpthread}.
190
191@item -On
192Pretend to optimise: set @option{-D__OPTIMIZE__} to the numeric value of n.
193Note that TCC performs no additional optimisation.
194
195@item -dt
196With @option{-run}/@option{-E}: auto-define 'test_...' macros
197
198@end table188@end table
199 189
200Preprocessor options:190Preprocessor options:
@@ -441,6 +431,12 @@ gnu11; @code{199901} otherwise. · 240 unmodified lines
441@item -x[c|a|b|n]431@item -x[c|a|b|n]
442Specify content of next input file: respectively C, assembly, binary, or none.432Specify content of next input file: respectively C, assembly, binary, or none.
443 433
434@item -O[n]
435Same as @option{-D__OPTIMIZE__} except for -O0.
436
437@item -pthread
438Preprocess with @option{-D_REENTRANT}, link with @option{-lpthread}.
439
444@item -M440@item -M
445Just output makefile fragment with dependencies441Just output makefile fragment with dependencies
446 442
@@ -456,6 +452,9 @@ Like -MD except mention only user header files, not system header files. · 9 unmodified lines
456@item -MF depfile452@item -MF depfile
457Use @file{depfile} as output for -MD.453Use @file{depfile} as output for -MD.
458 454
455@item -MP
456Mention all dependencies as targets too.
457
459@item -print-search-dirs458@item -print-search-dirs
460Print the configured installation directory and a list of library459Print the configured installation directory and a list of library
461and include directories tcc will search.460and include directories tcc will search.
@@ -463,6 +462,9 @@ and include directories tcc will search. · 1 unmodified line
463@item -dumpversion462@item -dumpversion
464Print version.463Print version.
465 464
465@item -dt
466With @option{-run}/@option{-E}: auto-define 'test_...' macros
467
466@end table468@end table
467 469
468Target specific options:470Target specific options:
tcc.c+6−4
@@ -158,7 +158,7 @@ static const char help2[] = · 157 unmodified lines
158#endif158#endif
159 " -Bsymbolic set DT_SYMBOLIC elf tag\n"159 " -Bsymbolic set DT_SYMBOLIC elf tag\n"
160 " -oformat=[elf32/64-* binary] set executable output format\n"160 " -oformat=[elf32/64-* binary] set executable output format\n"
161 " -init= -fini= -Map= -as-needed -O (ignored)\n"161 " -init= -fini= -Map= -as-needed -O -z= (ignored)\n"
162 "Predefined macros:\n"162 "Predefined macros:\n"
163 " tcc -E -dM - < /dev/null\n"163 " tcc -E -dM - < /dev/null\n"
164#endif164#endif
@@ -221,7 +221,7 @@ static void print_search_dirs(TCCState *s) · 56 unmodified lines
221 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);221 print_dirs("include", s->sysinclude_paths, s->nb_sysinclude_paths);
222 print_dirs("libraries", s->library_paths, s->nb_library_paths);222 print_dirs("libraries", s->library_paths, s->nb_library_paths);
223 printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);223 printf("libtcc1:\n %s/%s\n", s->library_paths[0], CONFIG_TCC_CROSSPREFIX TCC_LIBTCC1);
224#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO224#ifdef TCC_TARGET_UNIX
225 print_dirs("crt", s->crt_paths, s->nb_crt_paths);225 print_dirs("crt", s->crt_paths, s->nb_crt_paths);
226 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));226 printf("elfinterp:\n %s\n", DEFAULT_ELFINTERP(s));
227#endif227#endif
@@ -253,7 +253,9 @@ static char *default_outputfile(TCCState *s, const char *first_file) · 25 unmodified lines
253 253
254 if (first_file && strcmp(first_file, "-"))254 if (first_file && strcmp(first_file, "-"))
255 name = tcc_basename(first_file);255 name = tcc_basename(first_file);
256 snprintf(buf, sizeof(buf), "%s", name);256 if (strlen(name) + 4 >= sizeof buf)
257 name = "a";
258 strcpy(buf, name);
257 ext = tcc_fileextension(buf);259 ext = tcc_fileextension(buf);
258#ifdef TCC_TARGET_PE260#ifdef TCC_TARGET_PE
259 if (s->output_type == TCC_OUTPUT_DLL)261 if (s->output_type == TCC_OUTPUT_DLL)
@@ -293,7 +295,7 @@ int main(int argc0, char **argv0) · 33 unmodified lines
293redo:295redo:
294 argc = argc0, argv = argv0;296 argc = argc0, argv = argv0;
295 s = s1 = tcc_new();297 s = s1 = tcc_new();
296 opt = tcc_parse_args(s, &argc, &argv, 1);298 opt = tcc_parse_args(s, &argc, &argv);
297 if (opt < 0)299 if (opt < 0)
298 return 1;300 return 1;
299 301
tcc.h+12−11
@@ -217,6 +217,8 @@ extern long double strtold (const char *__nptr, char **__endptr); · 216 unmodified lines
217 217
218#if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO218#if defined TCC_TARGET_PE || defined TCC_TARGET_MACHO
219# define ELF_OBJ_ONLY /* create elf .o but native executables */219# define ELF_OBJ_ONLY /* create elf .o but native executables */
220#else
221# define TCC_TARGET_UNIX 1
220#endif222#endif
221 223
222/* No ten-byte long doubles on window and macos except in224/* No ten-byte long doubles on window and macos except in
@@ -919,8 +921,6 @@ struct TCCState { · 696 unmodified lines
919 /* debug state */921 /* debug state */
920 struct _tccdbg *dState;922 struct _tccdbg *dState;
921 923
922 /* Is there a new undefined sym since last new_undef_sym() */
923 int new_undef_sym;
924 /* extra attributes (eg. GOT/PLT value) for symtab symbols */924 /* extra attributes (eg. GOT/PLT value) for symtab symbols */
925 struct sym_attr *sym_attrs;925 struct sym_attr *sym_attrs;
926 int nb_sym_attrs;926 int nb_sym_attrs;
@@ -988,7 +988,7 @@ struct TCCState { · 61 unmodified lines
988 unsigned int total_output[4];988 unsigned int total_output[4];
989 989
990 /* used by tcc_load_ldscript */990 /* used by tcc_load_ldscript */
991 int fd, cc;991 unsigned char *ld_p; /* text pointer */
992 992
993 /* for warnings/errors for object files */993 /* for warnings/errors for object files */
994 const char *current_filename;994 const char *current_filename;
@@ -1001,7 +1001,9 @@ struct TCCState { · 6 unmodified lines
1001 char *deps_outfile; /* option -MF */1001 char *deps_outfile; /* option -MF */
1002 int argc;1002 int argc;
1003 char **argv;1003 char **argv;
1004 CString linker_arg; /* collect -Wl options */1004 /* -Wl options */
1005 char **link_argv;
1006 int link_argc, link_optind;
1005};1007};
1006 1008
1007struct filespec {1009struct filespec {
@@ -1195,7 +1197,7 @@ ST_DATA int g_debug; · 187 unmodified lines
1195/* public functions currently used by the tcc main function */1197/* public functions currently used by the tcc main function */
1196ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);1198ST_FUNC char *pstrcpy(char *buf, size_t buf_size, const char *s);
1197ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s);1199ST_FUNC char *pstrcat(char *buf, size_t buf_size, const char *s);
1198ST_FUNC char *pstrncpy(char *out, const char *in, size_t num);1200ST_FUNC char *pstrncpy(char *out, size_t buf_size, const char *s, size_t num);
1199PUB_FUNC char *tcc_basename(const char *name);1201PUB_FUNC char *tcc_basename(const char *name);
1200PUB_FUNC char *tcc_fileextension (const char *name);1202PUB_FUNC char *tcc_fileextension (const char *name);
1201 1203
@@ -1265,7 +1267,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 63 unmodified lines
1265#define AFF_TYPE_ASM 21267#define AFF_TYPE_ASM 2
1266#define AFF_TYPE_ASMPP 41268#define AFF_TYPE_ASMPP 4
1267#define AFF_TYPE_LIB 81269#define AFF_TYPE_LIB 8
1268#define AFF_TYPE_MASK (15 | AFF_TYPE_BIN)1270#define AFF_TYPE_MASK (7 | AFF_TYPE_BIN)
1269/* values from tcc_object_type(...) */1271/* values from tcc_object_type(...) */
1270#define AFF_BINTYPE_REL 11272#define AFF_BINTYPE_REL 1
1271#define AFF_BINTYPE_DYN 21273#define AFF_BINTYPE_DYN 2
@@ -1274,6 +1276,7 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 2 unmodified lines
1274 1276
1275/* return value of tcc_add_file_internal(): 0, -1, or FILE_NOT_FOUND */1277/* return value of tcc_add_file_internal(): 0, -1, or FILE_NOT_FOUND */
1276#define FILE_NOT_FOUND -21278#define FILE_NOT_FOUND -2
1279#define FILE_NOT_RECOGNIZED -3 /* unrecognized file type */
1277 1280
1278#ifndef ELF_OBJ_ONLY1281#ifndef ELF_OBJ_ONLY
1279ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);1282ST_FUNC int tcc_add_crt(TCCState *s, const char *filename);
@@ -1289,7 +1292,7 @@ ST_FUNC void tcc_add_btstub(TCCState *s1); · 9 unmodified lines
1289ST_FUNC void tcc_add_pragma_libs(TCCState *s1);1292ST_FUNC void tcc_add_pragma_libs(TCCState *s1);
1290PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);1293PUB_FUNC int tcc_add_library_err(TCCState *s, const char *f);
1291PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);1294PUB_FUNC void tcc_print_stats(TCCState *s, unsigned total_time);
1292PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv, int optind);1295PUB_FUNC int tcc_parse_args(TCCState *s, int *argc, char ***argv);
1293#ifdef _WIN321296#ifdef _WIN32
1294ST_FUNC char *normalize_slashes(char *path);1297ST_FUNC char *normalize_slashes(char *path);
1295#endif1298#endif
@@ -1571,7 +1574,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1); · 275 unmodified lines
1571 1574
1572/* ------------ xxx-link.c ------------ */1575/* ------------ xxx-link.c ------------ */
1573 1576
1574#if !defined ELF_OBJ_ONLY || defined TCC_TARGET_MACHO1577#ifndef TCC_TARGET_PE
1575ST_FUNC int code_reloc (int reloc_type);1578ST_FUNC int code_reloc (int reloc_type);
1576ST_FUNC int gotplt_entry_type (int reloc_type);1579ST_FUNC int gotplt_entry_type (int reloc_type);
1577/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so1580/* Whether to generate a GOT/PLT entry and when. NO_GOTPLT_ENTRY is first so
@@ -1583,13 +1586,11 @@ enum gotplt_entry { · 5 unmodified lines
1583 ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */1586 ALWAYS_GOTPLT_ENTRY /* always generate (eg. PLTOFF relocs) */
1584};1587};
1585#define NEED_RELOC_TYPE1588#define NEED_RELOC_TYPE
1586
1587#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE1589#if !defined TCC_TARGET_MACHO || defined TCC_IS_NATIVE
1588ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);1590ST_FUNC unsigned create_plt_entry(TCCState *s1, unsigned got_offset, struct sym_attr *attr);
1589ST_FUNC void relocate_plt(TCCState *s1);1591ST_FUNC void relocate_plt(TCCState *s1);
1590ST_FUNC void build_got_entries(TCCState *s1, int got_sym); /* in tccelf.c */1592ST_FUNC void build_got_entries(TCCState *s1, int got_sym); /* in tccelf.c */
1591#define NEED_BUILD_GOT1593#define NEED_BUILD_GOT
1592
1593#endif1594#endif
1594#endif1595#endif
1595 1596
@@ -1809,7 +1810,7 @@ ST_FUNC int macho_load_dll(TCCState *s1, int fd, const char *filename, int lev); · 213 unmodified lines
1809ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev);1810ST_FUNC int macho_load_tbd(TCCState *s1, int fd, const char *filename, int lev);
1810#ifdef TCC_IS_NATIVE1811#ifdef TCC_IS_NATIVE
1811ST_FUNC void tcc_add_macos_sdkpath(TCCState* s);1812ST_FUNC void tcc_add_macos_sdkpath(TCCState* s);
1812ST_FUNC const char* macho_tbd_soname(const char* filename);1813ST_FUNC char* macho_tbd_soname(int fd);
1813#endif1814#endif
1814#endif1815#endif
1815/* ------------ tccrun.c ----------------- */1816/* ------------ tccrun.c ----------------- */
tccelf.c+94−114
@@ -526,6 +526,24 @@ LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) · 525 unmodified lines
526 return addr == -1 ? NULL : (void*)(uintptr_t)addr;526 return addr == -1 ? NULL : (void*)(uintptr_t)addr;
527}527}
528 528
529LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val)
530{
531#ifdef TCC_TARGET_PE
532 /* On x86_64 'val' might not be reachable with a 32bit offset.
533 So it is handled here as if it were in a DLL. */
534 pe_putimport(s1, 0, name, (uintptr_t)val);
535#else
536 char buf[256];
537 if (s1->leading_underscore) {
538 buf[0] = '_';
539 pstrcpy(buf + 1, sizeof(buf) - 1, name);
540 name = buf;
541 }
542 set_global_sym(s1, name, NULL, (addr_t)(uintptr_t)val); /* NULL: SHN_ABS */
543#endif
544 return 0;
545}
546
529/* list elf symbol names and values */547/* list elf symbol names and values */
530ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,548ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
531 void (*symbol_cb)(void *ctx, const char *name, const void *val))549 void (*symbol_cb)(void *ctx, const char *name, const void *val))
@@ -733,7 +751,6 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size, · 201 unmodified lines
733 do_patch:751 do_patch:
734 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);752 esym->st_info = ELFW(ST_INFO)(sym_bind, sym_type);
735 esym->st_shndx = shndx;753 esym->st_shndx = shndx;
736 s1->new_undef_sym = 1;
737 esym->st_value = value;754 esym->st_value = value;
738 esym->st_size = size;755 esym->st_size = size;
739 }756 }
@@ -1058,15 +1075,16 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) · 318 unmodified lines
1058 if (do_resolve) {1075 if (do_resolve) {
1059#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE1076#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
1060 /* dlsym() needs the undecorated name. */1077 /* dlsym() needs the undecorated name. */
1061 void *addr = dlsym(RTLD_DEFAULT, &name[s1->leading_underscore]);1078 const char *name_ud = &name[s1->leading_underscore];
1062#if TARGETOS_OpenBSD || TARGETOS_FreeBSD || TARGETOS_NetBSD || TARGETOS_ANDROID1079 void *addr = NULL;
1080 if (!s1->nostdlib)
1081 addr = dlsym(RTLD_DEFAULT, name_ud);
1063 if (addr == NULL) {1082 if (addr == NULL) {
1064 int i;1083 int i;
1065 for (i = 0; i < s1->nb_loaded_dlls; i++)1084 for (i = 0; i < s1->nb_loaded_dlls; i++)
1066 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name)))1085 if ((addr = dlsym(s1->loaded_dlls[i]->handle, name_ud)))
1067 break;1086 break;
1068 }1087 }
1069#endif
1070 if (addr) {1088 if (addr) {
1071 sym->st_value = (addr_t) addr;1089 sym->st_value = (addr_t) addr;
1072#ifdef DEBUG_RELOC1090#ifdef DEBUG_RELOC
@@ -1691,7 +1709,7 @@ static void tcc_tcov_add_file(TCCState *s1, const char *filename) · 618 unmodified lines
1691 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);1709 set_local_sym(s1, &"___tcov_data"[!s1->leading_underscore], tcov_section, 0);
1692}1710}
1693 1711
1694#if !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO1712#ifdef TCC_TARGET_UNIX
1695/* add libc crt1/crti objects */1713/* add libc crt1/crti objects */
1696ST_FUNC void tccelf_add_crtbegin(TCCState *s1)1714ST_FUNC void tccelf_add_crtbegin(TCCState *s1)
1697{1715{
@@ -1750,7 +1768,7 @@ ST_FUNC void tccelf_add_crtend(TCCState *s1) · 52 unmodified lines
1750 tcc_add_crt(s1, "crtn.o");1768 tcc_add_crt(s1, "crtn.o");
1751#endif1769#endif
1752}1770}
1753#endif /* !defined TCC_TARGET_PE && !defined TCC_TARGET_MACHO */1771#endif /* TCC_TARGET_UNIX */
1754 1772
1755#ifndef TCC_TARGET_PE1773#ifndef TCC_TARGET_PE
1756/* add tcc runtime libraries */1774/* add tcc runtime libraries */
@@ -3789,19 +3807,15 @@ ST_FUNC int tcc_load_dll(TCCState *s1, int fd, const char *filename, int level) · 2032 unmodified lines
3789 3807
3790#define LD_TOK_NAME 2563808#define LD_TOK_NAME 256
3791#define LD_TOK_EOF (-1)3809#define LD_TOK_EOF (-1)
3792
3793static int ld_inp(TCCState *s1)3810static int ld_inp(TCCState *s1)
3794{3811{
3795 char b;3812 int c = *s1->ld_p;
3796 if (s1->cc != -1) {3813 if (c == 0)
3797 int c = s1->cc;3814 return CH_EOF;
3798 s1->cc = -1;3815 ++s1->ld_p;
3799 return c;3816 return c;
3800 }
3801 if (1 == read(s1->fd, &b, 1))
3802 return b;
3803 return CH_EOF;
3804}3817}
3818#define ld_unget(s1, ch) if (ch != CH_EOF) --s1->ld_p
3805 3819
3806/* return next ld script token */3820/* return next ld script token */
3807static int ld_next(TCCState *s1, char *name, int name_size)3821static int ld_next(TCCState *s1, char *name, int name_size)
@@ -3811,6 +3825,7 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 3 unmodified lines
3811 3825
3812 redo:3826 redo:
3813 ch = ld_inp(s1);3827 ch = ld_inp(s1);
3828 q = name, *q++ = ch;
3814 switch(ch) {3829 switch(ch) {
3815 case ' ':3830 case ' ':
3816 case '\t':3831 case '\t':
@@ -3829,8 +3844,6 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 12 unmodified lines
3829 }3844 }
3830 goto redo;3845 goto redo;
3831 } else {3846 } else {
3832 q = name;
3833 *q++ = '/';
3834 goto parse_name;3847 goto parse_name;
3835 }3848 }
3836 break;3849 break;
@@ -3889,13 +3902,14 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 52 unmodified lines
3889 case 'X':3902 case 'X':
3890 case 'Y':3903 case 'Y':
3891 case 'Z':3904 case 'Z':
3905 case '-':
3892 case '_':3906 case '_':
3893 case '.':3907 case '.':
3894 case '$':3908 case '$':
3895 case '~':3909 case '~':
3896 q = name;
3897 parse_name:
3898 for(;;) {3910 for(;;) {
3911 ch = ld_inp(s1);
3912 parse_name:
3899 if (!((ch >= 'a' && ch <= 'z') ||3913 if (!((ch >= 'a' && ch <= 'z') ||
3900 (ch >= 'A' && ch <= 'Z') ||3914 (ch >= 'A' && ch <= 'Z') ||
3901 (ch >= '0' && ch <= '9') ||3915 (ch >= '0' && ch <= '9') ||
@@ -3904,10 +3918,8 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 2 unmodified lines
3904 if ((q - name) < name_size - 1) {3918 if ((q - name) < name_size - 1) {
3905 *q++ = ch;3919 *q++ = ch;
3906 }3920 }
3907 ch = ld_inp(s1);
3908 }3921 }
3909 s1->cc = ch;3922 ld_unget(s1, ch);
3910 *q = '\0';
3911 c = LD_TOK_NAME;3923 c = LD_TOK_NAME;
3912 break;3924 break;
3913 case CH_EOF:3925 case CH_EOF:
@@ -3917,93 +3929,71 @@ static int ld_next(TCCState *s1, char *name, int name_size) · 3 unmodified lines
3917 c = ch;3929 c = ch;
3918 break;3930 break;
3919 }3931 }
3932 *q = '\0';
3920 return c;3933 return c;
3921}3934}
3922 3935
3923static int ld_add_file(TCCState *s1, const char filename[])3936static int ld_add_file(TCCState *s1, const char filename[])
3924{3937{
3925 if (filename[0] == '/') {3938 if (filename[0] == '-' && filename[1] == 'l')
3926 if (CONFIG_SYSROOT[0] == '\0'3939 return tcc_add_library(s1, filename + 2);
3927 && tcc_add_file_internal(s1, filename, AFF_TYPE_BIN) == 0)3940 if (CONFIG_SYSROOT[0] != '\0') {
3928 return 0;3941 /* lookup via library paths */
3929 filename = tcc_basename(filename);3942 int ret = tcc_add_dll(s1, tcc_basename(filename), 0);
3943 if (ret != FILE_NOT_FOUND)
3944 return ret;
3930 }3945 }
3931 return tcc_add_dll(s1, filename, AFF_PRINT_ERROR);3946 return tcc_add_file_internal(s1, filename, AFF_PRINT_ERROR);
3932}3947}
3933 3948
3934static int ld_add_file_list(TCCState *s1, const char *cmd, int as_needed)3949/* did static libraries add new undefined symbols? */
3950static int new_undef_sym(TCCState *s1, int sym_offset)
3935{3951{
3936 char filename[1024], libname[1016];3952 while (sym_offset < s1->symtab->data_offset) {
3937 int t, group, nblibs = 0, ret = 0;3953 ElfW(Sym) *esym = (void*)(s1->symtab->data + sym_offset);
3938 char **libs = NULL;3954 if (esym->st_shndx == SHN_UNDEF)
3955 return 1;
3956 sym_offset += sizeof (ElfW(Sym));
3957 }
3958 return 0;
3959}
3960
3961static int ld_add_file_list(TCCState *s1, const char *cmd)
3962{
3963 char filename[1024];
3964 int t, c, sym_offset, ret = 0;
3965 unsigned char *pos = s1->ld_p;
3966
3967repeat:
3968 s1->ld_p = pos;
3969 sym_offset = s1->symtab->data_offset;
3970 c = cmd[0];
3939 3971
3940 group = !strcmp(cmd, "GROUP");
3941 if (!as_needed)
3942 s1->new_undef_sym = 0;
3943 t = ld_next(s1, filename, sizeof(filename));3972 t = ld_next(s1, filename, sizeof(filename));
3944 if (t != '(') {3973 if (t != '(')
3945 ret = tcc_error_noabort("( expected");3974 return tcc_error_noabort("expected '(' after %s", cmd);
3946 goto lib_parse_error;
3947 }
3948 t = ld_next(s1, filename, sizeof(filename));3975 t = ld_next(s1, filename, sizeof(filename));
3949 for(;;) {3976 for(;;) {
3950 libname[0] = '\0';
3951 if (t == LD_TOK_EOF) {3977 if (t == LD_TOK_EOF) {
3952 ret = tcc_error_noabort("unexpected end of file");3978 return tcc_error_noabort("unexpected end of file");
3953 goto lib_parse_error;
3954 } else if (t == ')') {3979 } else if (t == ')') {
3955 break;3980 break;
3956 } else if (t == '-') {
3957 t = ld_next(s1, filename, sizeof(filename));
3958 if ((t != LD_TOK_NAME) || (filename[0] != 'l')) {
3959 ret = tcc_error_noabort("library name expected");
3960 goto lib_parse_error;
3961 }
3962 pstrcpy(libname, sizeof libname, &filename[1]);
3963 if (s1->static_link) {
3964 snprintf(filename, sizeof filename, "lib%s.a", libname);
3965 } else {
3966 snprintf(filename, sizeof filename, "lib%s.so", libname);
3967 }
3968 } else if (t != LD_TOK_NAME) {3981 } else if (t != LD_TOK_NAME) {
3969 ret = tcc_error_noabort("filename expected");3982 return tcc_error_noabort("unexpected token '%c'", t);
3970 goto lib_parse_error;3983 } else if (!strcmp(filename, "AS_NEEDED")) {
3971 }3984 ret = ld_add_file_list(s1, filename);
3972 if (!strcmp(filename, "AS_NEEDED")) {3985 } else if (c == 'I' || c == 'G' || c == 'A') {
3973 ret = ld_add_file_list(s1, cmd, 1);3986 ret = ld_add_file(s1, filename);
3974 if (ret)
3975 goto lib_parse_error;
3976 } else {
3977 /* TODO: Implement AS_NEEDED support. */
3978 /* DT_NEEDED is not used any more so ignore as_needed */
3979 if (1 || !as_needed) {
3980 ret = ld_add_file(s1, filename);
3981 if (ret)
3982 goto lib_parse_error;
3983 if (group) {
3984 /* Add the filename *and* the libname to avoid future conversions */
3985 dynarray_add(&libs, &nblibs, tcc_strdup(filename));
3986 if (libname[0] != '\0')
3987 dynarray_add(&libs, &nblibs, tcc_strdup(libname));
3988 }
3989 }
3990 }3987 }
3988 if (ret)
3989 return -1;
3991 t = ld_next(s1, filename, sizeof(filename));3990 t = ld_next(s1, filename, sizeof(filename));
3992 if (t == ',') {3991 if (t == ',')
3993 t = ld_next(s1, filename, sizeof(filename));3992 t = ld_next(s1, filename, sizeof(filename));
3994 }
3995 }3993 }
3996 if (group && !as_needed) {3994 if (c == 'G' && new_undef_sym(s1, sym_offset))
3997 while (s1->new_undef_sym) {3995 goto repeat;
3998 int i;3996 return 0;
3999 s1->new_undef_sym = 0;
4000 for (i = 0; i < nblibs; i ++)
4001 ld_add_file(s1, libs[i]);
4002 }
4003 }
4004lib_parse_error:
4005 dynarray_reset(&libs, &nblibs);
4006 return ret;
4007}3997}
4008 3998
4009/* interpret a subset of GNU ldscripts to handle the dummy libc.so3999/* interpret a subset of GNU ldscripts to handle the dummy libc.so
@@ -4011,40 +4001,30 @@ lib_parse_error: · 1 unmodified line
4011ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)4001ST_FUNC int tcc_load_ldscript(TCCState *s1, int fd)
4012{4002{
4013 char cmd[64];4003 char cmd[64];
4014 char filename[1024];4004 int t, ret = FILE_NOT_RECOGNIZED;
4015 int t, ret;4005 unsigned char *text_ptr, *saved_ptr;
4016 4006
4017 s1->fd = fd;4007 saved_ptr = s1->ld_p;
4018 s1->cc = -1;4008 s1->ld_p = text_ptr = (void*)tcc_load_text(fd);
4019 for(;;) {4009 for(;;) {
4020 t = ld_next(s1, cmd, sizeof(cmd));4010 t = ld_next(s1, cmd, sizeof(cmd));
4021 if (t == LD_TOK_EOF)4011 if (t == LD_TOK_EOF)
4022 return 0;4012 break;
4023 else if (t != LD_TOK_NAME)
4024 return -1;
4025 if (!strcmp(cmd, "INPUT") ||4013 if (!strcmp(cmd, "INPUT") ||
4026 !strcmp(cmd, "GROUP")) {4014 !strcmp(cmd, "GROUP")) {
4027 ret = ld_add_file_list(s1, cmd, 0);4015 ret = ld_add_file_list(s1, cmd);
4028 if (ret)
4029 return ret;
4030 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||4016 } else if (!strcmp(cmd, "OUTPUT_FORMAT") ||
4031 !strcmp(cmd, "TARGET")) {4017 !strcmp(cmd, "TARGET")) {
4032 /* ignore some commands */4018 /* ignore some commands */
4033 t = ld_next(s1, cmd, sizeof(cmd));4019 ret = ld_add_file_list(s1, cmd);
4034 if (t != '(')4020 } else if (0 == ret) {
4035 return tcc_error_noabort("( expected");4021 ret = tcc_error_noabort("unexpected '%s'", cmd);
4036 for(;;) {
4037 t = ld_next(s1, filename, sizeof(filename));
4038 if (t == LD_TOK_EOF) {
4039 return tcc_error_noabort("unexpected end of file");
4040 } else if (t == ')') {
4041 break;
4042 }
4043 }
4044 } else {
4045 return -1;
4046 }4022 }
4023 if (ret)
4024 break;
4047 }4025 }
4048 return 0;4026 tcc_free(text_ptr);
4027 s1->ld_p = saved_ptr;
4028 return ret;
4049}4029}
4050#endif /* !ELF_OBJ_ONLY */4030#endif /* !ELF_OBJ_ONLY */
tccgen.c+6−1
@@ -2401,10 +2401,15 @@ static void gen_opic(int op) · 2400 unmodified lines
2401 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {2401 (l2 == -1 || (l2 == 0xFFFFFFFF && t2 != VT_LLONG))))) {
2402 /* filter out NOP operations like x*1, x-0, x&-1... */2402 /* filter out NOP operations like x*1, x-0, x&-1... */
2403 vtop--;2403 vtop--;
2404 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV)) {2404 } else if (c2 && (op == '*' || op == TOK_PDIV || op == TOK_UDIV || op == TOK_UMOD)) {
2405 /* try to use shifts instead of muls or divs */2405 /* try to use shifts instead of muls or divs */
2406 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {2406 if (l2 > 0 && (l2 & (l2 - 1)) == 0) {
2407 int n = -1;2407 int n = -1;
2408 if (op == TOK_UMOD) {
2409 vtop->c.i = l2 - 1;
2410 op = '&';
2411 goto general_case;
2412 }
2408 while (l2) {2413 while (l2) {
2409 l2 >>= 1;2414 l2 >>= 1;
2410 n++;2415 n++;
tccmacho.c+4−8
@@ -2195,9 +2195,6 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 2194 unmodified lines
2195 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));2195 tcc_error_noabort("could not write '%s: %s'", filename, strerror(errno));
2196 return -1;2196 return -1;
2197 }2197 }
2198 if (s1->verbose)
2199 printf("<- %s\n", filename);
2200
2201 tcc_add_runtime(s1);2198 tcc_add_runtime(s1);
2202 tcc_macho_add_destructor(s1);2199 tcc_macho_add_destructor(s1);
2203 resolve_common_syms(s1);2200 resolve_common_syms(s1);
@@ -2222,6 +2219,8 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 18 unmodified lines
2222 bind_rebase_import(s1, &mo);2219 bind_rebase_import(s1, &mo);
2223#endif2220#endif
2224 convert_symbols(s1, &mo);2221 convert_symbols(s1, &mo);
2222 if (s1->verbose)
2223 printf("<- %s\n", filename);
2225 macho_write(s1, &mo, fp);2224 macho_write(s1, &mo, fp);
2226 }2225 }
2227 2226
@@ -2291,12 +2290,9 @@ ST_FUNC void tcc_add_macos_sdkpath(TCCState* s) · 63 unmodified lines
2291 cstr_free(&path);2290 cstr_free(&path);
2292}2291}
2293 2292
2294ST_FUNC const char* macho_tbd_soname(const char* filename) {2293ST_FUNC char* macho_tbd_soname(int fd) {
2295 char *soname, *data, *pos;2294 char *soname, *data, *pos;
2296 const char *ret = filename;2295 char *ret = 0;
2297
2298 int fd = open(filename,O_RDONLY);
2299 if (fd<0) return ret;
2300 pos = data = tcc_load_text(fd);2296 pos = data = tcc_load_text(fd);
2301 if (!tbd_parse_movepast("install-name: ")) goto the_end;2297 if (!tbd_parse_movepast("install-name: ")) goto the_end;
2302 tbd_parse_skipws;2298 tbd_parse_skipws;
tccpp.c+2−2
@@ -1354,7 +1354,7 @@ static int parse_include(TCCState *s1, int do_next, int test) · 1353 unmodified lines
1354 cstr_reset(&tokcstr);1354 cstr_reset(&tokcstr);
1355 file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &tokcstr);1355 file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &tokcstr);
1356 i = tokcstr.size;1356 i = tokcstr.size;
1357 pstrncpy(name, tokcstr.data, i >= sizeof name ? sizeof name - 1 : i);1357 pstrncpy(name, sizeof name, tokcstr.data, i);
1358 next_nomacro();1358 next_nomacro();
1359 } else {1359 } else {
1360 /* computed #include : concatenate tokens until result is one of1360 /* computed #include : concatenate tokens until result is one of
@@ -1395,7 +1395,7 @@ static int parse_include(TCCState *s1, int do_next, int test) · 34 unmodified lines
1395 if (c != '\"')1395 if (c != '\"')
1396 continue;1396 continue;
1397 p = file->true_filename;1397 p = file->true_filename;
1398 pstrncpy(buf, p, tcc_basename(p) - p);1398 pstrncpy(buf, sizeof buf, p, tcc_basename(p) - p);
1399 } else {1399 } else {
1400 int j = i - 2, k = j - s1->nb_include_paths;1400 int j = i - 2, k = j - s1->nb_include_paths;
1401 if (k < 0)1401 if (k < 0)
tccrun.c+2−2
@@ -221,7 +221,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 220 unmodified lines
221 221
222 tcc_add_symbol(s1, "__rt_exit", rt_exit);222 tcc_add_symbol(s1, "__rt_exit", rt_exit);
223 if (s1->nostdlib) {223 if (s1->nostdlib) {
224 s1->run_main = top_sym = "_start";224 s1->run_main = top_sym = s1->elf_entryname ? s1->elf_entryname : "_start";
225 } else {225 } else {
226 tcc_add_support(s1, "runmain.o");226 tcc_add_support(s1, "runmain.o");
227 s1->run_main = "_runmain";227 s1->run_main = "_runmain";
@@ -421,7 +421,7 @@ redo: · 193 unmodified lines
421 }421 }
422 422
423 /* relocate symbols */423 /* relocate symbols */
424 relocate_syms(s1, s1->symtab, !(s1->nostdlib));424 relocate_syms(s1, s1->symtab, 1);
425 /* relocate sections */425 /* relocate sections */
426#ifdef TCC_TARGET_PE426#ifdef TCC_TARGET_PE
427 s1->pe_imagebase = mem;427 s1->pe_imagebase = mem;

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