diff --git a/src/autodetection.c b/src/autodetection.c index f96bc06..5638740 100644 --- a/src/autodetection.c +++ b/src/autodetection.c @@ -1,6 +1,14 @@ #include "libblastrampoline_internal.h" #include +// Declarations for the self-symbols in LBT that we use for our symbol suffix detection +extern void ** isamax_; +extern void ** isamax_64_; +extern void ** dpotrf_; +extern void ** dpotrf_64_; +extern void ** cblas_zdotc_sub; +extern void ** cblas_zdotc_sub64_; + /* * Some vendors (such as Accelerate) decided to trim off the trailing underscore * from the F77 symbol names when adding their ILP64 symbol names. So the @@ -25,10 +33,16 @@ void build_symbol_name(char * out, const char *symbol_name, const char *suffix) strncpy(out + symbol_len, suffix, MAX_SYMBOL_LEN - symbol_len); } +typedef struct { + const char * symbol_name; + const void ** self_lp64_addr; + const void ** self_ilp64_addr; +} autodetect_symbol_info_t; + /* * Search for a symbol that ends in one of the given suffixes. Returns NULL if not found. */ -const char * symbol_suffix_search(void * handle, const char * symbol_name, const char ** suffixes, const int num_suffixes) { +const char * symbol_suffix_search(void * handle, autodetect_symbol_info_t* symbol, const char ** suffixes, const int num_suffixes) { char symbol_name_suffixed[MAX_SYMBOL_LEN]; for (int suffix_idx=0; suffix_idxsymbol_name, suffixes[suffix_idx]); + + void* sym = lookup_symbol(handle, symbol_name_suffixed); + + // Make sure we haven't found our symbol from LBT by accident (since lookup_symbol on Linux will + // search dependencies of the library we are loading as well). + if ((sym != NULL) && (sym != symbol->self_ilp64_addr) && (sym != symbol->self_lp64_addr)) { return suffixes[suffix_idx]; } } @@ -52,11 +71,16 @@ const char * symbol_suffix_search(void * handle, const char * symbol_name, const const char * autodetect_symbol_suffix(void * handle, const char * suffix_hint) { // We auto-detect the symbol suffix of the given library by searching for common // BLAS and LAPACK symbols, combined with various suffixes that we know of. - const char * symbol_names[] = { + + // We need to store the symbol addresses we expose for the symbol names we use - to ensure + // we don't accidentally detect any of our own symbols (such as when doing autodetection on + // a LAPACK library compiled with LBT as it's BLAS backend, where dlsym will search the entire + // dependency tree for a symbol, including us). + autodetect_symbol_info_t symbols[] = { // fortran BLAS symbol - "isamax_", + {"isamax_", (const void **)&isamax_, (const void **)&isamax_64_}, // fortran LAPACK symbol - "dpotrf_", + {"dpotrf_", (const void **)&dpotrf_, (const void **)&dpotrf_64_,} }; const char * suffixes[] = { // Possibly-NULL suffix that we should search over @@ -82,8 +106,8 @@ const char * autodetect_symbol_suffix(void * handle, const char * suffix_hint) { }; // If the suffix hint is NULL, just skip it when calling `lookup_symbol()`. - for (int symbol_idx=0; symbol_idx