Bug 27391

Summary: [readelf] Handle absolute DW_AT_dwo_name
Product: binutils Reporter: Tom de Vries <vries>
Component: binutilsAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 2.37   
Target Milestone: 2.37   
Host: Target:
Build: Last reconfirmed:

Description Tom de Vries 2021-02-10 11:38:13 UTC
With the fission-mix executable from the gdb testsuite, I run into:
...
$ ~/binutils/install/bin/readelf -w fission-mix > READELF
readelf: Warning: Unable to load dwo file: /home/vries/gdb_versions/devel/build/gdb/testsuite//home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.dwarf2/fission-mix/fission-mix2.dwo
...

At the start we find:
...
The .debug_info section contains link(s) to dwo file(s):

  Name:      /home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.dwarf2/fission-mix/fission-mix2.dwo
  Directory: /home/vries/gdb_versions/devel/build/gdb/testsuite
  ID:        <not specified>
...
and later-on the part from where we get this info:
...
  Compilation Unit @ offset 0x176:
   Length:        0x31 (32-bit)
   Version:       5
   Unit Type:     DW_UT_skeleton (4)
   Abbrev Offset: 0xfd
   Pointer Size:  8
 <0><18a>: Abbrev Number: 1 (DW_TAG_skeleton_unit)
    <18b>   DW_AT_low_pc      : 0x4004cf
    <193>   DW_AT_high_pc     : 0x15
    <19b>   DW_AT_stmt_list   : 0x14d
    <19f>   DW_AT_dwo_name    : /home/vries/gdb_versions/devel/build/gdb/testsuite/outputs/gdb.dwarf2/fission-mix/fission-mix2.dwo
    <1a3>   DW_AT_comp_dir    : /home/vries/gdb_versions/devel/build/gdb/testsuite
    <1a7>   DW_AT_GNU_pubnames: 1
    <1a7>   DW_AT_addr_base   : 0x8
...

In the dwarf-5 standard we read:
...
A skeleton compilation unit has a DW_AT_dwo_name attribute:
1. A DW_AT_dwo_name attribute whose value is a null-terminated string
containing the full or relative path name (relative to the value of the
DW_AT_comp_dir attribute, see below) of the object file that contains the full
compilation unit.
...

So, the name only needs to be prefixed with the dir if it's relative.

In this case, the name is already absolute and readelf shouldn't try to add the dir prefix.
Comment 1 Tom de Vries 2021-02-10 13:04:18 UTC
Tentative patch:
...
diff --git a/binutils/dwarf.c b/binutils/dwarf.c
index 84d63f63366..3cbd19710d7 100644
--- a/binutils/dwarf.c
+++ b/binutils/dwarf.c
@@ -11092,8 +11092,11 @@ load_dwo_file (const char * main_filename, const char * name,
 const char * dir,
   char * separate_filename;
   void * separate_handle;
 
-  /* FIXME: Skip adding / if dwo_dir ends in /.  */
-  separate_filename = concat (dir, "/", name, NULL);
+  if (IS_ABSOLUTE_PATH (name))
+    separate_filename = strdup (name);
+  else
+    /* FIXME: Skip adding / if dwo_dir ends in /.  */
+    separate_filename = concat (dir, "/", name, NULL);
   if (separate_filename == NULL)
     {
       warn (_("Out of memory allocating dwo filename\n"));
...
Comment 2 Tom de Vries 2021-02-10 13:49:51 UTC
submitted here: https://sourceware.org/pipermail/binutils/2021-February/115314.html
Comment 3 Sourceware Commits 2021-02-10 16:26:54 UTC
The master branch has been updated by Tom de Vries <vries@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=d9d9d8ef8ce984dee45f35a5f00f4cf74bcab1e6

commit d9d9d8ef8ce984dee45f35a5f00f4cf74bcab1e6
Author: Tom de Vries <tdevries@suse.de>
Date:   Wed Feb 10 17:26:50 2021 +0100

    [binutils] Handle absolute DW_AT_dwo_name
    
    With an exec:
    ...
    $ pwd
    /home/vries/tmp
    $ gcc /home/vries/tmp/src/hello.c -gsplit-dwarf -c \
      -o /home/vries/tmp/obj/hello.o
    ...
    I get:
    ...
    $ readelf -w obj/hello.o > READELF
    readelf: Warning: Unable to load dwo file: \
      /home/vries/tmp//home/vries/tmp/obj/hello.dwo
    ...
    
    The dwo file name is listed here:
    ...
        <20>   DW_AT_GNU_dwo_name: /home/vries/tmp/obj/hello.dwo
        <24>   DW_AT_comp_dir    : /home/vries/tmp
    ...
    
    The standard states about the DW_AT_dwo_name attribute:
    ...
    value is a null-terminated string containing the full or relative path name
    (relative to the value of the DW_AT_comp_dir attribute, see below) of the
    object file that contains the full compilation unit.
    ...
    
    So, readelf shouldn't try to prefix an absolute path with DW_AT_comp_dir.
    
    Fix this in load_dwo_file by handling the absolute path case.
    
    binutils/ChangeLog:
    
    2021-02-10  Tom de Vries  <tdevries@suse.de>
    
            PR binutils/27391
            * dwarf.c (load_dwo_file): Handle case that name is absolute path.
Comment 4 Tom de Vries 2021-02-10 16:27:43 UTC
Patch committed, marking resolved-fixed.