From dd2e5f8b06bc6ada943291fa4c67c8397038310f Mon Sep 17 00:00:00 2001 From: grischka Date: Sun, 17 Nov 2024 21:39:38 +0100 Subject: [PATCH] tccelf: cleanup sort_sections() & etc. fixes with -Wl,-oformat=binary, executable code should come first. (for linux kernel image for example) Also: - simplify RELRO sections: create them as readonly, but add SHF_WRITE flag later when needed (i.e. relocations do exist) - tcc.h etc: exclude eh_frames on non-elf platforms - tccelf.c:tcc_load_object_file(): don't load debug sections when linking without -g (special dwarf case in relocate_section() wont work when dwlo/hi were not initialized). - tcc.c: avoid loop if something fails (ret < 0) without message (while failing without message should not happen either) - tccelf.c:tcc_load_alacarte: give message - tccpp.c: treat '# 123xyz' in asm file as comment - lib/Makefile: cleanup - libtcc.c: tcc_add_library(): fallback to try filename as is (also remove tcc_add_library_err()) --- lib/Makefile | 71 +++++++++++++++++++------------------- libtcc.c | 34 ++++++++++--------- tcc.c | 10 +++--- tcc.h | 13 +++---- tccdbg.c | 11 +++--- tccelf.c | 96 ++++++++++++++++++++++++++++------------------------ tccgen.c | 2 ++ tccpe.c | 10 +++--- tccpp.c | 19 +++++++---- 9 files changed, 141 insertions(+), 125 deletions(-) diff --git a/lib/Makefile b/lib/Makefile index 03f4a6944..4727beeb9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -7,6 +7,8 @@ include $(TOP)/Makefile VPATH = $(TOPSRC)/lib $(TOPSRC)/win32/lib T = $(or $(CROSS_TARGET),$(NATIVE_TARGET),unknown) X = $(if $(CROSS_TARGET),$(CROSS_TARGET)-) +XCFG = $(or $(findstring -win,$T),-unx) +S = $(if $(findstring yes,$(SILENT)),@$(info * $@)) TCC = $(TOP)/$(X)tcc$(EXESUF) XTCC ?= $(TOP)/$(X)tcc$(EXESUF) @@ -16,8 +18,6 @@ XFLAGS-unx = -B$(TOPSRC) XFLAGS-win = -B$(TOPSRC)/win32 -I$(TOPSRC)/include XFLAGS = $(XFLAGS$(XCFG)) -I$(TOP) BFLAGS = -bt -XCFG = $(or $(findstring -win,$T),-unx) -S = $(if $(findstring yes,$(SILENT)),@$(info * $@)) # in order to use gcc, type: make -libtcc1-usegcc=yes arm-libtcc1-usegcc ?= no @@ -29,47 +29,48 @@ arm-libtcc1-usegcc ?= no ifeq "$($(T)-libtcc1-usegcc)" "yes" XCC = $(CC) XAR = $(AR) - XFLAGS = $(CFLAGS) -fPIC -gdwarf -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable - BFLAGS = -g + XFLAGS = $(CFLAGS) -fPIC -fno-omit-frame-pointer -Wno-unused-function -Wno-unused-variable + BFLAGS = $(if $(CONFIG_dwarf),-gdwarf,-gstabs) endif -ifneq ($(CONFIG_backtrace),no) -# only for native compiler -ifneq ($(CONFIG_bcheck),no) -$(X)BCHECK_O = bcheck.o -endif -$(X)BT_O = bt-exe.o bt-log.o -$(X)B_O = $(BCHECK_O) bt-exe.o bt-log.o bt-dll.o -endif -$(X)BT_O += runmain.o tcov.o +I386_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) +X86_64_O = libtcc1.o alloca.o alloca-bt.o $(COMMON_O) +ARM_O = libtcc1.o armeabi.o alloca.o armflush.o $(COMMON_O) +ARM64_O = lib-arm64.o $(COMMON_O) +RISCV64_O = lib-arm64.o $(COMMON_O) +COMMON_O = stdatomic.o atomic.o builtin.o +WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o +LIN_O = dsohandle.o +OSX_O = + +# backtrace/bcheck/run only for native compiler +Nat = $(if $X,no,) +Cbt = $(Nat)$(subst yes,,$(CONFIG_backtrace)) +Cbc = $(Cbt)$(subst yes,,$(CONFIG_bcheck)) -DSO_O = dsohandle.o +$(Nat)COMMON_O += runmain.o tcov.o +$(Cbt)COMMON_O += bt-exe.o bt-log.o +$(Cbt)WIN_O += bt-dll.o +$(Cbc)COMMON_O += bcheck.o # not in libtcc1.a EXTRA_O = runmain.o bt-exe.o bt-dll.o bt-log.o bcheck.o -I386_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O) -X86_64_O = libtcc1.o alloca.o alloca-bt.o stdatomic.o atomic.o builtin.o $(BT_O) -ARM_O = libtcc1.o armeabi.o alloca.o armflush.o stdatomic.o atomic.o builtin.o $(BT_O) -ARM64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O) -RISCV64_O = lib-arm64.o stdatomic.o atomic.o builtin.o $(BT_O) -WIN_O = crt1.o crt1w.o wincrt1.o wincrt1w.o dllcrt1.o dllmain.o - -OBJ-i386 = $(I386_O) $(BCHECK_O) $(DSO_O) -OBJ-x86_64 = $(X86_64_O) va_list.o $(BCHECK_O) $(DSO_O) -OBJ-x86_64-osx = $(X86_64_O) va_list.o $(BCHECK_O) -OBJ-i386-win32 = $(I386_O) chkstk.o $(B_O) $(WIN_O) -OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(B_O) $(WIN_O) -OBJ-arm64 = $(ARM64_O) $(BCHECK_O) $(DSO_O) -OBJ-arm64-osx = $(ARM64_O) $(BCHECK_O) -OBJ-arm = $(ARM_O) $(BCHECK_O) $(DSO_O) -OBJ-arm-fpa = $(ARM_O) $(DSO_O) -OBJ-arm-fpa-ld = $(ARM_O) $(DSO_O) -OBJ-arm-vfp = $(ARM_O) $(DSO_O) -OBJ-arm-eabi = $(ARM_O) $(DSO_O) -OBJ-arm-eabihf = $(ARM_O) $(DSO_O) +OBJ-i386 = $(I386_O) $(LIN_O) +OBJ-x86_64 = $(X86_64_O) va_list.o $(LIN_O) +OBJ-x86_64-osx = $(X86_64_O) va_list.o $(OSX_O) +OBJ-i386-win32 = $(I386_O) chkstk.o $(WIN_O) +OBJ-x86_64-win32 = $(X86_64_O) chkstk.o $(WIN_O) +OBJ-arm64 = $(ARM64_O) $(LIN_O) +OBJ-arm64-osx = $(ARM64_O) $(OSX_O) +OBJ-arm = $(ARM_O) $(LIN_O) +OBJ-arm-fpa = $(OBJ-arm) +OBJ-arm-fpa-ld = $(OBJ-arm) +OBJ-arm-vfp = $(OBJ-arm) +OBJ-arm-eabi = $(OBJ-arm) +OBJ-arm-eabihf = $(OBJ-arm) OBJ-arm-wince = $(ARM_O) $(WIN_O) -OBJ-riscv64 = $(RISCV64_O) $(BCHECK_O) $(DSO_O) +OBJ-riscv64 = $(RISCV64_O) $(LIN_O) OBJ-extra = $(filter $(EXTRA_O),$(OBJ-$T)) OBJ-libtcc1 = $(addprefix $(X),$(filter-out $(OBJ-extra),$(OBJ-$T))) diff --git a/libtcc.c b/libtcc.c index 1af9628f6..794d9879b 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1004,6 +1004,8 @@ static int tcc_glob_so(TCCState *s1, const char *pattern, char *buf, int size) } #endif +static int guess_filetype(const char *filename); + ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) { int fd, ret = -1; @@ -1014,6 +1016,9 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) filename = buf; #endif + if (0 == (flags & AFF_TYPE_MASK)) + flags |= guess_filetype(filename); + /* ignore binary files with -E */ if (s1->output_type == TCC_OUTPUT_PREPROCESS && (flags & AFF_TYPE_BIN)) @@ -1123,10 +1128,10 @@ ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags) return ret; } -LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) +static int guess_filetype(const char *filename) { - int filetype = s->filetype; - if (0 == (filetype & AFF_TYPE_MASK)) { + int filetype = 0; + if (1) { /* use a file extension to detect a filetype */ const char *ext = tcc_fileextension(filename); if (ext[0]) { @@ -1145,7 +1150,12 @@ LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) filetype = AFF_TYPE_C; } } - return tcc_add_file_internal(s, filename, filetype | AFF_PRINT_ERROR); + return filetype; +} + +LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename) +{ + return tcc_add_file_internal(s, filename, s->filetype | AFF_PRINT_ERROR); } 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, for(i = 0; i < nb_paths; i++) { snprintf(buf, sizeof(buf), fmt, paths[i], filename); - ret = tcc_add_file_internal(s1, buf, (flags & ~AFF_PRINT_ERROR) | AFF_TYPE_BIN); + ret = tcc_add_file_internal(s1, buf, flags & ~AFF_PRINT_ERROR); if (ret != FILE_NOT_FOUND) return ret; } if (flags & AFF_PRINT_ERROR) - tcc_error_noabort("file '%s' not found", filename); + tcc_error_noabort("library '%s' not found", filename); return FILE_NOT_FOUND; } @@ -1219,15 +1229,7 @@ LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname) return ret; ++pp; } - return FILE_NOT_FOUND; -} - -PUB_FUNC int tcc_add_library_err(TCCState *s1, const char *libname) -{ - int ret = tcc_add_library(s1, libname); - if (ret == FILE_NOT_FOUND) - tcc_error_noabort("library '%s' not found", libname); - return ret; + return tcc_add_dll(s, libraryname, AFF_PRINT_ERROR); } /* handle #pragma comment(lib,) */ @@ -1235,7 +1237,7 @@ ST_FUNC void tcc_add_pragma_libs(TCCState *s1) { int i; for (i = 0; i < s1->nb_pragma_libs; i++) - tcc_add_library_err(s1, s1->pragma_libs[i]); + tcc_add_library(s1, s1->pragma_libs[i]); } LIBTCCAPI int tcc_add_symbol(TCCState *s1, const char *name, const void *val) diff --git a/tcc.c b/tcc.c index 010f3b3ef..1ff54fe91 100644 --- a/tcc.c +++ b/tcc.c @@ -366,7 +366,7 @@ int main(int argc0, char **argv0) struct filespec *f = s->files[n]; s->filetype = f->type; if (f->type & AFF_TYPE_LIB) { - ret = tcc_add_library_err(s, f->name); + ret = tcc_add_library(s, f->name); } else { if (1 == s->verbose) printf("-> %s\n", f->name); @@ -392,9 +392,9 @@ int main(int argc0, char **argv0) } else { if (!s->outfile) s->outfile = default_outputfile(s, first_file); - if (!s->just_deps && tcc_output_file(s, s->outfile)) - ; - else if (s->gen_deps) + if (!s->just_deps) + ret = tcc_output_file(s, s->outfile); + if (!ret && s->gen_deps) gen_makedeps(s, s->outfile, s->deps_outfile); } } @@ -402,7 +402,7 @@ int main(int argc0, char **argv0) done = 1; if (t) done = 0; /* run more tests with -dt -run */ - else if (s->nb_errors) + else if (ret) ret = 1; else if (n < s->nb_files) done = 0; /* compile more files with -c */ diff --git a/tcc.h b/tcc.h index 7edf92381..d67381219 100644 --- a/tcc.h +++ b/tcc.h @@ -974,8 +974,6 @@ struct TCCState { int uw_sym; unsigned uw_offs; # endif -#else - unsigned shf_RELRO; /* section flags for RELRO sections */ #endif #if defined TCC_TARGET_MACHO @@ -1874,10 +1872,6 @@ ST_FUNC int gen_makedeps(TCCState *s, const char *target, const char *filename); /* ------------ tccdbg.c ------------ */ -ST_FUNC void tcc_eh_frame_start(TCCState *s1); -ST_FUNC void tcc_eh_frame_end(TCCState *s1); -ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final); - ST_FUNC void tcc_debug_new(TCCState *s); ST_FUNC void tcc_debug_start(TCCState *s1); @@ -1896,6 +1890,13 @@ ST_FUNC void tcc_debug_typedef(TCCState *s1, Sym *sym); ST_FUNC void tcc_debug_stabn(TCCState *s1, int type, int value); ST_FUNC void tcc_debug_fix_anon(TCCState *s1, CType *t); +#if !(defined ELF_OBJ_ONLY || defined TCC_TARGET_ARM || defined TARGETOS_BSD) +ST_FUNC void tcc_eh_frame_start(TCCState *s1); +ST_FUNC void tcc_eh_frame_end(TCCState *s1); +ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final); +#define TCC_EH_FRAME 1 +#endif + ST_FUNC void tcc_tcov_start(TCCState *s1); ST_FUNC void tcc_tcov_end(TCCState *s1); ST_FUNC void tcc_tcov_check_line(TCCState *s1, int start); diff --git a/tccdbg.c b/tccdbg.c index f9fb62eec..345f7aa9c 100644 --- a/tccdbg.c +++ b/tccdbg.c @@ -424,7 +424,7 @@ ST_FUNC void tcc_debug_new(TCCState *s1) if (s1->do_debug && s1->output_type == TCC_OUTPUT_MEMORY) s1->do_backtrace = 1; if (s1->do_backtrace) - shf = SHF_ALLOC | SHF_WRITE; // SHF_WRITE needed for musl/SELINUX + shf = SHF_ALLOC; /* have debug data available at runtime */ #endif if (s1->dwarf) { @@ -511,7 +511,7 @@ static void put_stabn(TCCState *s1, int type, int other, int desc, int value) /* ------------------------------------------------------------------------- */ #define dwarf_data1(s,data) \ - { unsigned char *p = section_ptr_add((s), 1); *p = (data); } + (*(uint8_t*)section_ptr_add((s), 1) = (data)) #define dwarf_data2(s,data) \ write16le(section_ptr_add((s), 2), (data)) #define dwarf_data4(s,data) \ @@ -712,10 +712,9 @@ static void dwarf_sleb128_op (TCCState *s1, long long value) } while (more); } +#if TCC_EH_FRAME ST_FUNC void tcc_eh_frame_start(TCCState *s1) { -#if !(defined _WIN32 || defined __APPLE__ || defined TCC_TARGET_ARM || \ - defined TARGETOS_BSD) if (!s1->unwind_tables) return; 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) dwarf_data1(eh_frame_section, DW_CFA_nop); write32le(eh_frame_section->data + s1->eh_start, // length eh_frame_section->data_offset - s1->eh_start - 4); -#endif } static void tcc_debug_frame_end(TCCState *s1, int size) @@ -1006,6 +1004,7 @@ ST_FUNC void tcc_eh_frame_hdr(TCCState *s1, int final) qsort(eh_frame_hdr_section->data + tab_offset, count, sizeof(struct eh_search_table), sort_eh_table); } +#endif /* start of translation unit info */ ST_FUNC void tcc_debug_start(TCCState *s1) @@ -2172,7 +2171,9 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) /* lldb does not like function end and next function start at same pc */ int min_instr_len; +#if TCC_EH_FRAME tcc_debug_frame_end(s1, size); +#endif if (!s1->do_debug) return; min_instr_len = dwarf_line.last_pc == ind ? 0 : DWARF_MIN_INSTR_LEN; diff --git a/tccelf.c b/tccelf.c index 50f365eb7..8b03a32bb 100644 --- a/tccelf.c +++ b/tccelf.c @@ -51,7 +51,7 @@ struct sym_version { #define shf_RELRO SHF_ALLOC static const char rdata[] = ".rdata"; #else -#define shf_RELRO s1->shf_RELRO +#define shf_RELRO SHF_ALLOC /* eventually made SHF_WRITE in sort_sections() */ static const char rdata[] = ".data.ro"; #endif @@ -61,12 +61,6 @@ ST_FUNC void tccelf_new(TCCState *s) { TCCState *s1 = s; -#ifndef TCC_TARGET_PE - shf_RELRO = SHF_ALLOC; - if (s1->output_type != TCC_OUTPUT_MEMORY) - shf_RELRO |= SHF_WRITE; /* the ELF loader will set it to RO at runtime */ -#endif - /* no section zero */ dynarray_add(&s->sections, &s->nb_sections, NULL); @@ -95,7 +89,9 @@ ST_FUNC void tccelf_new(TCCState *s) tcc_debug_new(s); } +#if TCC_EH_FRAME tcc_eh_frame_start(s); +#endif #ifdef CONFIG_TCC_BCHECK if (s->do_bounds_check) { @@ -1126,8 +1122,8 @@ static void relocate_section(TCCState *s1, Section *s, Section *sr) r = 0; /* cannot apply 64bit relocation to 32bit value */ sr->data_offset = sr->sh_size = r; #ifdef CONFIG_TCC_PIE - if (r && 0 == (s->sh_flags & SHF_WRITE)) - tcc_warning("%d relocations to ro-section %s", (unsigned)(r / sizeof *qrel), s->name); + if (r && (s->sh_flags & SHF_EXECINSTR)) + tcc_warning("%d relocations to %s", (unsigned)(r / sizeof *qrel), s->name); #endif } } @@ -1758,7 +1754,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) if (s1->do_bounds_check && s1->output_type != TCC_OUTPUT_DLL) { tcc_add_support(s1, "bcheck.o"); # if !(TARGETOS_OpenBSD || TARGETOS_NetBSD) - tcc_add_library_err(s1, "dl"); + tcc_add_library(s1, "dl"); # endif lpthread = 1; } @@ -1774,8 +1770,8 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) } #endif if (lpthread) - tcc_add_library_err(s1, "pthread"); - tcc_add_library_err(s1, "c"); + tcc_add_library(s1, "pthread"); + tcc_add_library(s1, "c"); #ifdef TCC_LIBGCC if (!s1->static_link) { if (TCC_LIBGCC[0] == '/') @@ -1785,7 +1781,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) } #endif #if defined TCC_TARGET_ARM && TARGETOS_FreeBSD - tcc_add_library_err(s1, "gcc_s"); // unwind code + tcc_add_library(s1, "gcc_s"); // unwind code #endif if (TCC_LIBTCC1[0]) tcc_add_support(s1, TCC_LIBTCC1); @@ -2091,7 +2087,7 @@ static int set_sec_sizes(TCCState *s1) /* allocate the section */ s->sh_flags |= SHF_ALLOC; s->sh_size = count * sizeof(ElfW_Rel); - if (!(s1->sections[s->sh_info]->sh_flags & SHF_WRITE)) + if (s1->sections[s->sh_info]->sh_flags & SHF_EXECINSTR) textrel += count; } } @@ -2161,47 +2157,58 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) } else { j = 0x700; } + if (s1->output_format != TCC_OUTPUT_FORMAT_ELF) { + if (j >= 0x700 || 0 == strncmp(s->name, ".eh_frame", 9)) + s->sh_size = 0, j = 0x900; + } + if (s->sh_type == SHT_SYMTAB || s->sh_type == SHT_DYNSYM) { k = 0x10; } else if (s->sh_type == SHT_STRTAB && strcmp(s->name, ".stabstr")) { k = 0x11; - if (i == nb_sections - 1) /* ".shstrtab" assumed to remain last */ + if (i == nb_sections - 1) /* ".shstrtab" assumed to stay last */ k = 0xff; } else if (s->sh_type == SHT_HASH || s->sh_type == SHT_GNU_HASH) { k = 0x12; + } else if (s->sh_type == SHT_GNU_verdef + || s->sh_type == SHT_GNU_verneed + || s->sh_type == SHT_GNU_versym) { + k = 0x13; } else if (s->sh_type == SHT_RELX) { k = 0x20; if (s1->plt && s == s1->plt->reloc) k = 0x21; + } else if (s->sh_flags & SHF_EXECINSTR) { + k = 0x30; + /* RELRO sections --> */ } else if (s->sh_type == SHT_PREINIT_ARRAY) { k = 0x41; } else if (s->sh_type == SHT_INIT_ARRAY) { k = 0x42; } else if (s->sh_type == SHT_FINI_ARRAY) { k = 0x43; -#ifdef CONFIG_TCC_BCHECK - } else if (s == bounds_section || s == lbounds_section) { - k = 0x44; -#endif - } else if (s == rodata_section || 0 == strcmp(s->name, ".data.rel.ro")) { - k = 0x45; } else if (s->sh_type == SHT_DYNAMIC) { k = 0x46; } else if (s == s1->got) { k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */ + } else if (s->reloc && (s->reloc->sh_flags & SHF_ALLOC) && j == 0x100) { + k = 0x44; + /* <-- */ + } else if (s->sh_type == SHT_NOTE) { + k = 0x60; + } else if (s->sh_type == SHT_NOBITS) { + k = 0x70; /* bss */ + } else if (s == d->interp) { + k = 0x00; } else { - k = 0x50; - if (s->sh_type == SHT_NOTE) - k = 0x60; - if (s->sh_flags & SHF_EXECINSTR) - k = 0x70; - if (s->sh_type == SHT_NOBITS) - k = 0x80; - if (s == d->interp) - k = 0x00; + k = 0x50; /* data */ } k += j; + if ((k & 0xfff0) == 0x140) { + /* make RELRO section writable */ + k += 0x100, s->sh_flags |= SHF_WRITE; + } for (n = i; n > 1 && k < (f = sec_cls[n - 1]); --n) sec_cls[n] = f, sec_order[n] = sec_order[n - 1]; 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) f0 = f, ++n, f |= 1<<8; } sec_cls[i] = f; - //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); + //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); } return n; } @@ -2395,12 +2402,8 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d) fill_phdr(++ph, PT_NOTE, d->note); if (d->dynamic) fill_phdr(++ph, PT_DYNAMIC, d->dynamic)->p_flags |= PF_W; - if (eh_frame_hdr_section) { - add32le(eh_frame_hdr_section->data + 4, - eh_frame_section->sh_offset - - eh_frame_hdr_section->sh_offset - 4); + if (eh_frame_hdr_section) fill_phdr(++ph, PT_GNU_EH_FRAME, eh_frame_hdr_section); - } if (d->roinf) fill_phdr(++ph, PT_GNU_RELRO, d->roinf)->p_flags |= PF_W; if (d->interp) @@ -2869,10 +2872,10 @@ static int elf_output_file(TCCState *s1, const char *filename) /* shared library case: simply export all global symbols */ export_global_syms(s1); } - +#if TCC_EH_FRAME /* fill with initial data */ tcc_eh_frame_hdr(s1, 0); - +#endif dyninf.gnu_hash = create_gnu_hash(s1); } else { build_got_entries(s1, 0); @@ -2956,10 +2959,10 @@ static int elf_output_file(TCCState *s1, const char *filename) update_gnu_hash(s1, dyninf.gnu_hash); reorder_sections(s1, sec_order); - +#if TCC_EH_FRAME /* fill with final data */ tcc_eh_frame_hdr(s1, 1); - +#endif /* Create the ELF file with name 'filename' */ ret = tcc_write_elf_file(s1, filename, dyninf.phnum, dyninf.phdr); the_end: @@ -3146,6 +3149,11 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, if (sh->sh_type == SHT_RELX) sh = &shdr[sh->sh_info]; /* ignore sections types we do not handle (plus relocs to those) */ + if (0 == strncmp(strsec + sh->sh_name, ".debug_", 7) + || 0 == strncmp(strsec + sh->sh_name, ".stab", 5)) { + if (!s1->do_debug || seencompressed) + continue; + } else if (sh->sh_type != SHT_PROGBITS && #ifdef TCC_ARM_EABI sh->sh_type != SHT_ARM_EXIDX && @@ -3157,12 +3165,9 @@ ST_FUNC int tcc_load_object_file(TCCState *s1, sh->sh_type != SHT_NOBITS && sh->sh_type != SHT_PREINIT_ARRAY && sh->sh_type != SHT_INIT_ARRAY && - sh->sh_type != SHT_FINI_ARRAY && - strcmp(strsec + sh->sh_name, ".stabstr") + sh->sh_type != SHT_FINI_ARRAY ) continue; - if (seencompressed && 0 == strncmp(strsec + sh->sh_name, ".debug_", 7)) - continue; sh = &shdr[i]; sh_name = strsec + sh->sh_name; @@ -3414,7 +3419,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) data = tcc_malloc(size); if (full_read(fd, data, size) != size) - goto the_end; + goto invalid; nsyms = get_be(data, entrysize); ar_index = data + entrysize; ar_names = (char *) ar_index + nsyms * entrysize; @@ -3432,6 +3437,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size, int entrysize) off = get_be(ar_index + i * entrysize, entrysize); len = read_ar_header(fd, off, &hdr); if (len <= 0 || memcmp(hdr.ar_fmag, ARFMAG, 2)) { + invalid: tcc_error_noabort("invalid archive"); goto the_end; } diff --git a/tccgen.c b/tccgen.c index d42a8b40e..923abf554 100644 --- a/tccgen.c +++ b/tccgen.c @@ -401,7 +401,9 @@ ST_FUNC int tccgen_compile(TCCState *s1) gen_inline_functions(s1); check_vstack(); /* end of translation unit info */ +#if TCC_EH_FRAME tcc_eh_frame_end(s1); +#endif tcc_debug_end(s1); tcc_tcov_end(s1); return 0; diff --git a/tccpe.c b/tccpe.c index f7bd67ce4..6f2db866e 100644 --- a/tccpe.c +++ b/tccpe.c @@ -845,7 +845,7 @@ static struct import_symbol *pe_add_import(struct pe_info *pe, int sym_index) return s; } -void pe_free_imports(struct pe_info *pe) +static void pe_free_imports(struct pe_info *pe) { int i; for (i = 0; i < pe->imp_count; ++i) { @@ -1133,9 +1133,7 @@ static int pe_section_class(Section *s) name = s->name; if (0 == memcmp(name, ".stab", 5) || 0 == memcmp(name, ".debug_", 7)) { - if (s->s1->do_debug) - return sec_debug; - + return sec_debug; } else if (flags & SHF_ALLOC) { if (type == SHT_PROGBITS || type == SHT_INIT_ARRAY @@ -1995,7 +1993,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe) tcc_add_support(s1, TCC_LIBTCC1); for (pp = libs; 0 != (p = *pp); ++pp) { if (*p) - tcc_add_library_err(s1, p); + tcc_add_library(s1, p); else if (PE_DLL != pe_type && PE_GUI != pe_type) break; } @@ -2068,8 +2066,8 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename) #ifdef CONFIG_TCC_BCHECK tcc_add_bcheck(s1); #endif - pe_add_runtime(s1, &pe); tcc_add_pragma_libs(s1); + pe_add_runtime(s1, &pe); resolve_common_syms(s1); pe_set_options(s1, &pe); pe_check_symbols(&pe); diff --git a/tccpp.c b/tccpp.c index 6f2bc173b..ade45f9ec 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1929,23 +1929,28 @@ ST_FUNC void preprocess(int is_bof) break; case TOK_LINE: next_nomacro(); - if (tok != TOK_PPNUM) + if (tok != TOK_PPNUM) { _line_err: + if (parse_flags & PARSE_FLAG_ASM_FILE) + goto ignore; tcc_error("wrong #line format"); + } case TOK_PPNUM: - parse_number(tokc.str.data); - n = tokc.i; + for (n = 0, q = tokc.str.data; *q; ++q) { + if (!isnum(*q)) + goto _line_err; + n = n * 10 + *q - '0'; + } next_nomacro(); if (tok != TOK_LINEFEED) { if (tok == TOK_PPSTR && tokc.str.data[0] == '"') { tokc.str.data[tokc.str.size - 2] = 0; tccpp_putfile(tokc.str.data + 1); - } else if (parse_flags & PARSE_FLAG_ASM_FILE) - goto ignore; - else + } else goto _line_err; next_nomacro(); - } + } else if (parse_flags & PARSE_FLAG_ASM_FILE) + goto ignore; if (file->fd > 0) total_lines += file->line_num - n; file->line_num = n;