X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fbuild_id.c;h=8b4f8f30afb560fb26479c5c2bb4cbff8ba686ff;hb=HEAD;hp=cc0f852730289dbc5259aaf7968e9da7a7aef8db;hpb=a042465c218eaed098d505e0a2e78508b554fc67;p=mesa.git diff --git a/src/util/build_id.c b/src/util/build_id.c index cc0f8527302..8b4f8f30afb 100644 --- a/src/util/build_id.c +++ b/src/util/build_id.c @@ -22,11 +22,13 @@ */ #ifdef HAVE_DL_ITERATE_PHDR +#include #include #include #include #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