with -Wl,-oformat=binary, executable code should come first. (for linux kernel image for example)
Unified · Split
| @@ -7,6 +7,8 @@ include $(TOP)/Makefile · 6 unmodified lines | ||
| 7 | 7 | VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib |
| 8 | 8 | T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) |
| 9 | 9 | X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) |
| 10 | +XCFG = $(or $(findstring -win,$T),-unx) | |
| 11 | +S = $(if $(findstring yes,$(SILENT)),@$(info * $@)) | |
| 10 | 12 | |
| 11 | 13 | TCC = $(TOP)/$(X)tcc$(EXESUF) |
| 12 | 14 | XTCC ?= $(TOP)/$(X)tcc$(EXESUF) |
| @@ -16,8 +18,6 @@ XFLAGS-unx = -B$(TOPSRC) · 3 unmodified lines | ||
| 16 | 18 | XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include |
| 17 | 19 | XFLAGS = $(XFLAGS$(XCFG)) -I$(TOP) |
| 18 | 20 | BFLAGS = -bt |
| 19 | −XCFG = $(or $(findstring -win,$T),-unx) | |
| 20 | −S = $(if $(findstring yes,$(SILENT)),@$(info * $@)) | |
| 21 | 21 | |
| 22 | 22 | # in order to use gcc, type: make <target>-libtcc1-usegcc=yes |
| 23 | 23 | arm-libtcc1-usegcc ?= no |
| @@ -29,47 +29,48 @@ arm-libtcc1-usegcc ?= no · 5 unmodified lines | ||
| 29 | 29 | ifeq "$($(T)-libtcc1-usegcc)" "yes" |
| 30 | 30 | XCC = $(CC) |
| 31 | 31 | XAR = $(AR) |
| 32 | − XFLAGS = $(CFLAGS) -fPIC -gdwarf -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable | |
| 33 | − BFLAGS = -g | |
| 32 | + XFLAGS = $(CFLAGS) -fPIC -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable | |
| 33 | + BFLAGS = $(if $(CONFIG_dwarf),-gdwarf,-gstabs) | |
| 34 | 34 | endif |
| 35 | 35 | |
| 36 | −ifneq ($(CONFIG_backtrace),no) | |
| 37 | −# only for native compiler | |
| 38 | −ifneq ($(CONFIG_bcheck),no) | |
| 39 | −$(X)BCHECK_O = bcheck.o | |
| 40 | −endif | |
| 41 | −$(X)BT_O = bt-exe.o bt-log.o | |
| 42 | −$(X)B_O = $(BCHECK_O) bt-exe.o bt-log.o bt-dll.o | |
| 43 | −endif | |
| 44 | −$(X)BT_O += runmain.o tcov.o | |
| 36 | +I386_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) | |
| 37 | +X86_64_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) | |
| 38 | +ARM_O = libtcc1.o armeabi.o alloca.o armflush.o $(COMMON_O) | |
| 39 | +ARM64_O = lib-arm64.o $(COMMON_O) | |
| 40 | +RISCV64_O = lib-arm64.o $(COMMON_O) | |
| 41 | +COMMON_O = stdatomic.o atomic.o builtin.o | |
| 42 | +WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o | |
| 43 | +LIN_O = dsohandle.o | |
| 44 | +OSX_O = | |
| 45 | + | |
| 46 | +# backtrace/bcheck/run only for native compiler | |
| 47 | +Nat = $(if $X,no,) | |
| 48 | +Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace)) | |
| 49 | +Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck)) | |
| 45 | 50 | |
| 46 | −DSO_O = dsohandle.o | |
| 51 | +$(Nat)COMMON_O += runmain.o tcov.o | |
| 52 | +$(Cbt)COMMON_O += bt-exe.o bt-log.o | |
| 53 | +$(Cbt)WIN_O += bt-dll.o | |
| 54 | +$(Cbc)COMMON_O += bcheck.o | |
| 47 | 55 | |
| 48 | 56 | # not in libtcc1.a |
| 49 | 57 | EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o |
| 50 | 58 | |
| 51 | −I386_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O) | |
| 52 | −X86_64_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O) | |
| 53 | −ARM_O = libtcc1.o armeabi.o alloca.o armflush.o stdatomic.o atomic.o builtin.o $(BT_O) | |
| 54 | −ARM64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O) | |
| 55 | −RISCV64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O) | |
| 56 | −WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o | |
| 57 | − | |
| 58 | −OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O) | |
| 59 | −OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O) | |
| 60 | −OBJ-x86_64-osx = $(X86_64_O) va_list.o $(BCHECK_O) | |
| 61 | −OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O) | |
| 62 | −OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O) | |
| 63 | −OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O) | |
| 64 | −OBJ-arm64-osx = $(ARM64_O) $(BCHECK_O) | |
| 65 | −OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O) | |
| 66 | −OBJ-arm-fpa = $(ARM_O) $(DSO_O) | |
| 67 | −OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O) | |
| 68 | −OBJ-arm-vfp = $(ARM_O) $(DSO_O) | |
| 69 | −OBJ-arm-eabi = $(ARM_O) $(DSO_O) | |
| 70 | −OBJ-arm-eabihf = $(ARM_O) $(DSO_O) | |
| 59 | +OBJ-i386 = $(I386_O) $(LIN_O) | |
| 60 | +OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O) | |
| 61 | +OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O) | |
| 62 | +OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O) | |
| 63 | +OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O) | |
| 64 | +OBJ-arm64 = $(ARM64_O) $(LIN_O) | |
| 65 | +OBJ-arm64-osx = $(ARM64_O) $(OSX_O) | |
| 66 | +OBJ-arm = $(ARM_O) $(LIN_O) | |
| 67 | +OBJ-arm-fpa = $(OBJ-arm) | |
| 68 | +OBJ-arm-fpa-ld = $(OBJ-arm) | |
| 69 | +OBJ-arm-vfp = $(OBJ-arm) | |
| 70 | +OBJ-arm-eabi = $(OBJ-arm) | |
| 71 | +OBJ-arm-eabihf = $(OBJ-arm) | |
| 71 | 72 | OBJ-arm-wince = $(ARM_O) $(WIN_O) |
| 72 | −OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O) $(DSO_O) | |
| 73 | +OBJ-riscv64 = $(RISCV64_O) $(LIN_O) | |
| 73 | 74 | |
| 74 | 75 | OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T)) |
| 75 | 76 | OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) |
| @@ -1004,6 +1004,8 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) · 1003 unmodified lines | ||
| 1004 | 1004 | } |
| 1005 | 1005 | #endif |
| 1006 | 1006 | |
| 1007 | +static int guess_filetype(const char *filename); | |
| 1008 | + | |
| 1007 | 1009 | ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) |
| 1008 | 1010 | { |
| 1009 | 1011 | int fd, ret = -1; |
| @@ -1014,6 +1016,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) · 4 unmodified lines | ||
| 1014 | 1016 | filename = buf; |
| 1015 | 1017 | #endif |
| 1016 | 1018 | |
| 1019 | + if (0 == (flags & AFF_TYPE_MASK)) | |
| 1020 | + flags |= guess_filetype(filename); | |
| 1021 | + | |
| 1017 | 1022 | /* ignore binary files with -E */ |
| 1018 | 1023 | if (s1->output_type == TCC_OUTPUT_PREPROCESS |
| 1019 | 1024 | && (flags & AFF_TYPE_BIN)) |
| @@ -1123,10 +1128,10 @@ check_success: · 103 unmodified lines | ||
| 1123 | 1128 | return ret; |
| 1124 | 1129 | } |
| 1125 | 1130 | |
| 1126 | −LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) | |
| 1131 | +static int guess_filetype(const char *filename) | |
| 1127 | 1132 | { |
| 1128 | − int filetype = s->filetype; | |
| 1129 | − if (0 == (filetype & AFF_TYPE_MASK)) { | |
| 1133 | + int filetype = 0; | |
| 1134 | + if (1) { | |
| 1130 | 1135 | /* use a file extension to detect a filetype */ |
| 1131 | 1136 | const char *ext = tcc_fileextension(filename); |
| 1132 | 1137 | if (ext[0]) { |
| @@ -1145,7 +1150,12 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) · 12 unmodified lines | ||
| 1145 | 1150 | filetype = AFF_TYPE_C; |
| 1146 | 1151 | } |
| 1147 | 1152 | } |
| 1148 | − return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR); | |
| 1153 | + return filetype; | |
| 1154 | +} | |
| 1155 | + | |
| 1156 | +LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) | |
| 1157 | +{ | |
| 1158 | + return tcc_add_file_internal(s, filename, s->filetype | AFF_PRINT_ERROR); | |
| 1149 | 1159 | } |
| 1150 | 1160 | |
| 1151 | 1161 | LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname) |
| @@ -1162,12 +1172,12 @@ static int tcc_add_library_internal(TCCState *s1, const char *fmt, · 10 unmodified lines | ||
| 1162 | 1172 | |
| 1163 | 1173 | for(i = 0; i < nb_paths; i++) { |
| 1164 | 1174 | snprintf(buf, sizeof(buf), fmt, paths[i], filename); |
| 1165 | − ret = tcc_add_file_internal(s1, buf, (flags & ~AFF_PRINT_ERROR) | AFF_TYPE_BIN); | |
| 1175 | + ret = tcc_add_file_internal(s1, buf, flags & ~AFF_PRINT_ERROR); | |
| 1166 | 1176 | if (ret != FILE_NOT_FOUND) |
| 1167 | 1177 | return ret; |
| 1168 | 1178 | } |
| 1169 | 1179 | if (flags & AFF_PRINT_ERROR) |
| 1170 | − tcc_error_noabort("file '%s' not found", filename); | |
| 1180 | + tcc_error_noabort("library '%s' not found", filename); | |
| 1171 | 1181 | return FILE_NOT_FOUND; |
| 1172 | 1182 | } |
| 1173 | 1183 | |
| @@ -1219,15 +1229,7 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) · 45 unmodified lines | ||
| 1219 | 1229 | return ret; |
| 1220 | 1230 | ++pp; |
| 1221 | 1231 | } |
| 1222 | − return FILE_NOT_FOUND; | |
| 1223 | −} | |
| 1224 | − | |
| 1225 | −PUB_FUNC int tcc_add_library_err(TCCState *s1, const char *libname) | |
| 1226 | −{ | |
| 1227 | − int ret = tcc_add_library(s1, libname); | |
| 1228 | − if (ret == FILE_NOT_FOUND) | |
| 1229 | − tcc_error_noabort("library '%s' not found", libname); | |
| 1230 | − return ret; | |
| 1232 | + return tcc_add_dll(s, libraryname, AFF_PRINT_ERROR); | |
| 1231 | 1233 | } |
| 1232 | 1234 | |
| 1233 | 1235 | /* handle #pragma comment(lib,) */ |
| @@ -1235,7 +1237,7 @@ ST_FUNC void tcc_add_pragma_libs(TCCState *s1) · 1 unmodified line | ||
| 1235 | 1237 | { |
| 1236 | 1238 | int i; |
| 1237 | 1239 | for (i = 0; i < s1->nb_pragma_libs; i++) |
| 1238 | − tcc_add_library_err(s1, s1->pragma_libs[i]); | |
| 1240 | + tcc_add_library(s1, s1->pragma_libs[i]); | |
| 1239 | 1241 | } |
| 1240 | 1242 | |
| 1241 | 1243 | LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val) |
| @@ -366,7 +366,7 @@ redo: · 365 unmodified lines | ||
| 366 | 366 | struct filespec *f = s->files[n]; |
| 367 | 367 | s->filetype = f->type; |
| 368 | 368 | if (f->type & AFF_TYPE_LIB) { |
| 369 | − ret = tcc_add_library_err(s, f->name); | |
| 369 | + ret = tcc_add_library(s, f->name); | |
| 370 | 370 | } else { |
| 371 | 371 | if (1 == s->verbose) |
| 372 | 372 | printf("-> %s\n", f->name); |
| @@ -392,9 +392,9 @@ redo: · 19 unmodified lines | ||
| 392 | 392 | } else { |
| 393 | 393 | if (!s->outfile) |
| 394 | 394 | s->outfile = default_outputfile(s, first_file); |
| 395 | − if (!s->just_deps && tcc_output_file(s, s->outfile)) | |
| 396 | − ; | |
| 397 | − else if (s->gen_deps) | |
| 395 | + if (!s->just_deps) | |
| 396 | + ret = tcc_output_file(s, s->outfile); | |
| 397 | + if (!ret && s->gen_deps) | |
| 398 | 398 | gen_makedeps(s, s->outfile, s->deps_outfile); |
| 399 | 399 | } |
| 400 | 400 | } |
| @@ -402,7 +402,7 @@ redo: · 1 unmodified line | ||
| 402 | 402 | done = 1; |
| 403 | 403 | if (t) |
| 404 | 404 | done = 0; /* run more tests with -dt -run */ |
| 405 | − else if (s->nb_errors) | |
| 405 | + else if (ret) | |
| 406 | 406 | ret = 1; |
| 407 | 407 | else if (n < s->nb_files) |
| 408 | 408 | done = 0; /* compile more files with -c */ |
| @@ -974,8 +974,6 @@ struct TCCState { · 973 unmodified lines | ||
| 974 | 974 | int uw_sym; |
| 975 | 975 | unsigned uw_offs; |
| 976 | 976 | # endif |
| 977 | −#else | |
| 978 | − unsigned shf_RELRO; /* section flags for RELRO sections */ | |
| 979 | 977 | #endif |
| 980 | 978 | |
| 981 | 979 | #if defined TCC_TARGET_MACHO |
| @@ -1874,10 +1872,6 @@ ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename); · 892 unmodified lines | ||
| 1874 | 1872 | |
| 1875 | 1873 | /* ------------ tccdbg.c ------------ */ |
| 1876 | 1874 | |
| 1877 | −ST_FUNC void tcc_eh_frame_start(TCCState *s1); | |
| 1878 | −ST_FUNC void tcc_eh_frame_end(TCCState *s1); | |
| 1879 | −ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final); | |
| 1880 | − | |
| 1881 | 1875 | ST_FUNC void tcc_debug_new(TCCState *s); |
| 1882 | 1876 | |
| 1883 | 1877 | ST_FUNC void tcc_debug_start(TCCState *s1); |
| @@ -1896,6 +1890,13 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym); · 12 unmodified lines | ||
| 1896 | 1890 | ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value); |
| 1897 | 1891 | ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t); |
| 1898 | 1892 | |
| 1893 | +#if !(defined ELF_OBJ_ONLY || defined TCC_TARGET_ARM || defined TARGETOS_BSD) | |
| 1894 | +ST_FUNC void tcc_eh_frame_start(TCCState *s1); | |
| 1895 | +ST_FUNC void tcc_eh_frame_end(TCCState *s1); | |
| 1896 | +ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final); | |
| 1897 | +#define TCC_EH_FRAME 1 | |
| 1898 | +#endif | |
| 1899 | + | |
| 1899 | 1900 | ST_FUNC void tcc_tcov_start(TCCState *s1); |
| 1900 | 1901 | ST_FUNC void tcc_tcov_end(TCCState *s1); |
| 1901 | 1902 | ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start); |
| @@ -424,7 +424,7 @@ ST_FUNC void tcc_debug_new(TCCState *s1) · 423 unmodified lines | ||
| 424 | 424 | if (s1->do_debug && s1->output_type == TCC_OUTPUT_MEMORY) |
| 425 | 425 | s1->do_backtrace = 1; |
| 426 | 426 | if (s1->do_backtrace) |
| 427 | − shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX | |
| 427 | + shf = SHF_ALLOC; /* have debug data available at runtime */ | |
| 428 | 428 | #endif |
| 429 | 429 | |
| 430 | 430 | if (s1->dwarf) { |
| @@ -511,7 +511,7 @@ static void put_stabn(TCCState *s1, int type, int other, int desc, int value) · 80 unmodified lines | ||
| 511 | 511 | |
| 512 | 512 | /* ------------------------------------------------------------------------- */ |
| 513 | 513 | #define dwarf_data1(s,data) \ |
| 514 | − { unsigned char *p = section_ptr_add((s), 1); *p = (data); } | |
| 514 | + (*(uint8_t*)section_ptr_add((s), 1) = (data)) | |
| 515 | 515 | #define dwarf_data2(s,data) \ |
| 516 | 516 | write16le(section_ptr_add((s), 2), (data)) |
| 517 | 517 | #define dwarf_data4(s,data) \ |
| @@ -712,10 +712,9 @@ static void dwarf_sleb128_op (TCCState *s1, long long value) · 194 unmodified lines | ||
| 712 | 712 | } while (more); |
| 713 | 713 | } |
| 714 | 714 | |
| 715 | +#if TCC_EH_FRAME | |
| 715 | 716 | ST_FUNC void tcc_eh_frame_start(TCCState *s1) |
| 716 | 717 | { |
| 717 | −#if !(defined _WIN32 || defined __APPLE__ || defined TCC_TARGET_ARM || \ | |
| 718 | − defined TARGETOS_BSD) | |
| 719 | 718 | if (!s1->unwind_tables) |
| 720 | 719 | return; |
| 721 | 720 | eh_frame_section = new_section(s1, ".eh_frame", SHT_PROGBITS, SHF_ALLOC); |
| @@ -784,7 +783,6 @@ ST_FUNC void tcc_eh_frame_start(TCCState *s1) · 62 unmodified lines | ||
| 784 | 783 | dwarf_data1(eh_frame_section, DW_CFA_nop); |
| 785 | 784 | write32le(eh_frame_section->data + s1->eh_start, // length |
| 786 | 785 | eh_frame_section->data_offset - s1->eh_start - 4); |
| 787 | −#endif | |
| 788 | 786 | } |
| 789 | 787 | |
| 790 | 788 | static void tcc_debug_frame_end(TCCState *s1, int size) |
| @@ -1006,6 +1004,7 @@ next: · 215 unmodified lines | ||
| 1006 | 1004 | qsort(eh_frame_hdr_section->data + tab_offset, count, |
| 1007 | 1005 | sizeof(struct eh_search_table), sort_eh_table); |
| 1008 | 1006 | } |
| 1007 | +#endif | |
| 1009 | 1008 | |
| 1010 | 1009 | /* start of translation unit info */ |
| 1011 | 1010 | ST_FUNC void tcc_debug_start(TCCState *s1) |
| @@ -2172,7 +2171,9 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) · 1160 unmodified lines | ||
| 2172 | 2171 | /* lldb does not like function end and next function start at same pc */ |
| 2173 | 2172 | int min_instr_len; |
| 2174 | 2173 | |
| 2174 | +#if TCC_EH_FRAME | |
| 2175 | 2175 | tcc_debug_frame_end(s1, size); |
| 2176 | +#endif | |
| 2176 | 2177 | if (!s1->do_debug) |
| 2177 | 2178 | return; |
| 2178 | 2179 | min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN; |
| @@ -51,7 +51,7 @@ struct sym_version { · 50 unmodified lines | ||
| 51 | 51 | #define shf_RELRO SHF_ALLOC |
| 52 | 52 | static const char rdata[] = ".rdata"; |
| 53 | 53 | #else |
| 54 | −#define shf_RELRO s1->shf_RELRO | |
| 54 | +#define shf_RELRO SHF_ALLOC /* eventually made SHF_WRITE in sort_sections() */ | |
| 55 | 55 | static const char rdata[] = ".data.ro"; |
| 56 | 56 | #endif |
| 57 | 57 | |
| @@ -61,12 +61,6 @@ ST_FUNC void tccelf_new(TCCState *s) · 3 unmodified lines | ||
| 61 | 61 | { |
| 62 | 62 | TCCState *s1 = s; |
| 63 | 63 | |
| 64 | −#ifndef TCC_TARGET_PE | |
| 65 | − shf_RELRO = SHF_ALLOC; | |
| 66 | − if (s1->output_type != TCC_OUTPUT_MEMORY) | |
| 67 | − shf_RELRO |= SHF_WRITE; /* the ELF loader will set it to RO at runtime */ | |
| 68 | −#endif | |
| 69 | − | |
| 70 | 64 | /* no section zero */ |
| 71 | 65 | dynarray_add(&s->sections, &s->nb_sections, NULL); |
| 72 | 66 | |
| @@ -95,7 +89,9 @@ ST_FUNC void tccelf_new(TCCState *s) · 22 unmodified lines | ||
| 95 | 89 | tcc_debug_new(s); |
| 96 | 90 | } |
| 97 | 91 | |
| 92 | +#if TCC_EH_FRAME | |
| 98 | 93 | tcc_eh_frame_start(s); |
| 94 | +#endif | |
| 99 | 95 | |
| 100 | 96 | #ifdef CONFIG_TCC_BCHECK |
| 101 | 97 | if (s->do_bounds_check) { |
| @@ -1126,8 +1122,8 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr) · 1024 unmodified lines | ||
| 1126 | 1122 | r = 0; /* cannot apply 64bit relocation to 32bit value */ |
| 1127 | 1123 | sr->data_offset = sr->sh_size = r; |
| 1128 | 1124 | #ifdef CONFIG_TCC_PIE |
| 1129 | − if (r && 0 == (s->sh_flags & SHF_WRITE)) | |
| 1130 | − tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name); | |
| 1125 | + if (r && (s->sh_flags & SHF_EXECINSTR)) | |
| 1126 | + tcc_warning("%d relocations to %s", (unsigned)(r / sizeof *qrel), s->name); | |
| 1131 | 1127 | #endif |
| 1132 | 1128 | } |
| 1133 | 1129 | } |
| @@ -1758,7 +1754,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 624 unmodified lines | ||
| 1758 | 1754 | if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) { |
| 1759 | 1755 | tcc_add_support(s1, "bcheck.o"); |
| 1760 | 1756 | # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD) |
| 1761 | − tcc_add_library_err(s1, "dl"); | |
| 1757 | + tcc_add_library(s1, "dl"); | |
| 1762 | 1758 | # endif |
| 1763 | 1759 | lpthread = 1; |
| 1764 | 1760 | } |
| @@ -1774,8 +1770,8 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 9 unmodified lines | ||
| 1774 | 1770 | } |
| 1775 | 1771 | #endif |
| 1776 | 1772 | if (lpthread) |
| 1777 | − tcc_add_library_err(s1, "pthread"); | |
| 1778 | − tcc_add_library_err(s1, "c"); | |
| 1773 | + tcc_add_library(s1, "pthread"); | |
| 1774 | + tcc_add_library(s1, "c"); | |
| 1779 | 1775 | #ifdef TCC_LIBGCC |
| 1780 | 1776 | if (!s1->static_link) { |
| 1781 | 1777 | if (TCC_LIBGCC[0] == '/') |
| @@ -1785,7 +1781,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 3 unmodified lines | ||
| 1785 | 1781 | } |
| 1786 | 1782 | #endif |
| 1787 | 1783 | #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD |
| 1788 | − tcc_add_library_err(s1, "gcc_s"); // unwind code | |
| 1784 | + tcc_add_library(s1, "gcc_s"); // unwind code | |
| 1789 | 1785 | #endif |
| 1790 | 1786 | if (TCC_LIBTCC1[0]) |
| 1791 | 1787 | tcc_add_support(s1, TCC_LIBTCC1); |
| @@ -2091,7 +2087,7 @@ static int set_sec_sizes(TCCState *s1) · 299 unmodified lines | ||
| 2091 | 2087 | /* allocate the section */ |
| 2092 | 2088 | s->sh_flags |= SHF_ALLOC; |
| 2093 | 2089 | s->sh_size = count * sizeof(ElfW_Rel); |
| 2094 | − if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE)) | |
| 2090 | + if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR) | |
| 2095 | 2091 | textrel += count; |
| 2096 | 2092 | } |
| 2097 | 2093 | } |
| @@ -2161,47 +2157,58 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 63 unmodified lines | ||
| 2161 | 2157 | } else { |
| 2162 | 2158 | j = 0x700; |
| 2163 | 2159 | } |
| 2160 | + if (s1->output_format != TCC_OUTPUT_FORMAT_ELF) { | |
| 2161 | + if (j >= 0x700 || 0 == strncmp(s->name, ".eh_frame", 9)) | |
| 2162 | + s->sh_size = 0, j = 0x900; | |
| 2163 | + } | |
| 2164 | + | |
| 2164 | 2165 | if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) { |
| 2165 | 2166 | k = 0x10; |
| 2166 | 2167 | } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) { |
| 2167 | 2168 | k = 0x11; |
| 2168 | − if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */ | |
| 2169 | + if (i == nb_sections - 1) /* ".shstrtab" assumed to stay last */ | |
| 2169 | 2170 | k = 0xff; |
| 2170 | 2171 | } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) { |
| 2171 | 2172 | k = 0x12; |
| 2173 | + } else if (s->sh_type == SHT_GNU_verdef | |
| 2174 | + || s->sh_type == SHT_GNU_verneed | |
| 2175 | + || s->sh_type == SHT_GNU_versym) { | |
| 2176 | + k = 0x13; | |
| 2172 | 2177 | } else if (s->sh_type == SHT_RELX) { |
| 2173 | 2178 | k = 0x20; |
| 2174 | 2179 | if (s1->plt && s == s1->plt->reloc) |
| 2175 | 2180 | k = 0x21; |
| 2181 | + } else if (s->sh_flags & SHF_EXECINSTR) { | |
| 2182 | + k = 0x30; | |
| 2183 | + /* RELRO sections --> */ | |
| 2176 | 2184 | } else if (s->sh_type == SHT_PREINIT_ARRAY) { |
| 2177 | 2185 | k = 0x41; |
| 2178 | 2186 | } else if (s->sh_type == SHT_INIT_ARRAY) { |
| 2179 | 2187 | k = 0x42; |
| 2180 | 2188 | } else if (s->sh_type == SHT_FINI_ARRAY) { |
| 2181 | 2189 | k = 0x43; |
| 2182 | −#ifdef CONFIG_TCC_BCHECK | |
| 2183 | − } else if (s == bounds_section || s == lbounds_section) { | |
| 2184 | − k = 0x44; | |
| 2185 | −#endif | |
| 2186 | − } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) { | |
| 2187 | − k = 0x45; | |
| 2188 | 2190 | } else if (s->sh_type == SHT_DYNAMIC) { |
| 2189 | 2191 | k = 0x46; |
| 2190 | 2192 | } else if (s == s1->got) { |
| 2191 | 2193 | k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */ |
| 2194 | + } else if (s->reloc && (s->reloc->sh_flags & SHF_ALLOC) && j == 0x100) { | |
| 2195 | + k = 0x44; | |
| 2196 | + /* <-- */ | |
| 2197 | + } else if (s->sh_type == SHT_NOTE) { | |
| 2198 | + k = 0x60; | |
| 2199 | + } else if (s->sh_type == SHT_NOBITS) { | |
| 2200 | + k = 0x70; /* bss */ | |
| 2201 | + } else if (s == d->interp) { | |
| 2202 | + k = 0x00; | |
| 2192 | 2203 | } else { |
| 2193 | − k = 0x50; | |
| 2194 | − if (s->sh_type == SHT_NOTE) | |
| 2195 | − k = 0x60; | |
| 2196 | − if (s->sh_flags & SHF_EXECINSTR) | |
| 2197 | − k = 0x70; | |
| 2198 | − if (s->sh_type == SHT_NOBITS) | |
| 2199 | − k = 0x80; | |
| 2200 | − if (s == d->interp) | |
| 2201 | − k = 0x00; | |
| 2204 | + k = 0x50; /* data */ | |
| 2202 | 2205 | } |
| 2203 | 2206 | k += j; |
| 2204 | 2207 | |
| 2208 | + if ((k & 0xfff0) == 0x140) { | |
| 2209 | + /* make RELRO section writable */ | |
| 2210 | + k += 0x100, s->sh_flags |= SHF_WRITE; | |
| 2211 | + } | |
| 2205 | 2212 | for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n) |
| 2206 | 2213 | sec_cls[n] = f, sec_order[n] = sec_order[n - 1]; |
| 2207 | 2214 | sec_cls[n] = k, sec_order[n] = i; |
| @@ -2233,7 +2240,7 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 25 unmodified lines | ||
| 2233 | 2240 | f0 = f, ++n, f |= 1<<8; |
| 2234 | 2241 | } |
| 2235 | 2242 | sec_cls[i] = f; |
| 2236 | − //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, s->sh_size, s->name); | |
| 2243 | + //printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, (int)s->sh_size, s->name); | |
| 2237 | 2244 | } |
| 2238 | 2245 | return n; |
| 2239 | 2246 | } |
| @@ -2395,12 +2402,8 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) · 155 unmodified lines | ||
| 2395 | 2402 | fill_phdr(++ph, PT_NOTE, d->note); |
| 2396 | 2403 | if (d->dynamic) |
| 2397 | 2404 | fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W; |
| 2398 | − if (eh_frame_hdr_section) { | |
| 2399 | − add32le(eh_frame_hdr_section->data + 4, | |
| 2400 | − eh_frame_section->sh_offset - | |
| 2401 | − eh_frame_hdr_section->sh_offset - 4); | |
| 2405 | + if (eh_frame_hdr_section) | |
| 2402 | 2406 | fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section); |
| 2403 | − } | |
| 2404 | 2407 | if (d->roinf) |
| 2405 | 2408 | fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W; |
| 2406 | 2409 | if (d->interp) |
| @@ -2869,10 +2872,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 462 unmodified lines | ||
| 2869 | 2872 | /* shared library case: simply export all global symbols */ |
| 2870 | 2873 | export_global_syms(s1); |
| 2871 | 2874 | } |
| 2872 | − | |
| 2875 | +#if TCC_EH_FRAME | |
| 2873 | 2876 | /* fill with initial data */ |
| 2874 | 2877 | tcc_eh_frame_hdr(s1, 0); |
| 2875 | − | |
| 2878 | +#endif | |
| 2876 | 2879 | dyninf.gnu_hash = create_gnu_hash(s1); |
| 2877 | 2880 | } else { |
| 2878 | 2881 | build_got_entries(s1, 0); |
| @@ -2956,10 +2959,10 @@ static int elf_output_file(TCCState *s1, const char *filename) · 77 unmodified lines | ||
| 2956 | 2959 | update_gnu_hash(s1, dyninf.gnu_hash); |
| 2957 | 2960 | |
| 2958 | 2961 | reorder_sections(s1, sec_order); |
| 2959 | − | |
| 2962 | +#if TCC_EH_FRAME | |
| 2960 | 2963 | /* fill with final data */ |
| 2961 | 2964 | tcc_eh_frame_hdr(s1, 1); |
| 2962 | − | |
| 2965 | +#endif | |
| 2963 | 2966 | /* Create the ELF file with name 'filename' */ |
| 2964 | 2967 | ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr); |
| 2965 | 2968 | the_end: |
| @@ -3146,6 +3149,11 @@ invalid: · 180 unmodified lines | ||
| 3146 | 3149 | if (sh->sh_type == SHT_RELX) |
| 3147 | 3150 | sh = &shdr[sh->sh_info]; |
| 3148 | 3151 | /* ignore sections types we do not handle (plus relocs to those) */ |
| 3152 | + if (0 == strncmp(strsec + sh->sh_name, ".debug_", 7) | |
| 3153 | + || 0 == strncmp(strsec + sh->sh_name, ".stab", 5)) { | |
| 3154 | + if (!s1->do_debug || seencompressed) | |
| 3155 | + continue; | |
| 3156 | + } else | |
| 3149 | 3157 | if (sh->sh_type != SHT_PROGBITS && |
| 3150 | 3158 | #ifdef TCC_ARM_EABI |
| 3151 | 3159 | sh->sh_type != SHT_ARM_EXIDX && |
| @@ -3157,12 +3165,9 @@ invalid: · 5 unmodified lines | ||
| 3157 | 3165 | sh->sh_type != SHT_NOBITS && |
| 3158 | 3166 | sh->sh_type != SHT_PREINIT_ARRAY && |
| 3159 | 3167 | sh->sh_type != SHT_INIT_ARRAY && |
| 3160 | − sh->sh_type != SHT_FINI_ARRAY && | |
| 3161 | − strcmp(strsec + sh->sh_name, ".stabstr") | |
| 3168 | + sh->sh_type != SHT_FINI_ARRAY | |
| 3162 | 3169 | ) |
| 3163 | 3170 | continue; |
| 3164 | − if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7)) | |
| 3165 | − continue; | |
| 3166 | 3171 | |
| 3167 | 3172 | sh = &shdr[i]; |
| 3168 | 3173 | sh_name = strsec + sh->sh_name; |
| @@ -3414,7 +3419,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) · 245 unmodified lines | ||
| 3414 | 3419 | |
| 3415 | 3420 | data = tcc_malloc(size); |
| 3416 | 3421 | if (full_read(fd, data, size) != size) |
| 3417 | − goto the_end; | |
| 3422 | + goto invalid; | |
| 3418 | 3423 | nsyms = get_be(data, entrysize); |
| 3419 | 3424 | ar_index = data + entrysize; |
| 3420 | 3425 | ar_names = (char *) ar_index + nsyms * entrysize; |
| @@ -3432,6 +3437,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) · 11 unmodified lines | ||
| 3432 | 3437 | off = get_be(ar_index + i * entrysize, entrysize); |
| 3433 | 3438 | len = read_ar_header(fd, off, &hdr); |
| 3434 | 3439 | if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) { |
| 3440 | + invalid: | |
| 3435 | 3441 | tcc_error_noabort("invalid archive"); |
| 3436 | 3442 | goto the_end; |
| 3437 | 3443 | } |
| @@ -401,7 +401,9 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 400 unmodified lines | ||
| 401 | 401 | gen_inline_functions(s1); |
| 402 | 402 | check_vstack(); |
| 403 | 403 | /* end of translation unit info */ |
| 404 | +#if TCC_EH_FRAME | |
| 404 | 405 | tcc_eh_frame_end(s1); |
| 406 | +#endif | |
| 405 | 407 | tcc_debug_end(s1); |
| 406 | 408 | tcc_tcov_end(s1); |
| 407 | 409 | return 0; |
| @@ -845,7 +845,7 @@ found_dll: · 844 unmodified lines | ||
| 845 | 845 | return s; |
| 846 | 846 | } |
| 847 | 847 | |
| 848 | −void pe_free_imports(struct pe_info *pe) | |
| 848 | +static void pe_free_imports(struct pe_info *pe) | |
| 849 | 849 | { |
| 850 | 850 | int i; |
| 851 | 851 | for (i = 0; i < pe->imp_count; ++i) { |
| @@ -1133,9 +1133,7 @@ static int pe_section_class(Section *s) · 281 unmodified lines | ||
| 1133 | 1133 | name = s->name; |
| 1134 | 1134 | |
| 1135 | 1135 | if (0 == memcmp(name, ".stab", 5) || 0 == memcmp(name, ".debug_", 7)) { |
| 1136 | − if (s->s1->do_debug) | |
| 1137 | − return sec_debug; | |
| 1138 | − | |
| 1136 | + return sec_debug; | |
| 1139 | 1137 | } else if (flags & SHF_ALLOC) { |
| 1140 | 1138 | if (type == SHT_PROGBITS |
| 1141 | 1139 | || type == SHT_INIT_ARRAY |
| @@ -1995,7 +1993,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) · 853 unmodified lines | ||
| 1995 | 1993 | tcc_add_support(s1, TCC_LIBTCC1); |
| 1996 | 1994 | for (pp = libs; 0 != (p = *pp); ++pp) { |
| 1997 | 1995 | if (*p) |
| 1998 | − tcc_add_library_err(s1, p); | |
| 1996 | + tcc_add_library(s1, p); | |
| 1999 | 1997 | else if (PE_DLL != pe_type && PE_GUI != pe_type) |
| 2000 | 1998 | break; |
| 2001 | 1999 | } |
| @@ -2068,8 +2066,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) · 66 unmodified lines | ||
| 2068 | 2066 | #ifdef CONFIG_TCC_BCHECK |
| 2069 | 2067 | tcc_add_bcheck(s1); |
| 2070 | 2068 | #endif |
| 2071 | − pe_add_runtime(s1, &pe); | |
| 2072 | 2069 | tcc_add_pragma_libs(s1); |
| 2070 | + pe_add_runtime(s1, &pe); | |
| 2073 | 2071 | resolve_common_syms(s1); |
| 2074 | 2072 | pe_set_options(s1, &pe); |
| 2075 | 2073 | pe_check_symbols(&pe); |
| @@ -1929,23 +1929,28 @@ ST_FUNC void preprocess(int is_bof) · 1928 unmodified lines | ||
| 1929 | 1929 | break; |
| 1930 | 1930 | case TOK_LINE: |
| 1931 | 1931 | next_nomacro(); |
| 1932 | − if (tok != TOK_PPNUM) | |
| 1932 | + if (tok != TOK_PPNUM) { | |
| 1933 | 1933 | _line_err: |
| 1934 | + if (parse_flags & PARSE_FLAG_ASM_FILE) | |
| 1935 | + goto ignore; | |
| 1934 | 1936 | tcc_error("wrong #line format"); |
| 1937 | + } | |
| 1935 | 1938 | case TOK_PPNUM: |
| 1936 | − parse_number(tokc.str.data); | |
| 1937 | − n = tokc.i; | |
| 1939 | + for (n = 0, q = tokc.str.data; *q; ++q) { | |
| 1940 | + if (!isnum(*q)) | |
| 1941 | + goto _line_err; | |
| 1942 | + n = n * 10 + *q - '0'; | |
| 1943 | + } | |
| 1938 | 1944 | next_nomacro(); |
| 1939 | 1945 | if (tok != TOK_LINEFEED) { |
| 1940 | 1946 | if (tok == TOK_PPSTR && tokc.str.data[0] == '"') { |
| 1941 | 1947 | tokc.str.data[tokc.str.size - 2] = 0; |
| 1942 | 1948 | tccpp_putfile(tokc.str.data + 1); |
| 1943 | − } else if (parse_flags & PARSE_FLAG_ASM_FILE) | |
| 1944 | − goto ignore; | |
| 1945 | − else | |
| 1949 | + } else | |
| 1946 | 1950 | goto _line_err; |
| 1947 | 1951 | next_nomacro(); |
| 1948 | − } | |
| 1952 | + } else if (parse_flags & PARSE_FLAG_ASM_FILE) | |
| 1953 | + goto ignore; | |
| 1949 | 1954 | if (file->fd > 0) |
| 1950 | 1955 | total_lines += file->line_num - n; |
| 1951 | 1956 | file->line_num = n; |