From a8ece0f2ce3d2c2471fc8ddb7109938ecec333f7 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Thu, 16 Nov 2017 13:29:59 +0100 Subject: [PATCH] Don't make forard asm symbols static by default fixes the problem in the testcase. A symbolic reference from asm, which remains undefined at the end of processing is always a global reference, not a static (STB_LOCAL) one. This also affected the linux kernel. --- tccasm.c | 2 -- tests/tcctest.c | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/tccasm.c b/tccasm.c index ac1618a..1e20dc6 100644 --- a/tccasm.c +++ b/tccasm.c @@ -75,8 +75,6 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym) sym->type.t &= ~VT_EXTERN; /* Mark that this asm symbol doesn't need to be fed back. */ sym->a.dllimport = 1; - } else { - sym->type.t |= VT_STATIC; } } return sym; diff --git a/tests/tcctest.c b/tests/tcctest.c index 099fc35..d6fb7e2 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -3345,6 +3345,25 @@ void test_asm_dead_code(void) })); } +void test_asm_call(void) +{ +#if defined __x86_64__ && !defined _WIN64 + static char str[] = "PATH"; + char *s; + /* This tests if a reference to an undefined symbol from an asm + block, which isn't otherwise referenced in this file, is correctly + regarded as global symbol, so that it's resolved by other object files + or libraries. We chose getenv here, which isn't used anywhere else + in this file. (If we used e.g. printf, which is used we already + would have a global symbol entry, not triggering the bug which is + tested here). */ + /* two pushes so stack remains aligned */ + asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi; call getenv; pop %%rdi; pop %%rdi" + : "=a" (s) : "r" (str)); + printf("asmd: %s\n", s); +#endif +} + void asm_test(void) { char buf[128]; @@ -3431,6 +3450,7 @@ void asm_test(void) test_high_clobbers(); trace_console(8, 8); test_asm_dead_code(); + test_asm_call(); return; label1: goto label2;