libtcc: Allow multiple options for -Wl separated with ','
I moved the code to libtcc to prepare for a later tiny_ld -- By by ... Detlef
This commit is contained in:
111
libtcc.c
111
libtcc.c
@ -1394,6 +1394,117 @@ PUB_FUNC int tcc_set_flag(TCCState *s, const char *flag_name, int value)
|
|||||||
flag_name, 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)
|
PUB_FUNC void tcc_print_stats(TCCState *s, int64_t total_time)
|
||||||
{
|
{
|
||||||
double tt;
|
double tt;
|
||||||
|
|||||||
3
libtcc.h
3
libtcc.h
@ -31,6 +31,9 @@ LIBTCCAPI void tcc_set_error_func(TCCState *s, void *error_opaque,
|
|||||||
/* set/reset a warning */
|
/* set/reset a warning */
|
||||||
LIBTCCAPI int tcc_set_warning(TCCState *s, const char *warning_name, int value);
|
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 */
|
/* preprocessor */
|
||||||
|
|
||||||
|
|||||||
85
tcc.c
85
tcc.c
@ -171,22 +171,6 @@ static int64_t getclock_us(void)
|
|||||||
#endif
|
#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 */
|
/* convert 'str' into an array of space separated strings */
|
||||||
static int expand_args(char ***pargv, const char *str)
|
static int expand_args(char ***pargv, const char *str)
|
||||||
{
|
{
|
||||||
@ -383,73 +367,8 @@ static int parse_args(TCCState *s, int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case TCC_OPTION_Wl:
|
case TCC_OPTION_Wl:
|
||||||
{
|
{
|
||||||
const char *p;
|
if ((r = (char *)tcc_set_linker(s, optarg, TRUE)))
|
||||||
if (strstart(optarg, "-Ttext,", &p)) {
|
error("unsupported linker option '%s'", r);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TCC_OPTION_E:
|
case TCC_OPTION_E:
|
||||||
|
|||||||
Reference in New Issue
Block a user