From 78e83d8761afb792f1a848ade7e1f97a21283a5e Mon Sep 17 00:00:00 2001 From: Detlef Riekenberg Date: Mon, 5 Apr 2010 21:21:58 +0200 Subject: [PATCH] libtcc: Allow multiple options for -Wl separated with ',' I moved the code to libtcc to prepare for a later tiny_ld -- By by ... Detlef --- libtcc.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ libtcc.h | 3 ++ tcc.c | 85 +----------------------------------------- 3 files changed, 116 insertions(+), 83 deletions(-) diff --git a/libtcc.c b/libtcc.c index 396ba77c..32f2f812 100644 --- a/libtcc.c +++ b/libtcc.c @@ -1394,6 +1394,117 @@ PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value) flag_name, value); } + +static int strstart(const char *str, const char *val, const char **ptr) +{ + const char *p, *q; + p = str; + q = val; + while (*q != '\0') { + if (*p != *q) + return 0; + p++; + q++; + } + if (ptr) + *ptr = p; + return 1; +} + +/* set linker options */ +PUB_FUNC const char * tcc_set_linker(TCCState *s, const char *option, int multi) +{ + const char *p = option; + char *end = NULL; + + while (option && *option) { + + if (strstart(option, "-Bsymbolic", &p)) { + s->symbolic = TRUE; +#ifdef TCC_TARGET_PE + } else if (strstart(option, "--file-alignment,", &p)) { + s->pe_file_align = strtoul(p, &end, 16); +#endif + } else if (strstart(option, "--image-base,", &p)) { + s->text_addr = strtoul(p, &end, 16); + s->has_text_addr = 1; + + } else if (strstart(option, "--oformat,", &p)) { +#if defined(TCC_TARGET_PE) + if (strstart(p, "pe-", NULL)) { +#else +#if defined(TCC_TARGET_X86_64) + if (strstart(p, "elf64-", NULL)) { +#else + if (strstart(p, "elf32-", NULL)) { +#endif +#endif + s->output_format = TCC_OUTPUT_FORMAT_ELF; + } else if (!strcmp(p, "binary")) { + s->output_format = TCC_OUTPUT_FORMAT_BINARY; + } else +#ifdef TCC_TARGET_COFF + if (!strcmp(p, "coff")) { + s->output_format = TCC_OUTPUT_FORMAT_COFF; + } else +#endif + { + return p; + } + + } else if (strstart(option, "-rpath=", &p)) { + s->rpath = p; + } else if (strstart(option, "--section-alignment,", &p)) { + s->section_align = strtoul(p, &end, 16); +#ifdef TCC_TARGET_PE + } else if (strstart(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 { + return p; + } +#endif + + } else if (strstart(option, "-Ttext,", &p)) { + s->text_addr = strtoul(p, &end, 16); + s->has_text_addr = 1; + + } else { + return option; + } + + if (multi) { + if (end) { + option = end; + } else { + option = strchr(p, ','); + if (option) option++; + } + } else + option = NULL; + } + return NULL; +} + PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time) { double tt; diff --git a/libtcc.h b/libtcc.h index b661fda7..c25ab0fb 100644 --- a/libtcc.h +++ b/libtcc.h @@ -31,6 +31,9 @@ LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque, /* set/reset a warning */ LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value); +/* set linker option */ +LIBTCCAPI const char * tcc_set_linker(TCCState *s, const char *option, int multi); + /*****************************/ /* preprocessor */ diff --git a/tcc.c b/tcc.c index 418c2ec4..06537735 100644 --- a/tcc.c +++ b/tcc.c @@ -171,22 +171,6 @@ static int64_t getclock_us(void) #endif } -static int strstart(const char *str, const char *val, const char **ptr) -{ - const char *p, *q; - p = str; - q = val; - while (*q != '\0') { - if (*p != *q) - return 0; - p++; - q++; - } - if (ptr) - *ptr = p; - return 1; -} - /* convert 'str' into an array of space separated strings */ static int expand_args(char ***pargv, const char *str) { @@ -383,73 +367,8 @@ static int parse_args(TCCState *s, int argc, char **argv) break; case TCC_OPTION_Wl: { - const char *p; - if (strstart(optarg, "-Ttext,", &p)) { - s->text_addr = strtoul(p, NULL, 16); - s->has_text_addr = 1; - } else if (strstart(optarg, "-Bsymbolic", &p)) { - s->symbolic = TRUE; - } else if (strstart(optarg, "--section-alignment,", &p)) { - s->section_align = strtoul(p, NULL, 16); - } else if (strstart(optarg, "--image-base,", &p)) { - s->text_addr = strtoul(p, NULL, 16); - s->has_text_addr = 1; -#ifdef TCC_TARGET_PE - } else if (strstart(optarg, "--file-alignment,", &p)) { - s->pe_file_align = strtoul(p, NULL, 16); - } else if (strstart(optarg, "--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 { - error("invalid subsystem '%s'", p); - } -#endif - } else if (strstart(optarg, "--oformat,", &p)) { -#if defined(TCC_TARGET_PE) - if (strstart(p, "pe-", NULL)) { -#else -#if defined(TCC_TARGET_X86_64) - if (strstart(p, "elf64-", NULL)) { -#else - if (strstart(p, "elf32-", NULL)) { -#endif -#endif - s->output_format = TCC_OUTPUT_FORMAT_ELF; - } else if (!strcmp(p, "binary")) { - s->output_format = TCC_OUTPUT_FORMAT_BINARY; - } else -#ifdef TCC_TARGET_COFF - if (!strcmp(p, "coff")) { - s->output_format = TCC_OUTPUT_FORMAT_COFF; - } else -#endif - { - error("target %s not found", p); - } - } else if (strstart(optarg, "-rpath=", &p)) { - s->rpath = p; - } else { - error("unsupported linker option '%s'", optarg); - } + if ((r = (char *)tcc_set_linker(s, optarg, TRUE))) + error("unsupported linker option '%s'", r); } break; case TCC_OPTION_E: