[Mesa-dev] [PATCH] util/build-id: Fix address comparison for binaries with LOAD vaddr > 0

Tapani Pälli tapani.palli at intel.com
Fri Jan 26 05:50:02 UTC 2018


I've verified this gets the correct address. Very nice work figuring 
this out Stephan!

Reviewed-by: Tapani Pälli <tapani.palli at intel.com>

On 01/24/2018 04:13 PM, Stephan Gerhold wrote:
> build_id_find_nhdr_for_addr() fails to find the build-id if the first LOAD
> segment has a virtual address other than 0x0.
> 
> For most shared libraries, the first LOAD segment has vaddr=0x0:
> 
>      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>      LOAD           0x000000 0x00000000 0x00000000 0x2d2e26 0x2d2e26 R E 0x1000
>      LOAD           0x2d2e54 0x002d3e54 0x002d3e54 0x2e248 0x2f148 RW  0x1000
> 
> However, compiling the Intel Vulkan driver as 32-bit binary on Android produces
> the following ELF header with vaddr=0x8000 instead:
> 
>      Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>      PHDR           0x000034 0x00008034 0x00008034 0x00100 0x00100 R   0x4
>      LOAD           0x000000 0x00008000 0x00008000 0x224a04 0x224a04 R E 0x1000
>      LOAD           0x225710 0x0022e710 0x0022e710 0x25988 0x27364 RW  0x1000
> 
> build_id_find_nhdr_callback() compares the address of dli_fbase from dladdr()
> and dlpi_addr from dl_iterate_phdr(). With vaddr > 0, these point to a
> different memory address, e.g.:
> 
>      dli_fbase=0xd8395000 (offset 0x8000)
>      dlpi_addr=0xd838d000
> 
> At least on glibc and bionic (Android) dli_fbase refers to the address where
> the shared object is mapped into the process space, whereas dlpi_addr is just
> the base address for the vaddrs declared in the ELF header.
> 
> To compare them correctly, we need to calculate the start of the mapping
> by adding the vaddr of the first LOAD segment to the base address.
> 
> Cc: Chad Versace <chadversary at chromium.org>
> Cc: Emil Velikov <emil.velikov at collabora.com>
> Cc: Tapani Pälli <tapani.palli at intel.com>
> Cc: <mesa-stable at lists.freedesktop.org>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=104642
> Fixes: 5c98d38 "util: Query build-id by symbol address, not library name"
> ---
>   src/util/build_id.c | 13 ++++++++++++-
>   1 file changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/src/util/build_id.c b/src/util/build_id.c
> index 536c74360e..fb67d160e3 100644
> --- a/src/util/build_id.c
> +++ b/src/util/build_id.c
> @@ -58,7 +58,18 @@ build_id_find_nhdr_callback(struct dl_phdr_info *info, size_t size, void *data_)
>   {
>      struct callback_data *data = data_;
>   
> -   if ((void *)info->dlpi_addr != data->dli_fbase)
> +   /* 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++) {
> 


More information about the mesa-dev mailing list