forked from Mirrors/tinycc
Compare commits
10 Commits
Author | SHA1 | Date |
---|---|---|
Bernhard Reutner-Fischer | bfa394dab8 | |
Bernhard Reutner-Fischer | a39d055d0e | |
Bernhard Reutner-Fischer | f0e8b23d02 | |
Bernhard Reutner-Fischer | 83cb1364a6 | |
Bernhard Reutner-Fischer | d90eb2008b | |
Bernhard Reutner-Fischer | 8a555345e3 | |
Bernhard Reutner-Fischer | 3a40b44938 | |
Mitchell N Charity | 77999caefe | |
Mitchell N Charity | e78212e2af | |
Mitchell N Charity | a5db5cf8df |
40
Makefile
40
Makefile
|
@ -8,6 +8,7 @@ include $(TOP)/config.mak
|
|||
CFLAGS+=-g -Wall
|
||||
CFLAGS_P=$(CFLAGS) -pg -static -DCONFIG_TCC_STATIC
|
||||
LIBS_P=
|
||||
CFLAGS_PIC ?= -fPIC
|
||||
|
||||
ifneq ($(GCC_MAJOR),2)
|
||||
CFLAGS+=-fno-strict-aliasing
|
||||
|
@ -32,19 +33,23 @@ LIBS+=-ldl
|
|||
endif
|
||||
endif
|
||||
|
||||
BCHECK=
|
||||
BCHECK_O=
|
||||
ALLOCA_O=
|
||||
|
||||
ifeq ($(ARCH),i386)
|
||||
NATIVE_TARGET=-DTCC_TARGET_I386
|
||||
LIBTCC1=libtcc1.a
|
||||
BCHECK_O=bcheck.o
|
||||
ALLOCA_O=alloca86.o alloca86-bt.o
|
||||
else
|
||||
ALLOCA_O=alloca86.o
|
||||
BCHECK_O=bcheck.o alloca86-bt.o
|
||||
BCHECK=bcheck.a
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),x86-64)
|
||||
NATIVE_TARGET=-DTCC_TARGET_X86_64
|
||||
LIBTCC1=libtcc1.a
|
||||
BCHECK_O=
|
||||
ALLOCA_O=alloca86_64.o
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),arm)
|
||||
NATIVE_TARGET=-DTCC_TARGET_ARM
|
||||
|
@ -54,12 +59,10 @@ endif
|
|||
|
||||
ifdef CONFIG_WIN32
|
||||
NATIVE_TARGET+=-DTCC_TARGET_PE
|
||||
BCHECK_O=
|
||||
endif
|
||||
|
||||
ifneq ($(wildcard /lib/ld-uClibc.so.0),)
|
||||
NATIVE_TARGET+=-DTCC_UCLIBC
|
||||
BCHECK_O=
|
||||
endif
|
||||
|
||||
ifdef CONFIG_USE_LIBGCC
|
||||
|
@ -113,7 +116,7 @@ ifdef CONFIG_CROSS
|
|||
PROGS+=$(PROGS_CROSS)
|
||||
endif
|
||||
|
||||
all: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)
|
||||
all: $(PROGS) $(LIBTCC1) $(BCHECK) libtcc.a tcc-doc.html tcc.1 libtcc_test$(EXESUF)
|
||||
|
||||
# Host Tiny C Compiler
|
||||
tcc$(EXESUF): $(NATIVE_FILES)
|
||||
|
@ -196,14 +199,17 @@ libtcc1.a: $(LIBTCC1_OBJS)
|
|||
bcheck.o: bcheck.c
|
||||
$(CC) -o $@ -c $< -O2 -Wall
|
||||
|
||||
bcheck.a: $(BCHECK_O)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
# install
|
||||
TCC_INCLUDES = stdarg.h stddef.h stdbool.h float.h varargs.h tcclib.h
|
||||
INSTALL=install
|
||||
|
||||
ifndef CONFIG_WIN32
|
||||
install: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc.1 tcc-doc.html
|
||||
install: $(PROGS) $(LIBTCC1) $(BCHECK) libtcc.a tcc.1 tcc-doc.html
|
||||
mkdir -p "$(bindir)"
|
||||
$(INSTALL) -s -m755 $(PROGS) "$(bindir)"
|
||||
$(INSTALL) -m755 $(PROGS) "$(bindir)"
|
||||
mkdir -p "$(mandir)/man1"
|
||||
$(INSTALL) tcc.1 "$(mandir)/man1"
|
||||
mkdir -p "$(tccdir)"
|
||||
|
@ -211,8 +217,8 @@ install: $(PROGS) $(LIBTCC1) $(BCHECK_O) libtcc.a tcc.1 tcc-doc.html
|
|||
ifneq ($(LIBTCC1),)
|
||||
$(INSTALL) -m644 $(LIBTCC1) "$(tccdir)"
|
||||
endif
|
||||
ifneq ($(BCHECK_O),)
|
||||
$(INSTALL) -m644 $(BCHECK_O) "$(tccdir)"
|
||||
ifneq ($(BCHECK),)
|
||||
$(INSTALL) -m644 $(BCHECK) "$(tccdir)"
|
||||
endif
|
||||
$(INSTALL) -m644 $(addprefix include/,$(TCC_INCLUDES)) "$(tccdir)/include"
|
||||
mkdir -p "$(docdir)"
|
||||
|
@ -224,20 +230,20 @@ endif
|
|||
|
||||
uninstall:
|
||||
rm -fv $(foreach P,$(PROGS),"$(bindir)/$P")
|
||||
rm -fv $(foreach P,$(LIBTCC1) $(BCHECK_O),"$(tccdir)/$P")
|
||||
rm -fv $(foreach P,$(LIBTCC1) $(BCHECK),"$(tccdir)/$P")
|
||||
rm -fv $(foreach P,$(TCC_INCLUDES),"$(tccdir)/include/$P")
|
||||
rm -fv "$(docdir)/tcc-doc.html" "$(mandir)/man1/tcc.1"
|
||||
rm -fv "$(libdir)/libtcc.a" "$(includedir)/libtcc.h"
|
||||
|
||||
else
|
||||
install: $(PROGS) $(LIBTCC1) libtcc.a tcc-doc.html
|
||||
mkdir -p "$(tccdir)"
|
||||
mkdir -p "$(bindir)"
|
||||
mkdir -p "$(tccdir)/lib"
|
||||
mkdir -p "$(tccdir)/include"
|
||||
mkdir -p "$(tccdir)/examples"
|
||||
mkdir -p "$(tccdir)/doc"
|
||||
mkdir -p "$(tccdir)/libtcc"
|
||||
$(INSTALL) -s -m755 $(PROGS) "$(tccdir)"
|
||||
$(INSTALL) -m755 $(PROGS) "$(bindir)"
|
||||
$(INSTALL) -m644 $(LIBTCC1) win32/lib/*.def "$(tccdir)/lib"
|
||||
cp -r win32/include/. "$(tccdir)/include"
|
||||
cp -r win32/examples/. "$(tccdir)/examples"
|
||||
|
@ -245,6 +251,10 @@ install: $(PROGS) $(LIBTCC1) libtcc.a tcc-doc.html
|
|||
$(INSTALL) -m644 tcc-doc.html win32/tcc-win32.txt "$(tccdir)/doc"
|
||||
$(INSTALL) -m644 libtcc.a libtcc.h "$(tccdir)/libtcc"
|
||||
endif
|
||||
install-strip: install
|
||||
ifneq ($(strip $(STRIP)),)
|
||||
$(STRIP) $(addprefix $(bindir), $(PROGS))
|
||||
endif
|
||||
|
||||
# documentation and man page
|
||||
tcc-doc.html: tcc-doc.texi
|
||||
|
|
14
libtcc.c
14
libtcc.c
|
@ -206,6 +206,7 @@ static int tcc_add_dll(TCCState *s, const char *filename, int flags);
|
|||
#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
|
||||
#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
|
||||
#define AFF_PREPROCESS 0x0004 /* preprocess file */
|
||||
#define AFF_WHOLE_ARCHIVE 0x0008 /* add whole archive not just undef symbol */
|
||||
static int tcc_add_file_internal(TCCState *s, const char *filename, int flags);
|
||||
|
||||
/* tcccoff.c */
|
||||
|
@ -1247,7 +1248,8 @@ static int tcc_compile(TCCState *s1)
|
|||
section_sym = put_elf_sym(symtab_section, 0, 0,
|
||||
ELFW(ST_INFO)(STB_LOCAL, STT_SECTION), 0,
|
||||
text_section->sh_num, NULL);
|
||||
getcwd(buf, sizeof(buf));
|
||||
if (getcwd(buf, sizeof(buf)) == NULL)
|
||||
error("getcwd: %s",strerror(errno));
|
||||
#ifdef _WIN32
|
||||
normalize_slashes(buf);
|
||||
#endif
|
||||
|
@ -2116,7 +2118,7 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
|
||||
if (memcmp((char *)&ehdr, ARMAG, 8) == 0) {
|
||||
file->line_num = 0; /* do not display line number if error */
|
||||
ret = tcc_load_archive(s1, fd);
|
||||
ret = tcc_load_archive(s1, fd, flags & AFF_WHOLE_ARCHIVE);
|
||||
goto the_end;
|
||||
}
|
||||
|
||||
|
@ -2133,9 +2135,11 @@ static int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
|
|||
/* as GNU ld, consider it is an ld script if not recognized */
|
||||
ret = tcc_load_ldscript(s1);
|
||||
#endif
|
||||
/* TODO: the_end label should be here !! */
|
||||
if (ret < 0)
|
||||
error_noabort("unrecognized file type");
|
||||
|
||||
error_noabort("%s: unrecognized file type", filename);
|
||||
else if (s1->verbose)
|
||||
printf("+> %s\n", filename);
|
||||
the_end:
|
||||
if (file)
|
||||
tcc_close(file);
|
||||
|
@ -2211,7 +2215,7 @@ int tcc_add_symbol(TCCState *s, const char *name, void *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tcc_set_output_type(TCCState *s, int output_type)
|
||||
int tcc_set_output_type(TCCState *s, output_t output_type)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
|
|
24
libtcc.h
24
libtcc.h
|
@ -61,17 +61,23 @@ LIBTCCAPI int tcc_compile_string(TCCState *s, const char *buf);
|
|||
/* linking commands */
|
||||
|
||||
/* set output type. MUST BE CALLED before any compilation */
|
||||
#define TCC_OUTPUT_MEMORY 0 /* output will be ran in memory (no
|
||||
enum output_type_e {
|
||||
TCC_OUTPUT_MEMORY = 0, /* output will be ran in memory (no
|
||||
output file) (default) */
|
||||
#define TCC_OUTPUT_EXE 1 /* executable file */
|
||||
#define TCC_OUTPUT_DLL 2 /* dynamic library */
|
||||
#define TCC_OUTPUT_OBJ 3 /* object file */
|
||||
#define TCC_OUTPUT_PREPROCESS 4 /* preprocessed file (used internally) */
|
||||
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type);
|
||||
TCC_OUTPUT_EXE = 1, /* executable file */
|
||||
TCC_OUTPUT_DLL = 2, /* dynamic library */
|
||||
TCC_OUTPUT_OBJ = 3, /* object file */
|
||||
TCC_OUTPUT_PREPROCESS = 4 /* preprocessed file (used internally) */
|
||||
};
|
||||
typedef enum output_type_e output_t;
|
||||
LIBTCCAPI int tcc_set_output_type(TCCState *s, output_t output_type);
|
||||
|
||||
#define TCC_OUTPUT_FORMAT_ELF 0 /* default output format: ELF */
|
||||
#define TCC_OUTPUT_FORMAT_BINARY 1 /* binary image output */
|
||||
#define TCC_OUTPUT_FORMAT_COFF 2 /* COFF */
|
||||
enum output_format_e {
|
||||
TCC_OUTPUT_FORMAT_ELF = 0, /* default output format: ELF */
|
||||
TCC_OUTPUT_FORMAT_BINARY = 1, /* binary image output */
|
||||
TCC_OUTPUT_FORMAT_COFF = 2 /* COFF */
|
||||
};
|
||||
typedef enum output_format_e output_format_t;
|
||||
|
||||
/* equivalent to -Lpath option */
|
||||
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname);
|
||||
|
|
12
tcc-doc.texi
12
tcc-doc.texi
|
@ -299,6 +299,14 @@ also be given).
|
|||
@item -Wl,-Ttext,address
|
||||
Set the start of the .text section to @var{address}.
|
||||
|
||||
@item -Wl,--whole-archive
|
||||
Add a whole archive, not just the symbols of the archive that would
|
||||
satisfy undefined symbols in the program.
|
||||
|
||||
@item -Wl,--no-whole-archive
|
||||
Turn off the effect of the --whole-archive option for subsequent archive
|
||||
files.
|
||||
|
||||
@item -Wl,--oformat,fmt
|
||||
Use @var{fmt} as output format. The supported output formats are:
|
||||
@table @code
|
||||
|
@ -332,8 +340,8 @@ Display N callers in stack traces. This is useful with @option{-g} or
|
|||
|
||||
@end table
|
||||
|
||||
Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are
|
||||
ignored.
|
||||
Note: GCC options @option{-Ox}, @option{-fx} and @option{-mx} are ignored
|
||||
except @option{-muclibc} and @option{-mglibc}.
|
||||
@c man end
|
||||
|
||||
@ignore
|
||||
|
|
24
tcc.c
24
tcc.c
|
@ -54,6 +54,8 @@ void help(void)
|
|||
" -static static linking\n"
|
||||
" -rdynamic export all global symbols to dynamic linker\n"
|
||||
" -r generate (relocatable) object file\n"
|
||||
" --whole-archive include all object files in the archives\n"
|
||||
" --no-whole-archive turn the effect of --whole-archives off\n"
|
||||
"Debugger options:\n"
|
||||
" -g generate runtime debug info\n"
|
||||
#ifdef CONFIG_TCC_BCHECK
|
||||
|
@ -66,13 +68,15 @@ void help(void)
|
|||
}
|
||||
|
||||
static char **files;
|
||||
static int nb_files, nb_libraries;
|
||||
static char **whole_archives;
|
||||
static int nb_files, nb_libraries, nb_whole_archive;
|
||||
static int multiple_files;
|
||||
static int print_search_dirs;
|
||||
static int output_type;
|
||||
static output_t output_type;
|
||||
static int reloc_output;
|
||||
static const char *outfile;
|
||||
static int do_bench = 0;
|
||||
static unsigned do_whole_archive = 0;
|
||||
|
||||
#define TCC_OPTION_HAS_ARG 0x0001
|
||||
#define TCC_OPTION_NOSEP 0x0002 /* cannot have space before option and arg */
|
||||
|
@ -227,6 +231,7 @@ int parse_args(TCCState *s, int argc, char **argv)
|
|||
if (r[0] != '-' || r[1] == '\0') {
|
||||
/* add a new file */
|
||||
dynarray_add((void ***)&files, &nb_files, r);
|
||||
dynarray_add((void ***)&whole_archives, &nb_whole_archive, (void*)do_whole_archive);
|
||||
if (!multiple_files) {
|
||||
optind--;
|
||||
/* argv[0] will be this file */
|
||||
|
@ -297,6 +302,7 @@ int parse_args(TCCState *s, int argc, char **argv)
|
|||
break;
|
||||
case TCC_OPTION_l:
|
||||
dynarray_add((void ***)&files, &nb_files, r);
|
||||
dynarray_add((void ***)&whole_archives, &nb_whole_archive, (void*)do_whole_archive);
|
||||
nb_libraries++;
|
||||
break;
|
||||
case TCC_OPTION_bench:
|
||||
|
@ -442,6 +448,10 @@ int parse_args(TCCState *s, int argc, char **argv)
|
|||
{
|
||||
error("target %s not found", p);
|
||||
}
|
||||
} else if (strstart(optarg, "--whole-archive", &p)) {
|
||||
do_whole_archive = 1;
|
||||
} else if (strstart(optarg, "--no-whole-archive", &p)) {
|
||||
do_whole_archive = 0;
|
||||
} else {
|
||||
error("unsupported linker option '%s'", optarg);
|
||||
}
|
||||
|
@ -452,6 +462,9 @@ int parse_args(TCCState *s, int argc, char **argv)
|
|||
break;
|
||||
case TCC_OPTION_x:
|
||||
break;
|
||||
case TCC_OPTION_m:
|
||||
s->use_ulibc_interp = !strcmp("uclibc", optarg);
|
||||
break;
|
||||
default:
|
||||
if (s->warn_unsupported) {
|
||||
unsupported_option:
|
||||
|
@ -478,8 +491,10 @@ int main(int argc, char **argv)
|
|||
outfile = NULL;
|
||||
multiple_files = 1;
|
||||
files = NULL;
|
||||
whole_archives = NULL;
|
||||
nb_files = 0;
|
||||
nb_libraries = 0;
|
||||
nb_whole_archive = 0;
|
||||
reloc_output = 0;
|
||||
print_search_dirs = 0;
|
||||
ret = 0;
|
||||
|
@ -563,9 +578,10 @@ int main(int argc, char **argv)
|
|||
ret = 1;
|
||||
}
|
||||
} else {
|
||||
int whole = ((int)whole_archives[i]) << 3; /* AFF_WHOLE_ARCHIVE */
|
||||
if (1 == s->verbose)
|
||||
printf("-> %s\n", filename);
|
||||
if (tcc_add_file(s, filename) < 0)
|
||||
printf("-%c %s\n", whole?'[':'>', filename);
|
||||
if (tcc_add_file_internal(s, filename, whole) < 0)
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
|
107
tcc.h
107
tcc.h
|
@ -108,7 +108,7 @@
|
|||
#define TCC_TARGET_I386
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(TCC_UCLIBC) && !defined(TCC_TARGET_ARM) && \
|
||||
#if !defined(_WIN32) && !defined(TCC_TARGET_ARM) && \
|
||||
!defined(TCC_TARGET_C67) && !defined(TCC_TARGET_X86_64)
|
||||
#define CONFIG_TCC_BCHECK /* enable bound checking code */
|
||||
#endif
|
||||
|
@ -392,8 +392,8 @@ typedef struct ASMOperand {
|
|||
#endif
|
||||
|
||||
struct TCCState {
|
||||
int output_type;
|
||||
|
||||
output_t output_type;
|
||||
|
||||
BufferedFile **include_stack_ptr;
|
||||
int *ifdef_stack_ptr;
|
||||
|
||||
|
@ -454,7 +454,7 @@ struct TCCState {
|
|||
int has_text_addr;
|
||||
|
||||
/* output format, see TCC_OUTPUT_FORMAT_xxx */
|
||||
int output_format;
|
||||
output_format_t output_format;
|
||||
|
||||
/* C language options */
|
||||
int char_is_unsigned;
|
||||
|
@ -531,6 +531,7 @@ struct TCCState {
|
|||
unsigned int runtime_plt_and_got_offset;
|
||||
#endif
|
||||
#endif
|
||||
unsigned int use_ulibc_interp; /* elf-interpreter to use */
|
||||
};
|
||||
|
||||
/* The current value can be: */
|
||||
|
@ -762,8 +763,7 @@ enum tcc_token {
|
|||
#define strtof (float)strtod
|
||||
#define strtoll (long long)strtol
|
||||
#endif
|
||||
#elif defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
|
||||
|| defined(__OpenBSD__)
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
|
||||
/* currently incorrect */
|
||||
long double strtold(const char *nptr, char **endptr)
|
||||
{
|
||||
|
@ -789,6 +789,101 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
|||
#define PATHCMP strcmp
|
||||
#endif
|
||||
|
||||
/* impose symbol hygiene
|
||||
|
||||
All global symbols defined in libtcc.a should have a prefix of either
|
||||
tcc_ or _tcc_ , to avoid user namespace pollution and conflicts.
|
||||
|
||||
nm -g -P libtcc.a |perl -e '$x=<>;while(<>){my($symbol,$type)=/(\S+) (\S) / or die;next if $type eq "U"||$symbol=~/^_?tcc_/;print "#define $symbol _tcc_$symbol\n"}' > insert_below
|
||||
*/
|
||||
#define bn_lshift _tcc_bn_lshift
|
||||
#define bn_zero _tcc_bn_zero
|
||||
#define dynarray_add _tcc_dynarray_add
|
||||
#define dynarray_reset _tcc_dynarray_reset
|
||||
#define elf_output_file _tcc_elf_output_file
|
||||
#define error _tcc_error
|
||||
#define error1 _tcc_error1
|
||||
#define error_noabort _tcc_error_noabort
|
||||
#define expect _tcc_expect
|
||||
#define find_section _tcc_find_section
|
||||
#define force_charshort_cast _tcc_force_charshort_cast
|
||||
#define g _tcc_g
|
||||
#define gaddrof _tcc_gaddrof
|
||||
#define gen_cvt_ftof _tcc_gen_cvt_ftof
|
||||
#define gen_cvt_ftoi _tcc_gen_cvt_ftoi
|
||||
#define gen_cvt_ftoi1 _tcc_gen_cvt_ftoi1
|
||||
#define gen_cvt_itof _tcc_gen_cvt_itof
|
||||
#define gen_cvt_itof1 _tcc_gen_cvt_itof1
|
||||
#define gen_le32 _tcc_gen_le32
|
||||
#define gen_le64 _tcc_gen_le64
|
||||
#define gen_op _tcc_gen_op
|
||||
#define gen_opf _tcc_gen_opf
|
||||
#define gen_opi _tcc_gen_opi
|
||||
#define gen_opic _tcc_gen_opic
|
||||
#define gen_opif _tcc_gen_opif
|
||||
#define gen_opl _tcc_gen_opl
|
||||
#define get_reg _tcc_get_reg
|
||||
#define get_reg_ex _tcc_get_reg_ex
|
||||
#define get_tok_str _tcc_get_tok_str
|
||||
#define gfunc_call _tcc_gfunc_call
|
||||
#define gfunc_epilog _tcc_gfunc_epilog
|
||||
#define gfunc_prolog _tcc_gfunc_prolog
|
||||
#define ggoto _tcc_ggoto
|
||||
#define gjmp _tcc_gjmp
|
||||
#define gjmp_addr _tcc_gjmp_addr
|
||||
#define gsym _tcc_gsym
|
||||
#define gsym_addr _tcc_gsym_addr
|
||||
#define gtst _tcc_gtst
|
||||
#define gv _tcc_gv
|
||||
#define gv2 _tcc_gv2
|
||||
#define gv_dup _tcc_gv_dup
|
||||
#define ieee_finite _tcc_ieee_finite
|
||||
#define inc _tcc_inc
|
||||
#define lbuild _tcc_lbuild
|
||||
#define lexpand _tcc_lexpand
|
||||
#define load _tcc_load
|
||||
#define move_reg _tcc_move_reg
|
||||
#define new_section _tcc_new_section
|
||||
#define num_callers _tcc_num_callers
|
||||
#define o _tcc_o
|
||||
#define parse_number _tcc_parse_number
|
||||
#define preprocess_new _tcc_preprocess_new
|
||||
#define preprocess_skip _tcc_preprocess_skip
|
||||
#define pstrcat _tcc_pstrcat
|
||||
#define pstrcpy _tcc_pstrcpy
|
||||
#define put_func_debug _tcc_put_func_debug
|
||||
#define rc_fret _tcc_rc_fret
|
||||
#define reg_classes _tcc_reg_classes
|
||||
#define reg_fret _tcc_reg_fret
|
||||
#define resolve_sym _tcc_resolve_sym
|
||||
#define restore_parse_state _tcc_restore_parse_state
|
||||
#define rt_bound_error_msg _tcc_rt_bound_error_msg
|
||||
#define rt_error _tcc_rt_error
|
||||
#define rt_prog_main _tcc_rt_prog_main
|
||||
#define save_parse_state _tcc_save_parse_state
|
||||
#define save_reg _tcc_save_reg
|
||||
#define save_regs _tcc_save_regs
|
||||
#define set_pages_executable _tcc_set_pages_executable
|
||||
#define skip _tcc_skip
|
||||
#define store _tcc_store
|
||||
#define swap _tcc_swap
|
||||
#define total_bytes _tcc_total_bytes
|
||||
#define total_lines _tcc_total_lines
|
||||
#define type_to_str _tcc_type_to_str
|
||||
#define vdup _tcc_vdup
|
||||
#define vpop _tcc_vpop
|
||||
#define vpushi _tcc_vpushi
|
||||
#define vpushll _tcc_vpushll
|
||||
#define vpushv _tcc_vpushv
|
||||
#define vrotb _tcc_vrotb
|
||||
#define vrott _tcc_vrott
|
||||
#define vset _tcc_vset
|
||||
#define vsetc _tcc_vsetc
|
||||
#define vseti _tcc_vseti
|
||||
#define vstore _tcc_vstore
|
||||
#define vswap _tcc_vswap
|
||||
#define warning _tcc_warning
|
||||
|
||||
void error(const char *fmt, ...);
|
||||
void error_noabort(const char *fmt, ...);
|
||||
void warning(const char *fmt, ...);
|
||||
|
|
44
tccelf.c
44
tccelf.c
|
@ -1207,8 +1207,8 @@ static void tcc_add_runtime(TCCState *s1)
|
|||
ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
|
||||
bounds_section->sh_num, "__bounds_start");
|
||||
/* add bound check code */
|
||||
snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.o");
|
||||
tcc_add_file(s1, buf);
|
||||
snprintf(buf, sizeof(buf), "%s/%s", s1->tcc_lib_path, "bcheck.a");
|
||||
tcc_add_file_internal(s1, buf, AFF_WHOLE_ARCHIVE | AFF_PRINT_ERROR);
|
||||
#ifdef TCC_TARGET_I386
|
||||
if (s1->output_type != TCC_OUTPUT_MEMORY) {
|
||||
/* add 'call __bound_init()' in .init section */
|
||||
|
@ -1301,17 +1301,21 @@ static void tcc_add_linker_symbols(TCCState *s1)
|
|||
}
|
||||
|
||||
/* name of ELF interpreter */
|
||||
static const char elf_interp[] =
|
||||
#if defined __FreeBSD__
|
||||
static const char elf_interp[] = "/libexec/ld-elf.so.1";
|
||||
"/libexec/ld-elf.so.1";
|
||||
#elif defined TCC_ARM_EABI
|
||||
static const char elf_interp[] = "/lib/ld-linux.so.3";
|
||||
"/lib/ld-linux.so.3"
|
||||
#elif defined(TCC_TARGET_X86_64)
|
||||
static const char elf_interp[] = "/lib/ld-linux-x86-64.so.2";
|
||||
#elif defined(TCC_UCLIBC)
|
||||
static const char elf_interp[] = "/lib/ld-uClibc.so.0";
|
||||
"/lib/ld-linux-x86-64.so.2"
|
||||
#else
|
||||
static const char elf_interp[] = "/lib/ld-linux.so.2";
|
||||
"/lib/ld-linux.so.2"
|
||||
#endif
|
||||
#if 1
|
||||
"\0/lib/ld-uClibc.so.0"
|
||||
#endif
|
||||
"\0"
|
||||
;
|
||||
|
||||
static void tcc_output_binary(TCCState *s1, FILE *f,
|
||||
const int *section_order)
|
||||
|
@ -1405,16 +1409,19 @@ int elf_output_file(TCCState *s1, const char *filename)
|
|||
ElfW(Sym) *esym, *sym_end;
|
||||
|
||||
if (file_type == TCC_OUTPUT_EXE) {
|
||||
/* add interpreter section only if executable */
|
||||
const char *ld = elf_interp;
|
||||
const char *ld_env = getenv("LD_SO");
|
||||
char *ptr;
|
||||
/* allow override the dynamic loader */
|
||||
const char *elfint = getenv("LD_SO");
|
||||
if (elfint == NULL)
|
||||
elfint = elf_interp;
|
||||
/* add interpreter section only if executable */
|
||||
if (s1->use_ulibc_interp == 1)
|
||||
ld += strlen(ld) + 1;
|
||||
else if (ld_env)
|
||||
ld = ld_env;
|
||||
interp = new_section(s1, ".interp", SHT_PROGBITS, SHF_ALLOC);
|
||||
interp->sh_addralign = 1;
|
||||
ptr = section_ptr_add(interp, 1+strlen(elfint));
|
||||
strcpy(ptr, elfint);
|
||||
ptr = section_ptr_add(interp, 1+strlen(ld));
|
||||
strcpy(ptr, ld);
|
||||
}
|
||||
|
||||
/* add dynamic symbol table */
|
||||
|
@ -2418,7 +2425,7 @@ static int get_be32(const uint8_t *b)
|
|||
}
|
||||
|
||||
/* load only the objects which resolve undefined symbols */
|
||||
static int tcc_load_alacarte(TCCState *s1, int fd, int size)
|
||||
static int tcc_load_alacarte(TCCState *s1, int fd, int size, int whole_archive)
|
||||
{
|
||||
int i, bound, nsyms, sym_index, off, ret;
|
||||
uint8_t *data;
|
||||
|
@ -2440,6 +2447,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
|
|||
if(sym_index) {
|
||||
sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if(sym->st_shndx == SHN_UNDEF) {
|
||||
load_obj:
|
||||
off = get_be32(ar_index + i * 4) + sizeof(ArchiveHeader);
|
||||
#if 0
|
||||
printf("%5d\t%s\t%08x\n", i, p, sym->st_shndx);
|
||||
|
@ -2452,6 +2460,8 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
|
|||
goto the_end;
|
||||
}
|
||||
}
|
||||
} else if (whole_archive) {
|
||||
goto load_obj;
|
||||
}
|
||||
}
|
||||
} while(bound);
|
||||
|
@ -2462,7 +2472,7 @@ static int tcc_load_alacarte(TCCState *s1, int fd, int size)
|
|||
}
|
||||
|
||||
/* load a '.a' file */
|
||||
static int tcc_load_archive(TCCState *s1, int fd)
|
||||
static int tcc_load_archive(TCCState *s1, int fd, int whole_archive)
|
||||
{
|
||||
ArchiveHeader hdr;
|
||||
char ar_size[11];
|
||||
|
@ -2498,7 +2508,7 @@ static int tcc_load_archive(TCCState *s1, int fd)
|
|||
if (!strcmp(ar_name, "/")) {
|
||||
/* coff symbol table : we handle it */
|
||||
if(s1->alacarte_link)
|
||||
return tcc_load_alacarte(s1, fd, size);
|
||||
return tcc_load_alacarte(s1, fd, size, whole_archive);
|
||||
} else if (!strcmp(ar_name, "//") ||
|
||||
!strcmp(ar_name, "__.SYMDEF") ||
|
||||
!strcmp(ar_name, "__.SYMDEF/") ||
|
||||
|
|
Loading…
Reference in New Issue