On 11/25/23 17:57, Warner Losh wrote:
Greetings,

It would appear that tcc doesn't support .symver assembler directive. FreeBSD uses it for the __sym_compat macro invocation for an old qsort interface:

#if defined(__generic) || defined(__cplusplus)
void __qsort_r_compat(void *, size_t, size_t, void *,
            int (*)(void *, const void *, const void *));
__sym_compat(qsort_r, __qsort_r_compat, FBSD_1.0);
#endif

Where __sym_compat is defined in cdefs.h:
#define __sym_compat(sym,impl,verid)    \
        __asm__(".symver " #impl ", " #sym "@" #verid)

I get this error when building tcc:
/usr/include/stdlib.h:353: error: unknown opcode '.symver'
(which corresponds to the line the above appears at).

If I have this code in cdefs.h:

#ifdef __TINYC__
#define __sym_compat(a,b,c)
#else
/* The above define */
#endif

That solves the problem. Since I have a FreeBSD commit access, I can easily fix this. In fact, I'm going through FreeBSD's cdefs.h trying to clean things up. I'd like to not break tcc, but it looks like it's starting out broken and I'd like to fix that as part of this... The above hack is the 'obvious' fix, but I thought I'd ask here to see if the wisdom of this crowd exceeds my quick and dirty somewhat ugly hack.

Running the tests, btw, shows things are close, but not quite right. Two tests are failing:
Test: 108_constructor...
Test: 126_bound_global...

Above problems are introduced with FreeBSD 14. FreeBSD 13 is just fine.

I did some debugging and implemented a small fix for the symvar problem. See attached patch. If I use the /usr/lib/crt1.o from FreeBSD 13 on FreeBSD 14 everything works again.

    Herman
diff --git a/tccasm.c b/tccasm.c
index fcae05eb..bed03199 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -918,6 +918,15 @@ static void asm_parse_directive(TCCState *s1, int global)
         next();
         break;
 #endif
+    /* TODO: Implement symvar support. FreeBSD 14 needs this */
+    case TOK_ASMDIR_symver:
+       next();
+       next();
+        skip(',');
+       next();
+        skip('@');
+       next();
+       break;
     default:
         tcc_error("unknown assembler directive '.%s'", get_tok_str(tok, NULL));
         break;
diff --git a/tcctok.h b/tcctok.h
index cfdc60dc..8f1315c1 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -405,6 +405,7 @@
  DEF_ASMDIR(short)
  DEF_ASMDIR(long)
  DEF_ASMDIR(int)
+ DEF_ASMDIR(symver)
  DEF_ASMDIR(section)    /* must be last directive */
 
 #if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
_______________________________________________
Tinycc-devel mailing list
Tinycc-devel@nongnu.org
https://lists.nongnu.org/mailman/listinfo/tinycc-devel

Reply via email to