From: Mark Wielaard Date: Thu, 12 Jul 2018 11:56:00 +0000 (+0200) Subject: Accept read-only PT_LOAD segments and .rodata. X-Git-Tag: VALGRIND_3_14_0~84 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64aa729bfae71561505a40c12755bd6b55bb3061;p=thirdparty%2Fvalgrind.git Accept read-only PT_LOAD segments and .rodata. 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 and H.J. Lu . https://bugs.kde.org/show_bug.cgi?id=395682 --- diff --git a/NEWS b/NEWS index 2e13004e41..35e39cd368 100644 --- 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 diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 13991b69a8..c36d498048 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -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; diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index 62192f00e1..95b97d6bf8 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -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);