]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 338791 Handle debug alt dwz files that are relative to the debug file.
authorMark Wielaard <mark@klomp.org>
Fri, 5 Sep 2014 14:25:17 +0000 (14:25 +0000)
committerMark Wielaard <mark@klomp.org>
Fri, 5 Sep 2014 14:25:17 +0000 (14:25 +0000)
readdwarf3 would only look for alt dwz files using the build-id.
But alt files can be installed relative to the debug (or main) file.
Fix find_debug_file to allow searching of relative files even if
we don't want an ET_REL (rel_ok) file, and pass the build-id to
open_debug_file so it can be checked. Add the debug file path to
_DebugInfoFSM and set it in find_debug_file once opened. Pass the
dbgname or filename as relative file to resolve an altfile in
read_elf_debug_info when we ahava an debugaltlink_escn.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14464

coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/priv_storage.h
coregrind/m_debuginfo/readelf.c

index 4ad9b7a333cdf051fbc48b47bbbe8e1479402b88..285f7c95fa35a80e8fccd37daa30a5e1c40daf55 100644 (file)
@@ -216,6 +216,7 @@ static void free_DebugInfo ( DebugInfo* di )
    vg_assert(di != NULL);
    if (di->fsm.maps)     VG_(deleteXA)(di->fsm.maps);
    if (di->fsm.filename) ML_(dinfo_free)(di->fsm.filename);
+   if (di->fsm.dbgname)  ML_(dinfo_free)(di->fsm.dbgname);
    if (di->soname)       ML_(dinfo_free)(di->soname);
    if (di->loctab)       ML_(dinfo_free)(di->loctab);
    if (di->loctab_fndn_ix) ML_(dinfo_free)(di->loctab_fndn_ix);
index 21ca4386152f7b691f2972c1887a2b02749c5272..89238d53d4dab327697761ca59c85f92ebb9d056 100644 (file)
@@ -543,6 +543,7 @@ struct _DebugInfoMapping
 struct _DebugInfoFSM
 {
    HChar*  filename;  /* in mallocville (VG_AR_DINFO)               */
+   HChar*  dbgname;   /* in mallocville (VG_AR_DINFO)               */
    XArray* maps;      /* XArray of _DebugInfoMapping structs        */
    Bool  have_rx_map; /* did we see a r?x mapping yet for the file? */
    Bool  have_rw_map; /* did we see a rw? mapping yet for the file? */
index 5867765491aa23bd3e4ccf38df0af9fae93e9198..86186d3b42b357b13c5228ca41cb2dc8cef836ca 100644 (file)
@@ -1244,7 +1244,7 @@ DiImage* find_debug_file( struct _DebugInfo* di,
       }
    }
 
-   if (dimg == NULL && debugname != NULL && !rel_ok) {
+   if (dimg == NULL && debugname != NULL) {
       HChar *objdir = ML_(dinfo_strdup)("di.fdf.2", objpath);
       HChar *objdirptr;
 
@@ -1258,21 +1258,21 @@ DiImage* find_debug_file( struct _DebugInfo* di,
                      + (serverpath ? VG_(strlen)(serverpath) : 0));
 
       VG_(sprintf)(debugpath, "%s/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
+      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
       if (dimg != NULL) goto dimg_ok;
 
       VG_(sprintf)(debugpath, "%s/.debug/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
+      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
       if (dimg != NULL) goto dimg_ok;
       
       VG_(sprintf)(debugpath, "/usr/lib/debug%s/%s", objdir, debugname);
-      dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
+      dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
       if (dimg != NULL) goto dimg_ok;
 
       if (extrapath) {
          VG_(sprintf)(debugpath, "%s%s/%s", extrapath,
                                             objdir, debugname);
-         dimg = open_debug_file(debugpath, NULL, crc, rel_ok, NULL);
+         dimg = open_debug_file(debugpath, buildid, crc, rel_ok, NULL);
          if (dimg != NULL) goto dimg_ok;
       }
 
@@ -1284,7 +1284,7 @@ DiImage* find_debug_file( struct _DebugInfo* di,
             basename = VG_(strrchr)(basename, '/') + 1;
          }
          VG_(sprintf)(debugpath, "%s on %s", basename, serverpath);
-         dimg = open_debug_file(basename, NULL, crc, rel_ok, serverpath);
+         dimg = open_debug_file(basename, buildid, crc, rel_ok, serverpath);
          if (dimg) goto dimg_ok;
       }
 
@@ -1297,6 +1297,10 @@ DiImage* find_debug_file( struct _DebugInfo* di,
       vg_assert(debugpath);
       TRACE_SYMTAB("\n");
       TRACE_SYMTAB("------ Found a debuginfo file: %s\n", debugpath);
+
+      /* Only set once, we might be called again for opening the altfile. */
+      if (di->fsm.dbgname == NULL)
+         di->fsm.dbgname = ML_(dinfo_strdup)("di.fdf.4", debugpath);
    }
 
    if (debugpath)
@@ -2714,6 +2718,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
       vg_assert(aimg == NULL);
 
       if (debugaltlink_escn.img != NULL) {
+         HChar* altfile_str_m
+             = ML_(img_strdup)(debugaltlink_escn.img,
+                               "di.fbi.3", debugaltlink_escn.ioff);
          UInt buildid_offset = ML_(img_strlen)(debugaltlink_escn.img,
                                                debugaltlink_escn.ioff)+1;
 
@@ -2724,6 +2731,9 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
                                 (debugaltlink_escn.szB - buildid_offset)
                                 * 2 + 1);
 
+         /* The altfile might be relative to the debug file or main file. */
+         HChar *dbgname = di->fsm.dbgname ? di->fsm.dbgname : di->fsm.filename;
+
          for (j = 0; j < debugaltlink_escn.szB - buildid_offset; j++)
             VG_(sprintf)(
                altbuildid + 2 * j, "%02x",
@@ -2732,9 +2742,11 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
                                         + buildid_offset + j));
 
          /* See if we can find a matching debug file */
-         aimg = find_debug_file( di, di->fsm.filename, altbuildid,
-                                 NULL, 0, True );
+         aimg = find_debug_file( di, dbgname, altbuildid,
+                                 altfile_str_m, 0, True );
 
+         if (altfile_str_m)
+            ML_(dinfo_free)(altfile_str_m);
          ML_(dinfo_free)(altbuildid);
       }