@@ -4176,7 +4176,11 @@ static bool dsl_jit_get_cache_dir(char *out, size_t out_size) {
41764176 }
41774177 const char * tmpdir = getenv ("TMPDIR" );
41784178 if (!tmpdir || tmpdir [0 ] == '\0' ) {
4179- tmpdir = "/tmp" ;
4179+ /* Avoid cross-user permission conflicts when TMPDIR is not set. */
4180+ if (snprintf (out , out_size , "/tmp/miniexpr-jit-%lu" , (unsigned long )getuid ()) >= (int )out_size ) {
4181+ return false;
4182+ }
4183+ return dsl_jit_ensure_dir (out );
41804184 }
41814185 if (snprintf (out , out_size , "%s/miniexpr-jit" , tmpdir ) >= (int )out_size ) {
41824186 return false;
@@ -4322,6 +4326,7 @@ typedef int (*me_tcc_compile_string_fn)(me_tcc_state *s, const char *buf);
43224326typedef int (* me_tcc_relocate_fn )(me_tcc_state * s );
43234327typedef void * (* me_tcc_get_symbol_fn )(me_tcc_state * s , const char * name );
43244328typedef int (* me_tcc_set_options_fn )(me_tcc_state * s , const char * str );
4329+ typedef int (* me_tcc_add_library_path_fn )(me_tcc_state * s , const char * path );
43254330typedef int (* me_tcc_add_library_fn )(me_tcc_state * s , const char * libraryname );
43264331typedef int (* me_tcc_add_symbol_fn )(me_tcc_state * s , const char * name , const void * val );
43274332typedef void (* me_tcc_set_lib_path_fn )(me_tcc_state * s , const char * path );
@@ -4337,6 +4342,7 @@ typedef struct {
43374342 me_tcc_relocate_fn tcc_relocate_fn ;
43384343 me_tcc_get_symbol_fn tcc_get_symbol_fn ;
43394344 me_tcc_set_options_fn tcc_set_options_fn ;
4345+ me_tcc_add_library_path_fn tcc_add_library_path_fn ;
43404346 me_tcc_add_library_fn tcc_add_library_fn ;
43414347 me_tcc_add_symbol_fn tcc_add_symbol_fn ;
43424348 me_tcc_set_lib_path_fn tcc_set_lib_path_fn ;
@@ -4514,6 +4520,49 @@ static bool dsl_jit_libtcc_runtime_dir(char *out, size_t out_size) {
45144520 return dsl_jit_path_dirname (module_path , out , out_size );
45154521}
45164522
4523+ static void dsl_jit_libtcc_add_library_path_if_exists (me_tcc_state * state , const char * path ) {
4524+ if (!state || !g_dsl_tcc_api .tcc_add_library_path_fn || !path || path [0 ] == '\0' ) {
4525+ return ;
4526+ }
4527+ struct stat st ;
4528+ if (stat (path , & st ) == 0 && S_ISDIR (st .st_mode )) {
4529+ (void )g_dsl_tcc_api .tcc_add_library_path_fn (state , path );
4530+ }
4531+ }
4532+
4533+ static void dsl_jit_libtcc_add_multiarch_paths (me_tcc_state * state ) {
4534+ #if defined(__linux__ )
4535+ if (!state || !g_dsl_tcc_api .tcc_add_library_path_fn ) {
4536+ return ;
4537+ }
4538+ const char * paths [] = {
4539+ #if defined(__x86_64__ ) || defined(__amd64__ )
4540+ "/usr/lib/x86_64-linux-gnu" , "/lib/x86_64-linux-gnu" ,
4541+ #elif defined(__aarch64__ )
4542+ "/usr/lib/aarch64-linux-gnu" , "/lib/aarch64-linux-gnu" ,
4543+ #elif defined(__arm__ )
4544+ "/usr/lib/arm-linux-gnueabihf" , "/lib/arm-linux-gnueabihf" ,
4545+ "/usr/lib/arm-linux-gnueabi" , "/lib/arm-linux-gnueabi" ,
4546+ #elif defined(__riscv ) && (__riscv_xlen == 64 )
4547+ "/usr/lib/riscv64-linux-gnu" , "/lib/riscv64-linux-gnu" ,
4548+ #elif defined(__powerpc64__ ) && defined(__LITTLE_ENDIAN__ )
4549+ "/usr/lib/powerpc64le-linux-gnu" , "/lib/powerpc64le-linux-gnu" ,
4550+ #elif defined(__s390x__ )
4551+ "/usr/lib/s390x-linux-gnu" , "/lib/s390x-linux-gnu" ,
4552+ #elif defined(__i386__ )
4553+ "/usr/lib/i386-linux-gnu" , "/lib/i386-linux-gnu" ,
4554+ #endif
4555+ "/usr/lib64" , "/lib64" ,
4556+ NULL
4557+ };
4558+ for (int i = 0 ; paths [i ]; i ++ ) {
4559+ dsl_jit_libtcc_add_library_path_if_exists (state , paths [i ]);
4560+ }
4561+ #else
4562+ (void )state ;
4563+ #endif
4564+ }
4565+
45174566static double dsl_jit_bridge_apply_unary_f64 (void (* fn )(const double * , double * , int ), double x ) {
45184567 double in_buf [1 ];
45194568 double out_buf [1 ];
@@ -5392,6 +5441,7 @@ static bool dsl_jit_libtcc_load_api(void) {
53925441#undef ME_LOAD_TCC_SYM
53935442
53945443 g_dsl_tcc_api .tcc_set_options_fn = (me_tcc_set_options_fn )dsl_jit_dynlib_symbol (handle , "tcc_set_options" );
5444+ g_dsl_tcc_api .tcc_add_library_path_fn = (me_tcc_add_library_path_fn )dsl_jit_dynlib_symbol (handle , "tcc_add_library_path" );
53955445 g_dsl_tcc_api .tcc_add_library_fn = (me_tcc_add_library_fn )dsl_jit_dynlib_symbol (handle , "tcc_add_library" );
53965446 g_dsl_tcc_api .tcc_add_symbol_fn = (me_tcc_add_symbol_fn )dsl_jit_dynlib_symbol (handle , "tcc_add_symbol" );
53975447 g_dsl_tcc_api .tcc_set_lib_path_fn = (me_tcc_set_lib_path_fn )dsl_jit_dynlib_symbol (handle , "tcc_set_lib_path" );
@@ -5446,6 +5496,7 @@ static bool dsl_jit_compile_libtcc_in_memory(me_dsl_compiled_program *program) {
54465496 "tcc_set_output_type failed" );
54475497 return false;
54485498 }
5499+ dsl_jit_libtcc_add_multiarch_paths (state );
54495500#if !defined(__APPLE__ ) && !defined(_WIN32 ) && !defined(_WIN64 )
54505501 if (g_dsl_tcc_api .tcc_add_library_fn ) {
54515502 (void )g_dsl_tcc_api .tcc_add_library_fn (state , "m" );
@@ -5563,6 +5614,59 @@ static bool dsl_jit_cc_math_bridge_available(void) {
55635614#endif
55645615}
55655616
5617+ static void dsl_jit_cc_add_library_flag_if_exists (char * flags , size_t flags_size , const char * path ) {
5618+ if (!flags || flags_size == 0 || !path || path [0 ] == '\0' ) {
5619+ return ;
5620+ }
5621+ struct stat st ;
5622+ if (stat (path , & st ) != 0 || !S_ISDIR (st .st_mode )) {
5623+ return ;
5624+ }
5625+ size_t len = strlen (flags );
5626+ if (len >= flags_size - 1 ) {
5627+ return ;
5628+ }
5629+ int n = snprintf (flags + len , flags_size - len , " -L%s" , path );
5630+ if (n <= 0 || (size_t )n >= (flags_size - len )) {
5631+ flags [flags_size - 1 ] = '\0' ;
5632+ }
5633+ }
5634+
5635+ static void dsl_jit_cc_add_multiarch_library_flags (char * flags , size_t flags_size ) {
5636+ if (!flags || flags_size == 0 ) {
5637+ return ;
5638+ }
5639+ flags [0 ] = '\0' ;
5640+ #if defined(__linux__ )
5641+ /* Match libtcc fallback dirs so cc JIT can resolve -lm on multiarch layouts. */
5642+ const char * paths [] = {
5643+ #if defined(__x86_64__ ) || defined(__amd64__ )
5644+ "/usr/lib/x86_64-linux-gnu" , "/lib/x86_64-linux-gnu" ,
5645+ #elif defined(__aarch64__ )
5646+ "/usr/lib/aarch64-linux-gnu" , "/lib/aarch64-linux-gnu" ,
5647+ #elif defined(__arm__ )
5648+ "/usr/lib/arm-linux-gnueabihf" , "/lib/arm-linux-gnueabihf" ,
5649+ "/usr/lib/arm-linux-gnueabi" , "/lib/arm-linux-gnueabi" ,
5650+ #elif defined(__riscv ) && (__riscv_xlen == 64 )
5651+ "/usr/lib/riscv64-linux-gnu" , "/lib/riscv64-linux-gnu" ,
5652+ #elif defined(__powerpc64__ ) && defined(__LITTLE_ENDIAN__ )
5653+ "/usr/lib/powerpc64le-linux-gnu" , "/lib/powerpc64le-linux-gnu" ,
5654+ #elif defined(__s390x__ )
5655+ "/usr/lib/s390x-linux-gnu" , "/lib/s390x-linux-gnu" ,
5656+ #elif defined(__i386__ )
5657+ "/usr/lib/i386-linux-gnu" , "/lib/i386-linux-gnu" ,
5658+ #endif
5659+ "/usr/lib64" , "/lib64" ,
5660+ NULL
5661+ };
5662+ for (int i = 0 ; paths [i ]; i ++ ) {
5663+ dsl_jit_cc_add_library_flag_if_exists (flags , flags_size , paths [i ]);
5664+ }
5665+ #else
5666+ (void )flags_size ;
5667+ #endif
5668+ }
5669+
55665670static bool dsl_jit_compile_shared (const me_dsl_compiled_program * program ,
55675671 const char * src_path , const char * so_path ) {
55685672 if (!program || !src_path || !so_path ) {
@@ -5583,21 +5687,28 @@ static bool dsl_jit_compile_shared(const me_dsl_compiled_program *program,
55835687 const char * debug_cc = getenv ("ME_DSL_JIT_DEBUG_CC" );
55845688 bool show_cc_output = (debug_cc && debug_cc [0 ] != '\0' && strcmp (debug_cc , "0" ) != 0 );
55855689 const char * bridge_ldflags = "" ;
5690+ char multiarch_ldflags [512 ];
5691+ const char * math_ldflags = "" ;
5692+ dsl_jit_cc_add_multiarch_library_flags (multiarch_ldflags , sizeof (multiarch_ldflags ));
55865693#if defined(__APPLE__ )
55875694 if (program -> jit_use_runtime_math_bridge ) {
55885695 bridge_ldflags = " -Wl,-undefined,dynamic_lookup" ;
55895696 }
5697+ #elif !defined(_WIN32 ) && !defined(_WIN64 )
5698+ math_ldflags = " -lm" ;
55905699#endif
55915700 char cmd [2048 ];
55925701#if defined(__APPLE__ )
55935702 int n = snprintf (cmd , sizeof (cmd ),
5594- "%s -std=c99 -O3 -fPIC %s %s -dynamiclib -o \"%s\" \"%s\"%s%s" ,
5703+ "%s -std=c99 -O3 -fPIC %s %s -dynamiclib -o \"%s\" \"%s\"%s%s%s%s " ,
55955704 cc , fp_cflags , cflags , so_path , src_path , bridge_ldflags ,
5705+ multiarch_ldflags , math_ldflags ,
55965706 show_cc_output ? "" : " >/dev/null 2>&1" );
55975707#else
55985708 int n = snprintf (cmd , sizeof (cmd ),
5599- "%s -std=c99 -O3 -fPIC %s %s -shared -o \"%s\" \"%s\"%s%s" ,
5709+ "%s -std=c99 -O3 -fPIC %s %s -shared -o \"%s\" \"%s\"%s%s%s%s " ,
56005710 cc , fp_cflags , cflags , so_path , src_path , bridge_ldflags ,
5711+ multiarch_ldflags , math_ldflags ,
56015712 show_cc_output ? "" : " >/dev/null 2>&1" );
56025713#endif
56035714 if (n <= 0 || (size_t )n >= sizeof (cmd )) {
0 commit comments