View | Details | Raw Unified | Return to bug 24488
Collapse All | Expand All

(-)a/libebl/eblopenbackend.c (-47 / +70 lines)
Lines 251-256 fill_defaults (Ebl *result) Link Here
251
  result->sysvhash_entrysize = sizeof (Elf32_Word);
251
  result->sysvhash_entrysize = sizeof (Elf32_Word);
252
}
252
}
253
253
254
static Ebl *
255
try_dlopen (const char *dsoname, Elf *elf, GElf_Half machine, size_t cnt,
256
	    Ebl *result)
257
{
258
  void *h = dlopen (dsoname, RTLD_LAZY);
259
260
  if (h != NULL)
261
    {
262
      /* We managed to load the object.  Now see whether the
263
	 initialization function likes our file.  */
264
      static const char version[] = MODVERSION;
265
      const char *modversion;
266
      ebl_bhinit_t initp;
267
268
      // We use a static number to help the compiler see we don't
269
      // overflow the stack with an arbitrary number.
270
      assert (machines[cnt].prefix_len <= MAX_PREFIX_LEN);
271
      char symname[MAX_PREFIX_LEN + sizeof "_init"];
272
273
      strcpy (mempcpy (symname, machines[cnt].prefix,
274
		       machines[cnt].prefix_len), "_init");
275
276
      initp = (ebl_bhinit_t) dlsym (h, symname);
277
      if (initp != NULL
278
	  && (modversion = initp (elf, machine, result, sizeof (Ebl)))
279
	  && strcmp (version, modversion) == 0)
280
	{
281
	  /* We found a module to handle our file.  */
282
	  result->dlhandle = h;
283
	  result->elf = elf;
284
285
	  /* A few entries are mandatory.  */
286
	  assert (result->name != NULL);
287
	  assert (result->destr != NULL);
288
289
	  return result;
290
	}
291
292
      /* Not the module we need.  */
293
      (void) dlclose (h);
294
    }
295
296
  return NULL;
297
}
254
298
255
/* Find an appropriate backend for the file associated with ELF.  */
299
/* Find an appropriate backend for the file associated with ELF.  */
256
static Ebl *
300
static Ebl *
Lines 316-375 openbackend (Elf *elf, const char *emulation, GElf_Half machine) Link Here
316
#ifndef LIBEBL_SUBDIR
360
#ifndef LIBEBL_SUBDIR
317
# define LIBEBL_SUBDIR PACKAGE
361
# define LIBEBL_SUBDIR PACKAGE
318
#endif
362
#endif
319
#define ORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
363
364
/* This works if libebl has been staticly linked into a binary.
365
   It might also work for shared libraries when installed in
366
   ${prefix}/lib/ or ${prefix}/lib64/, but not for multiarch
367
   library installs like ${prefix}/lib/i386-linux-gnu/  */
368
#define BINORIGINDIR "$ORIGIN/../$LIB/" LIBEBL_SUBDIR "/"
369
370
/* This works if libebl has been linked into a shared library,
371
   just look in the subdir.  */
372
#define LIBORIGINDIR "$ORIGIN/" LIBEBL_SUBDIR "/"
320
373
321
	/* Give it a try.  At least the machine type matches.  First
374
	/* Give it a try.  At least the machine type matches.  First
322
           try to load the module.  */
375
           try to load the module from the (bin) origin path.  */
323
	char dsoname[100];
376
	char dsoname[100];
324
	strcpy (stpcpy (stpcpy (dsoname, ORIGINDIR "libebl_"),
377
	strcpy (stpcpy (stpcpy (dsoname, BINORIGINDIR "libebl_"),
325
			machines[cnt].dsoname),
378
			machines[cnt].dsoname),
326
		".so");
379
		".so");
380
	if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL)
381
	  return result;
327
382
328
	void *h = dlopen (dsoname, RTLD_LAZY);
383
	/* Retry with the (lib) origin path.  */
329
	if (h == NULL)
384
	strcpy (stpcpy (stpcpy (dsoname, LIBORIGINDIR "libebl_"),
330
	  {
385
			machines[cnt].dsoname),
331
	    strcpy (stpcpy (stpcpy (dsoname, "libebl_"),
386
		".so");
332
			    machines[cnt].dsoname),
387
	if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL)
333
		    ".so");
388
	  return result;
334
	    h = dlopen (dsoname, RTLD_LAZY);
335
	  }
336
389
337
	  /* Try without an explicit path.  */
390
	/* Try without an explicit path (LD_LIBRARY_PATH or RPATH).  */
338
	if (h != NULL)
391
	strcpy (stpcpy (stpcpy (dsoname, "libebl_"),
339
	  {
392
			machines[cnt].dsoname),
340
	    /* We managed to load the object.  Now see whether the
393
		".so");
341
	       initialization function likes our file.  */
394
	if (try_dlopen (dsoname, elf, machine, cnt, result) != NULL)
342
	    static const char version[] = MODVERSION;
395
	  return result;
343
	    const char *modversion;
344
	    ebl_bhinit_t initp;
345
346
	    // We use a static number to help the compiler see we don't
347
	    // overflow the stack with an arbitrary number.
348
	    assert (machines[cnt].prefix_len <= MAX_PREFIX_LEN);
349
	    char symname[MAX_PREFIX_LEN + sizeof "_init"];
350
351
	    strcpy (mempcpy (symname, machines[cnt].prefix,
352
			     machines[cnt].prefix_len), "_init");
353
354
	    initp = (ebl_bhinit_t) dlsym (h, symname);
355
	    if (initp != NULL
356
		&& (modversion = initp (elf, machine, result, sizeof (Ebl)))
357
		&& strcmp (version, modversion) == 0)
358
	      {
359
		/* We found a module to handle our file.  */
360
		result->dlhandle = h;
361
		result->elf = elf;
362
363
		/* A few entries are mandatory.  */
364
		assert (result->name != NULL);
365
		assert (result->destr != NULL);
366
367
		return result;
368
	      }
369
370
	    /* Not the module we need.  */
371
	    (void) dlclose (h);
372
	  }
373
396
374
	/* We cannot find a DSO but the emulation/machine ID matches.
397
	/* We cannot find a DSO but the emulation/machine ID matches.
375
	   Return that information.  */
398
	   Return that information.  */

Return to bug 24488