Added few more stubs so that control reaches to DestroyDevice().
[mesa.git] / src / util / build_id.c
index cc0f852730289dbc5259aaf7968e9da7a7aef8db..8b4f8f30afb560fb26479c5c2bb4cbff8ba686ff 100644 (file)
  */
 
 #ifdef HAVE_DL_ITERATE_PHDR
+#include <dlfcn.h>
 #include <link.h>
 #include <stddef.h>
 #include <string.h>
 
 #include "build_id.h"
+#include "macros.h"
 
 #ifndef NT_GNU_BUILD_ID
 #define NT_GNU_BUILD_ID 3
@@ -36,8 +38,6 @@
 #define ElfW(type) Elf_##type
 #endif
 
-#define ALIGN(val, align)      (((val) + (align) - 1) & ~((align) - 1))
-
 struct build_id_note {
    ElfW(Nhdr) nhdr;
 
@@ -46,7 +46,9 @@ struct build_id_note {
 };
 
 struct callback_data {
-   const char *filename;
+   /* Base address of shared object, taken from Dl_info::dli_fbase */
+   const void *dli_fbase;
+
    struct build_id_note *note;
 };
 
@@ -55,8 +57,18 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
 {
    struct callback_data *data = data_;
 
-   char *ptr = strstr(info->dlpi_name, data->filename);
-   if (ptr == NULL || ptr[strlen(data->filename)] != '\0')
+   /* Calculate address where shared object is mapped into the process space.
+    * (Using the base address and the virtual address of the first LOAD segment)
+    */
+   void *map_start = NULL;
+   for (unsigned i = 0; i < info->dlpi_phnum; i++) {
+      if (info->dlpi_phdr[i].p_type == PT_LOAD) {
+         map_start = (void *)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
+         break;
+      }
+   }
+
+   if (map_start != data->dli_fbase)
       return 0;
 
    for (unsigned i = 0; i < info->dlpi_phnum; i++) {
@@ -77,8 +89,8 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
          }
 
          size_t offset = sizeof(ElfW(Nhdr)) +
-                         ALIGN(note->nhdr.n_namesz, 4) +
-                         ALIGN(note->nhdr.n_descsz, 4);
+                         ALIGN_POT(note->nhdr.n_namesz, 4) +
+                         ALIGN_POT(note->nhdr.n_descsz, 4);
          note = (struct build_id_note *)((char *)note + offset);
          len -= offset;
       }
@@ -88,10 +100,18 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
 }
 
 const struct build_id_note *
-build_id_find_nhdr(const char *filename)
+build_id_find_nhdr_for_addr(const void *addr)
 {
+   Dl_info info;
+
+   if (!dladdr(addr, &info))
+      return NULL;
+
+   if (!info.dli_fbase)
+      return NULL;
+
    struct callback_data data = {
-      .filename = filename,
+      .dli_fbase = info.dli_fbase,
       .note = NULL,
    };
 
@@ -107,11 +127,10 @@ build_id_length(const struct build_id_note *note)
    return note->nhdr.n_descsz;
 }
 
-void
-build_id_read(const struct build_id_note *note,
-              unsigned char *build_id, size_t n)
+const uint8_t *
+build_id_data(const struct build_id_note *note)
 {
-   memcpy(build_id, note->build_id, n);
+   return note->build_id;
 }
 
 #endif