From 5c98d3825ccbed9054a1bb2de607116b2b31d48b Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Tue, 12 Sep 2017 15:52:03 -0700 Subject: [PATCH] util: Query build-id by symbol address, not library name This patch renames build_id_find_nhdr() to build_id_find_nhdr_for_addr(), and changes it to never examine the library name. Tested on Fedora by confirming that build_id_get_data() returns the same build-id as the file(1) tool. For BSD, I confirmed that the API used (dladdr() and struct Dl_info) is documented in FreeBSD's manpages. This solves two problems: - We can now the query the build-id without knowing the installed library's filename. This matters because Android requires specific filenames for HAL modules, such as "/vendor/lib/hw/vulkan.${board}.so". The HAL filenames do not follow the Unix convention of "libfoo.so". In other words, the same query code will now work on Linux and Android. - Querying the build-id now works correctly when the process contains multiple shared objects with the same basename. (Admittedly, this is a highly unlikely scenario). Cc: Jonathan Gray Reviewed-by: Matt Turner Reviewed-by: Emil Velikov --- src/intel/vulkan/anv_device.c | 3 ++- src/util/build_id.c | 25 ++++++++++++++----------- src/util/build_id.h | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index be2455166e3..8e2ed9eac45 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -208,7 +208,8 @@ anv_physical_device_init_heaps(struct anv_physical_device *device, int fd) static VkResult anv_physical_device_init_uuids(struct anv_physical_device *device) { - const struct build_id_note *note = build_id_find_nhdr("libvulkan_intel.so"); + const struct build_id_note *note = + build_id_find_nhdr_for_addr(anv_physical_device_init_uuids); if (!note) { return vk_errorf(device->instance, device, VK_ERROR_INITIALIZATION_FAILED, diff --git a/src/util/build_id.c b/src/util/build_id.c index 898a15f2b31..6280b4a54e3 100644 --- a/src/util/build_id.c +++ b/src/util/build_id.c @@ -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,14 +57,7 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_) { struct callback_data *data = data_; - /* The first object visited by callback is the main program. - * Android's libc returns a NULL pointer for the first executable. - */ - if (info->dlpi_name == NULL) - return 0; - - char *ptr = strstr(info->dlpi_name, data->filename); - if (ptr == NULL || ptr[strlen(data->filename)] != '\0') + if ((void *)info->dlpi_addr != data->dli_fbase) return 0; for (unsigned i = 0; i < info->dlpi_phnum; i++) { @@ -94,10 +89,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, }; diff --git a/src/util/build_id.h b/src/util/build_id.h index 18641c44af2..86d611d8db7 100644 --- a/src/util/build_id.h +++ b/src/util/build_id.h @@ -29,7 +29,7 @@ struct build_id_note; const struct build_id_note * -build_id_find_nhdr(const char *filename); +build_id_find_nhdr_for_addr(const void *addr); unsigned build_id_length(const struct build_id_note *note); -- 2.30.2