]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
FreeBSD: fixed file mappings revisited
authorPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 13 Mar 2024 08:06:31 +0000 (09:06 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 13 Mar 2024 08:06:31 +0000 (09:06 +0100)
Revert to using the ELF fixed file flag, but keep the first
mapping so that it gets recorded to keep parse_procselfmaps
and ML_(read_elf_object) happy with what they see.

coregrind/m_debuginfo/debuginfo.c

index d6ed5dc34706668805a68f78f71619d8f77e6564..5939e7b3a77cb9fbafaecf3f1e470be4934c2827 100644 (file)
@@ -549,32 +549,6 @@ static Bool ranges_overlap (Addr s1, SizeT len1, Addr s2, SizeT len2 )
    return True;
 }
 
-/*
- * PJF 2023-09-23
- *
- * FreeBSD can perform a temporary mapping when loading exes
- * and shared libraries. This is seen as a single page mapped
- * before the ro/rx/rw mappings from the ELF file itself. More
- * importantly, FreeBSD can reuse that same page when loading
- * subsequent shared libraries. That means that we see this
- * page as an overlap. Previously we noted that the mapping
- * was not fixed and ignored it by returning early from
- * VG_(di_notify_mmap).
- *
- * That works OK in general, but not for the tool itself.
- * In order to read symbols for the tool, ML_(read_elf_object)
- * needs to match up the ELF headers with the DebugInfo maps
- * (populated from the global nsegments array).
- *
- * Two possible solutions would be to hack parse_procselfmaps
- * even more so that it doesn't record the ro segment (is
- * that info in kve_flags?). The other, which was also my
- * original fix for this problem, is to just ignore identical
- * ro mappings for different files on FreeBSD. I'm not certain
- * that the size is always one page - that could be used to
- * tighten the check even more.
- */
-
 /* Do the basic mappings of the two DebugInfos overlap in any way? */
 static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 )
 {
@@ -586,16 +560,6 @@ static Bool do_DebugInfos_overlap ( const DebugInfo* di1, const DebugInfo* di2 )
       for (j = 0; j < VG_(sizeXA)(di2->fsm.maps); j++) {
          const DebugInfoMapping* map2 = VG_(indexXA)(di2->fsm.maps, j);
          if (ranges_overlap(map1->avma, map1->size, map2->avma, map2->size)) {
-#if defined(VGO_freebsd)
-            if (di1 != di2 && map1->ro && map2->ro &&
-                map1->avma == map2->avma && map1->size == map2->size) {
-               if (VG_(debugLog_getLevel)() >= 3) {
-                   VG_(dmsg)("do_DebugInfos_overlap-0: identical ro mappings from files %s and %s\n",
-                            di1->fsm.filename, di2->fsm.filename);
-               }
-               continue;
-            }
-#endif
             return True;
          }
       }
@@ -1178,6 +1142,9 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
 #else
    Bool       elf_ok;
 #endif
+#if defined(VGO_freebsd)
+   static Bool first_fixed_file = True;
+#endif
 
    const Bool       debug = VG_(debugLog_getLevel)() >= 3;
    SysRes     statres;
@@ -1336,8 +1303,18 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
 #if defined(VGO_freebsd)
    /* Ignore non-fixed read-only mappings.  The dynamic linker may be
     * mapping something for its own transient purposes. */
-   if (!seg->isFF && is_ro_map && debug) {
-      VG_(dmsg)("di_notify_mmap-4: non-fixed ro map\n");
+   if (!seg->isFF && is_ro_map) {
+      if (first_fixed_file) {
+         if (debug) {
+            VG_(dmsg)("di_notify_mmap-4: first non-fixed ro map\n");
+         }
+         first_fixed_file = False;
+      } else {
+         if (debug) {
+            VG_(dmsg)("di_notify_mmap-5: not first non-fixed ro map, ignored\n");
+         }
+         return 0;
+      }
    }
 #endif