*/
#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
#define ElfW(type) Elf_##type
#endif
-#define ALIGN(val, align) (((val) + (align) - 1) & ~((align) - 1))
-
struct build_id_note {
ElfW(Nhdr) nhdr;
};
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;
};
{
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++) {
}
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;
}
}
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,
};
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