]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Accept read-only PT_LOAD segments and .rodata.
authorMark Wielaard <mark@klomp.org>
Thu, 12 Jul 2018 11:56:00 +0000 (13:56 +0200)
committerMark Wielaard <mark@klomp.org>
Mon, 16 Jul 2018 13:09:35 +0000 (15:09 +0200)
The new binutils ld -z separate-code option creates multiple read-only
PT_LOAD segments and might place .rodata in a non-executable segment.

Allow and keep track of separate read-only segments and allow a readonly
page with .rodata section.

Based on patches from Tom Hughes <tom@compton.nu> and
H.J. Lu <hjl.tools@gmail.com>.

https://bugs.kde.org/show_bug.cgi?id=395682

NEWS
coregrind/m_debuginfo/debuginfo.c
coregrind/m_debuginfo/readelf.c

diff --git a/NEWS b/NEWS
index 2e13004e41563e3ecd855c94ee10af7378367068..35e39cd368427d514725b889d85c94e47903b004 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -116,6 +116,7 @@ where XXXXXX is the bug number as listed below.
 393062  build-id ELF phdrs read causes "debuginfo reader: ensure_valid failed"
 393099  posix_memalign() invalid write if alignment == 0
 395709  PPC64 is missing support for the xvnegsp instruction
+395682  Accept read-only PT_LOAD segments and .rodata by ld -z separate-code
 
 n-i-bz  Fix missing workq_ops operations (macOS)
 n-i-bz  fix bug in strspn replacement
index 13991b69a8c80ad4bb3c2f3c614701037ca08406..c36d4980486c14b797681350b864fc1d39a7ac24 100644 (file)
@@ -1126,9 +1126,7 @@ ULong VG_(di_notify_mmap)( Addr a, Bool allow_SkFileV, Int use_fd )
 #    error "Unknown platform"
 #  endif
 
-#  if defined(VGP_x86_darwin) && DARWIN_VERS >= DARWIN_10_7
    is_ro_map = seg->hasR && !seg->hasW && !seg->hasX;
-#  endif
 
 #  if defined(VGO_solaris)
    is_rx_map = seg->hasR && seg->hasX && !seg->hasW;
index 62192f00e1427ea8737077827154a3f06f64c479..95b97d6bf8161182a16d1042b5a6893f5e9ff2bf 100644 (file)
@@ -1881,7 +1881,7 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
                Bool loaded = False;
                for (j = 0; j < VG_(sizeXA)(di->fsm.maps); j++) {
                   const DebugInfoMapping* map = VG_(indexXA)(di->fsm.maps, j);
-                  if (   (map->rx || map->rw)
+                  if (   (map->rx || map->rw || map->ro)
                       && map->size > 0 /* stay sane */
                       && a_phdr.p_offset >= map->foff
                       && a_phdr.p_offset <  map->foff + map->size
@@ -1912,6 +1912,16 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
                            i, (UWord)item.bias);
                         loaded = True;
                      }
+                     if (map->ro
+                         && (a_phdr.p_flags & (PF_R | PF_W | PF_X))
+                            == PF_R) {
+                        item.exec = False;
+                        VG_(addToXA)(svma_ranges, &item);
+                        TRACE_SYMTAB(
+                           "PT_LOAD[%ld]:   acquired as ro, bias 0x%lx\n",
+                           i, (UWord)item.bias);
+                        loaded = True;
+                     }
                   }
                }
                if (!loaded) {
@@ -2179,17 +2189,25 @@ Bool ML_(read_elf_debug_info) ( struct _DebugInfo* di )
          }
       }
 
-      /* Accept .rodata where mapped as rx (data), even if zero-sized */
+      /* Accept .rodata where mapped as rx or rw (data), even if zero-sized */
       if (0 == VG_(strcmp)(name, ".rodata")) {
-         if (inrx && !di->rodata_present) {
-            di->rodata_present = True;
+         if (!di->rodata_present) {
             di->rodata_svma = svma;
-            di->rodata_avma = svma + inrx->bias;
+            di->rodata_avma = svma;
             di->rodata_size = size;
-            di->rodata_bias = inrx->bias;
             di->rodata_debug_svma = svma;
-            di->rodata_debug_bias = inrx->bias;
-                                    /* NB was 'inrw' prior to r11794 */
+            if (inrx) {
+               di->rodata_avma += inrx->bias;
+               di->rodata_bias = inrx->bias;
+               di->rodata_debug_bias = inrx->bias;
+            } else if (inrw) {
+               di->rodata_avma += inrw->bias;
+               di->rodata_bias = inrw->bias;
+               di->rodata_debug_bias = inrw->bias;
+            } else {
+               BAD(".rodata");
+            }
+            di->rodata_present = True;
             TRACE_SYMTAB("acquiring .rodata svma = %#lx .. %#lx\n",
                          di->rodata_svma,
                          di->rodata_svma + di->rodata_size - 1);