Alien-TinyCCx
view release on metacpan or search on metacpan
src/libtcc.c view on Meta::CPAN
s->symtab_serialize_outfile = NULL;
s->dump_identifier_names_outfile = NULL;
/* #endif */
return s;
}
LIBTCCAPI void tcc_delete(TCCState *s1)
{
int bench = s1->do_bench;
tcc_cleanup();
/* #ifdef CONFIG_TCC_EXSYMTAB */
/* Clean up the extended symbol table if it was never copied. */
if (s1->exsymtab > (extended_symtab*)1)
tcc_delete_extended_symbol_table(s1->exsymtab);
/* free file paths related to caching */
tcc_free(s1->symtab_serialize_outfile);
tcc_free(s1->dump_identifier_names_outfile);
/* #endif */
/* free sections */
tccelf_delete(s1);
/* free library paths */
dynarray_reset(&s1->library_paths, &s1->nb_library_paths);
dynarray_reset(&s1->crt_paths, &s1->nb_crt_paths);
/* free include paths */
dynarray_reset(&s1->cached_includes, &s1->nb_cached_includes);
dynarray_reset(&s1->include_paths, &s1->nb_include_paths);
dynarray_reset(&s1->sysinclude_paths, &s1->nb_sysinclude_paths);
tcc_free(s1->tcc_lib_path);
tcc_free(s1->soname);
tcc_free(s1->rpath);
tcc_free(s1->init_symbol);
tcc_free(s1->fini_symbol);
tcc_free(s1->outfile);
tcc_free(s1->deps_outfile);
dynarray_reset(&s1->files, &s1->nb_files);
dynarray_reset(&s1->target_deps, &s1->nb_target_deps);
dynarray_reset(&s1->pragma_libs, &s1->nb_pragma_libs);
#ifdef TCC_IS_NATIVE
/* free runtime memory */
tcc_run_free(s1);
#endif
tcc_free(s1->sym_attrs);
tcc_free(s1);
tcc_memstats(bench);
}
LIBTCCAPI int tcc_set_output_type(TCCState *s, int output_type)
{
s->output_type = output_type;
/* always elf for objects */
if (output_type == TCC_OUTPUT_OBJ)
s->output_format = TCC_OUTPUT_FORMAT_ELF;
if (s->char_is_unsigned)
tcc_define_symbol(s, "__CHAR_UNSIGNED__", NULL);
if (!s->nostdinc) {
/* default include paths */
/* -isystem paths have already been handled */
tcc_add_sysinclude_path(s, CONFIG_TCC_SYSINCLUDEPATHS);
}
#ifdef CONFIG_TCC_BCHECK
if (s->do_bounds_check) {
/* if bound checking, then add corresponding sections */
tccelf_bounds_new(s);
/* define symbol */
tcc_define_symbol(s, "__BOUNDS_CHECKING_ON", NULL);
}
#endif
if (s->do_debug) {
/* add debug sections */
tccelf_stab_new(s);
}
tcc_add_library_path(s, CONFIG_TCC_LIBPATHS);
#ifdef TCC_TARGET_PE
# ifdef _WIN32
if (!s->nostdlib && output_type != TCC_OUTPUT_OBJ)
tcc_add_systemdir(s);
# endif
#else
/* paths for crt objects */
tcc_split_path(s, (void ***)&s->crt_paths, &s->nb_crt_paths, CONFIG_TCC_CRTPREFIX);
/* add libc crt1/crti objects */
if ((output_type == TCC_OUTPUT_EXE || output_type == TCC_OUTPUT_DLL) &&
!s->nostdlib) {
if (output_type != TCC_OUTPUT_DLL)
tcc_add_crt(s, "crt1.o");
tcc_add_crt(s, "crti.o");
}
#endif
return 0;
}
LIBTCCAPI int tcc_add_include_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, (void ***)&s->include_paths, &s->nb_include_paths, pathname);
return 0;
}
LIBTCCAPI int tcc_add_sysinclude_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, (void ***)&s->sysinclude_paths, &s->nb_sysinclude_paths, pathname);
return 0;
}
ST_FUNC int tcc_add_file_internal(TCCState *s1, const char *filename, int flags)
{
int ret, filetype;
filetype = flags & 0x0F;
if (filetype == 0) {
/* use a file extension to detect a filetype */
const char *ext = tcc_fileextension(filename);
if (ext[0]) {
ext++;
if (!strcmp(ext, "S"))
filetype = AFF_TYPE_ASMPP;
else if (!strcmp(ext, "s"))
filetype = AFF_TYPE_ASM;
else if (!PATHCMP(ext, "c") || !PATHCMP(ext, "i"))
filetype = AFF_TYPE_C;
else
filetype = AFF_TYPE_BIN;
} else {
filetype = AFF_TYPE_C;
}
}
/* open the file */
ret = tcc_open(s1, filename);
if (ret < 0) {
if (flags & AFF_PRINT_ERROR)
tcc_error_noabort("file '%s' not found", filename);
return ret;
}
/* update target deps */
dynarray_add((void ***)&s1->target_deps, &s1->nb_target_deps,
tcc_strdup(filename));
parse_flags = 0;
/* if .S file, define __ASSEMBLER__ like gcc does */
if (filetype == AFF_TYPE_ASM || filetype == AFF_TYPE_ASMPP) {
tcc_define_symbol(s1, "__ASSEMBLER__", NULL);
parse_flags = PARSE_FLAG_ASM_FILE;
}
if (flags & AFF_PREPROCESS) {
ret = tcc_preprocess(s1);
} else if (filetype == AFF_TYPE_C) {
ret = tcc_compile(s1);
#ifdef CONFIG_TCC_ASM
} else if (filetype == AFF_TYPE_ASMPP) {
/* non preprocessed assembler */
ret = tcc_assemble(s1, 1);
} else if (filetype == AFF_TYPE_ASM) {
/* preprocessed assembler */
ret = tcc_assemble(s1, 0);
#endif
} else {
ElfW(Ehdr) ehdr;
int fd, obj_type;
fd = file->fd;
obj_type = tcc_object_type(fd, &ehdr);
lseek(fd, 0, SEEK_SET);
/* do not display line number if error */
file->line_num = 0;
switch (obj_type) {
case AFF_BINTYPE_REL:
ret = tcc_load_object_file(s1, fd, 0);
break;
#ifndef TCC_TARGET_PE
case AFF_BINTYPE_DYN:
if (s1->output_type == TCC_OUTPUT_MEMORY) {
ret = 0;
#ifdef TCC_IS_NATIVE
if (NULL == dlopen(filename, RTLD_GLOBAL | RTLD_LAZY))
ret = -1;
#endif
} else {
ret = tcc_load_dll(s1, fd, filename,
(flags & AFF_REFERENCED_DLL) != 0);
}
break;
#endif
case AFF_BINTYPE_AR:
ret = tcc_load_archive(s1, fd);
break;
#ifdef TCC_TARGET_COFF
case AFF_BINTYPE_C67:
ret = tcc_load_coff(s1, fd);
break;
#endif
default:
#ifdef TCC_TARGET_PE
ret = pe_load_file(s1, filename, fd);
#else
/* as GNU ld, consider it is an ld script if not recognized */
ret = tcc_load_ldscript(s1);
#endif
if (ret < 0)
tcc_error_noabort("unrecognized file type");
break;
}
}
tcc_close();
return ret;
}
LIBTCCAPI int tcc_add_file(TCCState *s, const char *filename)
{
if (s->output_type == TCC_OUTPUT_PREPROCESS)
return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | AFF_PREPROCESS | s->filetype);
else
return tcc_add_file_internal(s, filename, AFF_PRINT_ERROR | s->filetype);
}
LIBTCCAPI int tcc_add_library_path(TCCState *s, const char *pathname)
{
tcc_split_path(s, (void ***)&s->library_paths, &s->nb_library_paths, pathname);
return 0;
}
static int tcc_add_library_internal(TCCState *s, const char *fmt,
const char *filename, int flags, char **paths, int nb_paths)
{
char buf[1024];
int i;
for(i = 0; i < nb_paths; i++) {
snprintf(buf, sizeof(buf), fmt, paths[i], filename);
if (tcc_add_file_internal(s, buf, flags | AFF_TYPE_BIN) == 0)
return 0;
}
return -1;
}
#ifndef TCC_TARGET_PE
/* find and load a dll. Return non zero if not found */
/* XXX: add '-rpath' option support ? */
ST_FUNC int tcc_add_dll(TCCState *s, const char *filename, int flags)
{
return tcc_add_library_internal(s, "%s/%s", filename, flags,
s->library_paths, s->nb_library_paths);
}
#endif
ST_FUNC int tcc_add_crt(TCCState *s, const char *filename)
{
if (-1 == tcc_add_library_internal(s, "%s/%s",
filename, 0, s->crt_paths, s->nb_crt_paths))
tcc_error_noabort("file '%s' not found", filename);
return 0;
}
/* the library name is the same as the argument of the '-l' option */
LIBTCCAPI int tcc_add_library(TCCState *s, const char *libraryname)
{
#ifdef TCC_TARGET_PE
const char *libs[] = { "%s/%s.def", "%s/lib%s.def", "%s/%s.dll", "%s/lib%s.dll", "%s/lib%s.a", NULL };
const char **pp = s->static_link ? libs + 4 : libs;
#else
const char *libs[] = { "%s/lib%s.so", "%s/lib%s.a", NULL };
const char **pp = s->static_link ? libs + 1 : libs;
#endif
while (*pp) {
if (0 == tcc_add_library_internal(s, *pp,
libraryname, 0, s->library_paths, s->nb_library_paths))
return 0;
++pp;
}
return -1;
src/libtcc.c view on Meta::CPAN
/* '=' near eos means ',' or '=' is ok */
if (*q == '=') {
if (*p == 0)
*ptr = p;
if (*p != ',' && *p != '=')
return 0;
p++;
}
*ptr = p;
return ret;
}
static const char *skip_linker_arg(const char **str)
{
const char *s1 = *str;
const char *s2 = strchr(s1, ',');
*str = s2 ? s2++ : (s2 = s1 + strlen(s1));
return s2;
}
static char *copy_linker_arg(const char *p)
{
const char *q = p;
skip_linker_arg(&q);
return pstrncpy(tcc_malloc(q - p + 1), p, q - p);
}
/* set linker options */
static int tcc_set_linker(TCCState *s, const char *option)
{
while (*option) {
const char *p = NULL;
char *end = NULL;
int ignoring = 0;
int ret;
if (link_option(option, "Bsymbolic", &p)) {
s->symbolic = 1;
} else if (link_option(option, "nostdlib", &p)) {
s->nostdlib = 1;
} else if (link_option(option, "fini=", &p)) {
s->fini_symbol = copy_linker_arg(p);
ignoring = 1;
} else if (link_option(option, "image-base=", &p)
|| link_option(option, "Ttext=", &p)) {
s->text_addr = strtoull(p, &end, 16);
s->has_text_addr = 1;
} else if (link_option(option, "init=", &p)) {
s->init_symbol = copy_linker_arg(p);
ignoring = 1;
} else if (link_option(option, "oformat=", &p)) {
#if defined(TCC_TARGET_PE)
if (strstart("pe-", &p)) {
#elif defined(TCC_TARGET_ARM64) || defined(TCC_TARGET_X86_64)
if (strstart("elf64-", &p)) {
#else
if (strstart("elf32-", &p)) {
#endif
s->output_format = TCC_OUTPUT_FORMAT_ELF;
} else if (!strcmp(p, "binary")) {
s->output_format = TCC_OUTPUT_FORMAT_BINARY;
#ifdef TCC_TARGET_COFF
} else if (!strcmp(p, "coff")) {
s->output_format = TCC_OUTPUT_FORMAT_COFF;
#endif
} else
goto err;
} else if (link_option(option, "as-needed", &p)) {
ignoring = 1;
} else if (link_option(option, "O", &p)) {
ignoring = 1;
} else if (link_option(option, "rpath=", &p)) {
s->rpath = copy_linker_arg(p);
} else if (link_option(option, "section-alignment=", &p)) {
s->section_align = strtoul(p, &end, 16);
} else if (link_option(option, "soname=", &p)) {
s->soname = copy_linker_arg(p);
#ifdef TCC_TARGET_PE
} else if (link_option(option, "file-alignment=", &p)) {
s->pe_file_align = strtoul(p, &end, 16);
} else if (link_option(option, "stack=", &p)) {
s->pe_stack_size = strtoul(p, &end, 10);
} else if (link_option(option, "subsystem=", &p)) {
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
if (!strcmp(p, "native")) {
s->pe_subsystem = 1;
} else if (!strcmp(p, "console")) {
s->pe_subsystem = 3;
} else if (!strcmp(p, "gui")) {
s->pe_subsystem = 2;
} else if (!strcmp(p, "posix")) {
s->pe_subsystem = 7;
} else if (!strcmp(p, "efiapp")) {
s->pe_subsystem = 10;
} else if (!strcmp(p, "efiboot")) {
s->pe_subsystem = 11;
} else if (!strcmp(p, "efiruntime")) {
s->pe_subsystem = 12;
} else if (!strcmp(p, "efirom")) {
s->pe_subsystem = 13;
#elif defined(TCC_TARGET_ARM)
if (!strcmp(p, "wince")) {
s->pe_subsystem = 9;
#endif
} else
goto err;
#endif
} else if (ret = link_option(option, "?whole-archive", &p), ret) {
s->alacarte_link = ret < 0;
} else if (p) {
return 0;
} else {
err:
tcc_error("unsupported linker option '%s'", option);
}
if (ignoring && s->warn_unsupported)
tcc_warning("unsupported linker option '%s'", option);
option = skip_linker_arg(&p);
}
return 1;
}
src/libtcc.c view on Meta::CPAN
if (!strstart(p1, &r1))
continue;
optarg = r1;
if (popt->flags & TCC_OPTION_HAS_ARG) {
if (*r1 == '\0' && !(popt->flags & TCC_OPTION_NOSEP)) {
if (optind >= argc)
arg_err:
tcc_error("argument to '%s' is missing", r);
optarg = argv[optind++];
}
} else if (*r1 != '\0')
continue;
break;
}
switch(popt->index) {
case TCC_OPTION_HELP:
return 0;
case TCC_OPTION_I:
tcc_add_include_path(s, optarg);
break;
case TCC_OPTION_D:
parse_option_D(s, optarg);
break;
case TCC_OPTION_U:
tcc_undefine_symbol(s, optarg);
break;
case TCC_OPTION_L:
tcc_add_library_path(s, optarg);
break;
case TCC_OPTION_B:
/* set tcc utilities path (mainly for tcc development) */
tcc_set_lib_path(s, optarg);
break;
case TCC_OPTION_l:
args_parser_add_file(s, optarg, AFF_TYPE_LIBWH - s->alacarte_link);
s->nb_libraries++;
break;
case TCC_OPTION_pthread:
parse_option_D(s, "_REENTRANT");
s->option_pthread = 1;
break;
case TCC_OPTION_bench:
s->do_bench = 1;
break;
#ifdef CONFIG_TCC_BACKTRACE
case TCC_OPTION_bt:
tcc_set_num_callers(atoi(optarg));
break;
#endif
#ifdef CONFIG_TCC_BCHECK
case TCC_OPTION_b:
s->do_bounds_check = 1;
s->do_debug = 1;
break;
#endif
case TCC_OPTION_g:
s->do_debug = 1;
break;
case TCC_OPTION_c:
x = TCC_OUTPUT_OBJ;
set_output_type:
if (s->output_type)
tcc_warning("-%s: overriding compiler action already specified", popt->name);
s->output_type = x;
break;
case TCC_OPTION_d:
if (*optarg == 'D')
s->dflag = 3;
else if (*optarg == 'M')
s->dflag = 7;
else
goto unsupported_option;
break;
#ifdef TCC_TARGET_ARM
case TCC_OPTION_float_abi:
/* tcc doesn't support soft float yet */
if (!strcmp(optarg, "softfp")) {
s->float_abi = ARM_SOFTFP_FLOAT;
tcc_undefine_symbol(s, "__ARM_PCS_VFP");
} else if (!strcmp(optarg, "hard"))
s->float_abi = ARM_HARD_FLOAT;
else
tcc_error("unsupported float abi '%s'", optarg);
break;
#endif
case TCC_OPTION_static:
s->static_link = 1;
break;
case TCC_OPTION_std:
/* silently ignore, a current purpose:
allow to use a tcc as a reference compiler for "make test" */
break;
case TCC_OPTION_shared:
x = TCC_OUTPUT_DLL;
goto set_output_type;
case TCC_OPTION_soname:
s->soname = tcc_strdup(optarg);
break;
case TCC_OPTION_m:
s->option_m = tcc_strdup(optarg);
break;
case TCC_OPTION_o:
if (s->outfile) {
tcc_warning("multiple -o option");
tcc_free(s->outfile);
}
s->outfile = tcc_strdup(optarg);
break;
case TCC_OPTION_r:
/* generate a .o merging several output files */
s->option_r = 1;
x = TCC_OUTPUT_OBJ;
goto set_output_type;
case TCC_OPTION_isystem:
tcc_add_sysinclude_path(s, optarg);
break;
case TCC_OPTION_iwithprefix:
snprintf(buf, sizeof buf, "{B}/%s", optarg);
tcc_add_sysinclude_path(s, buf);
break;
case TCC_OPTION_nostdinc:
s->nostdinc = 1;
break;
case TCC_OPTION_nostdlib:
s->nostdlib = 1;
break;
case TCC_OPTION_print_search_dirs:
s->print_search_dirs = 1;
break;
case TCC_OPTION_run:
#ifndef TCC_IS_NATIVE
tcc_error("-run is not available in a cross compiler");
#endif
tcc_set_options(s, optarg);
run = 1;
x = TCC_OUTPUT_MEMORY;
goto set_output_type;
case TCC_OPTION_v:
do ++s->verbose; while (*optarg++ == 'v');
break;
case TCC_OPTION_f:
if (tcc_set_flag(s, optarg, 1) < 0)
goto unsupported_option;
break;
case TCC_OPTION_W:
if (tcc_set_warning(s, optarg, 1) < 0)
goto unsupported_option;
break;
case TCC_OPTION_w:
s->warn_none = 1;
break;
case TCC_OPTION_rdynamic:
s->rdynamic = 1;
break;
case TCC_OPTION_Wl:
if (linker_arg.size)
--linker_arg.size, cstr_ccat(&linker_arg, ',');
cstr_cat(&linker_arg, optarg, 0);
if (tcc_set_linker(s, linker_arg.data))
cstr_free(&linker_arg);
break;
case TCC_OPTION_E:
x = TCC_OUTPUT_PREPROCESS;
goto set_output_type;
case TCC_OPTION_P:
s->Pflag = atoi(optarg) + 1;
break;
case TCC_OPTION_MD:
s->gen_deps = 1;
break;
case TCC_OPTION_MF:
s->deps_outfile = tcc_strdup(optarg);
break;
/* #ifdef CONFIG_TCC_EXSYMTAB */
case TCC_OPTION_serialize_symtab:
s->symtab_serialize_outfile = tcc_strdup(optarg + 1);
s->exsymtab = (extended_symtab*)1;
break;
case TCC_OPTION_dump_identifier_names:
s->dump_identifier_names_outfile = tcc_strdup(optarg + 1);
s->exsymtab = (extended_symtab*)1;
break;
/* #endif */
case TCC_OPTION_dumpversion:
printf ("%s\n", TCC_VERSION);
exit(0);
break;
case TCC_OPTION_x:
if (*optarg == 'c')
s->filetype = AFF_TYPE_C;
else if (*optarg == 'a')
s->filetype = AFF_TYPE_ASMPP;
else if (*optarg == 'n')
s->filetype = AFF_TYPE_NONE;
else
tcc_warning("unsupported language '%s'", optarg);
break;
case TCC_OPTION_O:
x = atoi(optarg);
if (x > 0)
tcc_define_symbol(s, "__OPTIMIZE__", NULL);
break;
case TCC_OPTION_mms_bitfields:
s->ms_bitfields = 1;
break;
case TCC_OPTION_traditional:
case TCC_OPTION_pedantic:
case TCC_OPTION_pipe:
case TCC_OPTION_s:
/* ignored */
break;
default:
unsupported_option:
if (s->warn_unsupported)
tcc_warning("unsupported option '%s'", r);
break;
}
}
if (linker_arg.size) {
r = linker_arg.data;
goto arg_err;
}
( run in 0.975 second using v1.01-cache-2.11-cpan-5623c5533a1 )