X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=glaze-gl.c;h=d4ad33f77023415466f76febc3ce5c62c8437f44;hb=fded9f20d5f5c92bd5af051117327816dda0238e;hp=b6e7d72d3f8f9317a4ae03136f73b1ff9f444fa7;hpb=2b7630a8f3277a568695fc59996c8bad34261454;p=glaze diff --git a/glaze-gl.c b/glaze-gl.c index b6e7d72..d4ad33f 100644 --- a/glaze-gl.c +++ b/glaze-gl.c @@ -24,27 +24,96 @@ #include #include +#include + +#include +#include void *libgl_handle; void *wrapper_handle; +/* Is the given elf program 32 or 64 bit? + * + * Note: This function returns -1 if 'filename' cannot + * be opened as a valid ELF file. + */ +static int +elf_bits (const char *filename) +{ + Elf *elf; + GElf_Ehdr ehdr; + int fd, class; + + fd = open (filename, O_RDONLY, 0); + if (fd < 0) + return -1; + + if (elf_version (EV_CURRENT ) == EV_NONE) + return -1; + + elf = elf_begin (fd, ELF_C_READ, NULL); + if (elf == NULL) + return -1; + + if (elf_kind (elf) != ELF_K_ELF) + return -1; + + if (gelf_getehdr (elf, &ehdr) == NULL) + return -1; + + class = gelf_getclass (elf); + + switch (class) { + case ELFCLASS32: + return 32; + case ELFCLASS64: + return 64; + default: + return -1; + } +} + static void open_libgl_handle (void) { - const char *path; + const char *libgl_path; if (libgl_handle) return; - path = getenv ("GLAZE_LIBGL"); - if (path == NULL) { - fprintf (stderr, "GLAZE_LIBGL unset. Please set to path of real libGL.so under glaze.\n"); - exit (1); + libgl_path = getenv ("GLAZE_LIBGL"); + + if (libgl_path == NULL) { + Dl_info info; + int bits; + + if (dladdr (open_libgl_handle, &info) == 0) { + fprintf (stderr, "Internal error: Failed to lookup filename of glaze library with dladdr.\n"); + exit (1); + } + + bits = elf_bits (info.dli_fname); + + if (bits == 32) + libgl_path = getenv ("GLAZE_LIBGL_32_AUTO"); + if (bits == 64) + libgl_path = getenv ("GLAZE_LIBGL_64_AUTO"); + + if (libgl_path == NULL) { + fprintf (stderr, + "Error: Failed to detect OpenGL library.\n" + "Please set GLAZE_LIBGL to path of real libGL.so\n"); + exit (1); + } + + setenv ("GLAZE_LIBGL", libgl_path, 1); } - libgl_handle = dlopen (path, RTLD_LAZY | RTLD_GLOBAL); + dlerror(); + libgl_handle = dlopen (libgl_path, RTLD_LAZY | RTLD_GLOBAL); if (libgl_handle == NULL) { - fprintf (stderr, "Error: Failed to dlopen %s\n", path); + fprintf (stderr, "glaze_init: Error: Failed to dlopen %s: %s\n", + libgl_path, dlerror()); exit (1); } }