summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorChad Versace <[email protected]>2017-09-12 15:52:03 -0700
committerChad Versace <[email protected]>2017-09-13 09:49:27 -0700
commit5c98d3825ccbed9054a1bb2de607116b2b31d48b (patch)
tree08eb6cc0beb3e572b48d28f59977a878646a412b /src/util
parentc8db134e4deed596a67d9daa1827feca76d5c4c4 (diff)
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 <[email protected]> Reviewed-by: Matt Turner <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/util')
-rw-r--r--src/util/build_id.c25
-rw-r--r--src/util/build_id.h2
2 files changed, 15 insertions, 12 deletions
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);