Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2012 Intel Corporation. All Rights Reserved.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the
  6.  * "Software"), to deal in the Software without restriction, including
  7.  * without limitation the rights to use, copy, modify, merge, publish,
  8.  * distribute, sub license, and/or sell copies of the Software, and to
  9.  * permit persons to whom the Software is furnished to do so, subject to
  10.  * the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the
  13.  * next paragraph) shall be included in all copies or substantial portions
  14.  * of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  19.  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
  20.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  21.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  22.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #define _GNU_SOURCE 1
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <dlfcn.h>
  29. #include "dso_utils.h"
  30.  
  31. struct dso_handle {
  32.     void       *handle;
  33. };
  34.  
  35. /* Opens the named shared library */
  36. struct dso_handle *
  37. dso_open(const char *path)
  38. {
  39.     struct dso_handle *h;
  40.  
  41.     h = calloc(1, sizeof(*h));
  42.     if (!h)
  43.         return NULL;
  44.  
  45.     if (path) {
  46.         h->handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL);
  47.         if (!h->handle)
  48.             goto error;
  49.     }
  50.     else
  51.         h->handle = RTLD_DEFAULT;
  52.     return h;
  53.  
  54. error:
  55.     dso_close(h);
  56.     return NULL;
  57. }
  58.  
  59. /* Closes and disposed any allocated data */
  60. void
  61. dso_close(struct dso_handle *h)
  62. {
  63.     if (!h)
  64.         return;
  65.  
  66.     if (h->handle) {
  67.         if (h->handle != RTLD_DEFAULT)
  68.             dlclose(h->handle);
  69.         h->handle = NULL;
  70.     }
  71.     free(h);
  72. }
  73.  
  74. /* Load symbol into the supplied location */
  75. static bool
  76. get_symbol(struct dso_handle *h, void *func_vptr, const char *name)
  77. {
  78.     dso_generic_func func, * const func_ptr = func_vptr;
  79.     const char *error;
  80.  
  81.     dlerror();
  82.     func = (dso_generic_func)dlsym(h->handle, name);
  83.     error = dlerror();
  84.     if (error) {
  85.         fprintf(stderr, "error: failed to resolve %s(): %s\n", name, error);
  86.         return false;
  87.     }
  88.     *func_ptr = func;
  89.     return true;
  90. }
  91.  
  92. /* Loads symbols into the supplied vtable */
  93. bool
  94. dso_get_symbols(
  95.     struct dso_handle          *h,
  96.     void                       *vtable,
  97.     unsigned int                vtable_length,
  98.     const struct dso_symbol    *symbols
  99. )
  100. {
  101.     const struct dso_symbol *s;
  102.  
  103.     for (s = symbols; s->name != NULL; s++) {
  104.         if (s->offset + sizeof(dso_generic_func) > vtable_length)
  105.             return false;
  106.         if (!get_symbol(h, ((char *)vtable) + s->offset, s->name))
  107.             return false;
  108.     }
  109.     return true;
  110. }
  111.