From f150f93854a10f1e02d701c73126035a069d3e54 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Tue, 17 Dec 2019 17:54:54 +0100 Subject: [PATCH] Fix the get_asm_string fail on i386 in another way the problem is that new debian GCC enabled -fPIC or -fPIE by default, causing the mentioned compile error. --- tests/Makefile | 5 +++++ tests/tcctest.c | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/tests/Makefile b/tests/Makefile index b3aaea8..034ddc1 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -64,6 +64,11 @@ ifeq ($(ARCH),arm) # of functions via bit masking comes out as 1. Just disable thumb. test.ref: CFLAGS+=-marm endif +ifeq ($(ARCH),i386) +# tcctest.c:get_asm_string uses a construct that is checked too strictly +# by GCC in 32bit mode when PIC is enabled. +test.ref: CFLAGS+=-fno-PIC -fno-PIE +endif RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) DISAS = objdump -d diff --git a/tests/tcctest.c b/tests/tcctest.c index 7f8ebfb..374ecc2 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -3320,12 +3320,20 @@ void override_func2 (void) extern int bug_table[] __attribute__((section("__bug_table"))); char * get_asm_string (void) { -#ifdef __i386__ - /* i386 is not currently tested because this code triggers a gcc - bug on some distributions. See - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=946678 */ - char *str = "(not tested)"; -#else + /* On i386 when -fPIC is enabled this would cause a compile error with GCC, + the problem being the "i" constraint used with a symbolic operand + resolving to a local label. That check is overly zealous as the code + within the asm makes sure to use it only in PIC-possible contexts, + but all GCC versions behave like so. We arrange for PIC to be disabled + for compiling tcctest.c in the Makefile. + + Additionally the usage of 'c' in "%c0" in the template is actually wrong, + as that would expect an operand that is a condition code. The operand + as is (a local label) is accepted by GCC in non-PIC mode, and on x86-64. + What the linux kernel really wanted is 'p' to disable the addition of '$' + to the printed operand (as in "$.LC0" where the template only wants the + bare operand ".LC0"). But the code below is what the linux kernel + happens to use and as such is the one we want to test. */ extern int some_symbol; asm volatile (".globl some_symbol\n" "jmp .+6\n" @@ -3340,7 +3348,6 @@ char * get_asm_string (void) "2:\t.long 1b - 2b, %c0 - 2b\n" ".popsection\n" : : "i" ("A string")); char * str = ((char*)bug_table) + bug_table[1]; -#endif return str; }