Skip to content

Commit

Permalink
tccelf: cleanup sort_sections() & etc. fixes
Browse files Browse the repository at this point in the history
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())
  • Loading branch information
grischka committed Nov 17, 2024
1 parent 3eb6352 commit dd2e5f8
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 125 deletions.
71 changes: 36 additions & 35 deletions lib/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 <target>-libtcc1-usegcc=yes
arm-libtcc1-usegcc ?= no
Expand All @@ -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)))
Expand Down
34 changes: 18 additions & 16 deletions libtcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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))
Expand Down Expand Up @@ -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]) {
Expand All @@ -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)
Expand All @@ -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;
}

Expand Down Expand Up @@ -1219,23 +1229,15 @@ 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,) */
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)
Expand Down
10 changes: 5 additions & 5 deletions tcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -392,17 +392,17 @@ 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);
}
}

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 */
Expand Down
13 changes: 7 additions & 6 deletions tcc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
11 changes: 6 additions & 5 deletions tccdbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) \
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
Loading

0 comments on commit dd2e5f8

Please sign in to comment.