@@ -174,7 +174,18 @@ static char *get_origin() {
174174}
175175#endif
176176
177- #if defined(__linux__ )
177+ /*
178+ * Glibc, Musl and Soloris support RTLD_DI_LINKMAP.
179+ * Musl hate the vendor detect macro and refuse to support __musl__.
180+ * They think we should test feature instead of detect vendor, it's normally right,
181+ * but for dlinfo(3), it's almost impossible because dlinfo has no errno or similar thing,
182+ * there is dlerror(3), right? No! dlerror(3) can only return a implementation-defined error string
183+ * (In C term, it should be called unspecified behavior because libc implementation needn't have
184+ * documentation for it) instead of an integer which we can compare it with specific value
185+ * programmatically. So we can't test this feature is available, we can only assume there is only
186+ * Glibc and Musl on Linux, forget Nolibc and other libc implementations on Linux.
187+ */
188+ #if defined(__GLIBC__ ) || defined(__linux__ ) || (defined(__sun ) && defined(__SVR4 ))
178189static const char * get_runpath () {
179190 void * handle = dlopen (NULL , RTLD_NOW );
180191 if (handle == NULL ) {
@@ -194,18 +205,18 @@ static const char *get_runpath() {
194205 } else if (dyn -> d_tag == DT_RUNPATH ) {
195206 runpath = dyn ;
196207 } else if (dyn -> d_tag == DT_STRTAB ) {
197- strtab = (const char * )dyn -> d_un .d_val ;
208+ strtab = (const char * )dyn -> d_un .d_ptr ;
198209 }
199210 }
200- if (runpath ) {
211+ if (runpath != NULL && strtab != NULL ) {
201212 return strtab + runpath -> d_un .d_val ;
202213 } else {
203214 return NULL ;
204215 }
205216}
206217
207218#else
208- // FIXME: I still didn't find the way to determine RUNPATH on non-Linux .
219+ // FIXME: I still didn't find the way to determine RUNPATH on non-Glibc/Musl/Soloris .
209220// So use $ORIGIN as a temporary solution
210221static char * get_runpath () { return get_origin (); }
211222#endif
@@ -224,7 +235,7 @@ static char *get_driver_path() {
224235 char * LPAC_DRIVER_HOME = get_first_runpath (get_runpath ());
225236 if (LPAC_DRIVER_HOME == NULL )
226237 return NULL ;
227- if (!strcmp (LPAC_DRIVER_HOME , "$ORIGIN" )) {
238+ if (!strcmp (LPAC_DRIVER_HOME , "$ORIGIN" ) || ! strcmp ( LPAC_DRIVER_HOME , "@loader_path" ) ) {
228239 free (LPAC_DRIVER_HOME );
229240 LPAC_DRIVER_HOME = get_origin ();
230241 if (LPAC_DRIVER_HOME == NULL )
@@ -324,7 +335,7 @@ static const struct euicc_driver *find_driver_by_name(const enum euicc_driver_ty
324335 _cleanup_free_ char * LPAC_DRIVER_HOME = get_driver_path ();
325336 if (LPAC_DRIVER_HOME == NULL )
326337 return false;
327- if (!strcmp (LPAC_DRIVER_HOME , "$ORIGIN" )) {
338+ if (!strcmp (LPAC_DRIVER_HOME , "$ORIGIN" ) || ! strcmp ( LPAC_DRIVER_HOME , "@loader_path" ) ) {
328339 free (LPAC_DRIVER_HOME );
329340 LPAC_DRIVER_HOME = get_origin ();
330341 if (LPAC_DRIVER_HOME == NULL )
0 commit comments