From b8735981a04b3c3f3267db2d1db3077be3d9e0e0 Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Sun, 20 Apr 2014 22:10:24 +0000 Subject: [PATCH] * Factorise code between is_valid_for_client and is_valid_for_valgrind. * Implement VG_(am_is_valid_for_valgrind) * Use it in gdbsrv to check accessibility when hostvisibility is activated git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13903 --- coregrind/m_aspacemgr/aspacemgr-linux.c | 77 ++++++++++++------------- coregrind/m_gdbserver/target.c | 15 +++-- coregrind/pub_core_aspacemgr.h | 6 ++ 3 files changed, 53 insertions(+), 45 deletions(-) diff --git a/coregrind/m_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c index dddbe37b5..30b61495b 100644 --- a/coregrind/m_aspacemgr/aspacemgr-linux.c +++ b/coregrind/m_aspacemgr/aspacemgr-linux.c @@ -1294,12 +1294,12 @@ ULong VG_(am_get_anonsize_total)( void ) } -/* Test if a piece of memory is addressable by the client with at +/* Test if a piece of memory is addressable by client or by valgrind with at least the "prot" protection permissions by examining the underlying - segments. If freeOk is True then SkFree areas are also allowed. + segments. If client && freeOk is True then SkFree areas are also allowed. */ static -Bool is_valid_for_client( Addr start, SizeT len, UInt prot, Bool freeOk ) +Bool is_valid_for( Bool client, Addr start, SizeT len, UInt prot, Bool freeOk ) { Int i, iLo, iHi; Bool needR, needW, needX; @@ -1327,18 +1327,32 @@ Bool is_valid_for_client( Addr start, SizeT len, UInt prot, Bool freeOk ) iHi = find_nsegment_idx(start + len - 1); } - for (i = iLo; i <= iHi; i++) { - if ( (nsegments[i].kind == SkFileC - || nsegments[i].kind == SkAnonC - || nsegments[i].kind == SkShmC - || (nsegments[i].kind == SkFree && freeOk) - || (nsegments[i].kind == SkResvn && freeOk)) - && (needR ? nsegments[i].hasR : True) - && (needW ? nsegments[i].hasW : True) - && (needX ? nsegments[i].hasX : True) ) { - /* ok */ - } else { - return False; + if (client) { + for (i = iLo; i <= iHi; i++) { + if ( (nsegments[i].kind == SkFileC + || nsegments[i].kind == SkAnonC + || nsegments[i].kind == SkShmC + || (nsegments[i].kind == SkFree && freeOk) + || (nsegments[i].kind == SkResvn && freeOk)) + && (needR ? nsegments[i].hasR : True) + && (needW ? nsegments[i].hasW : True) + && (needX ? nsegments[i].hasX : True) ) { + /* ok */ + } else { + return False; + } + } + } else { + for (i = iLo; i <= iHi; i++) { + if ( (nsegments[i].kind == SkFileV + || nsegments[i].kind == SkAnonV) + && (needR ? nsegments[i].hasR : True) + && (needW ? nsegments[i].hasW : True) + && (needX ? nsegments[i].hasX : True) ) { + /* ok */ + } else { + return False; + } } } return True; @@ -1350,7 +1364,8 @@ Bool is_valid_for_client( Addr start, SizeT len, UInt prot, Bool freeOk ) Bool VG_(am_is_valid_for_client)( Addr start, SizeT len, UInt prot ) { - return is_valid_for_client( start, len, prot, False/*free not OK*/ ); + return is_valid_for(/* client */ True, + start, len, prot, False/*free not OK*/ ); } /* Variant of VG_(am_is_valid_for_client) which allows free areas to @@ -1360,32 +1375,15 @@ Bool VG_(am_is_valid_for_client)( Addr start, SizeT len, Bool VG_(am_is_valid_for_client_or_free_or_resvn) ( Addr start, SizeT len, UInt prot ) { - return is_valid_for_client( start, len, prot, True/*free is OK*/ ); + return is_valid_for(/* client */ True, + start, len, prot, True/*free is OK*/ ); } -/* Test if a piece of memory is addressable by valgrind with at least - PROT_NONE protection permissions by examining the underlying - segments. */ -static Bool is_valid_for_valgrind( Addr start, SizeT len ) +Bool VG_(am_is_valid_for_valgrind) ( Addr start, SizeT len, UInt prot ) { - Int i, iLo, iHi; - - if (len == 0) - return True; /* somewhat dubious case */ - if (start + len < start) - return False; /* reject wraparounds */ - - iLo = find_nsegment_idx(start); - iHi = find_nsegment_idx(start + len - 1); - for (i = iLo; i <= iHi; i++) { - if (nsegments[i].kind == SkFileV || nsegments[i].kind == SkAnonV) { - /* ok */ - } else { - return False; - } - } - return True; + return is_valid_for(/* client */ False, + start, len, prot, False/*irrelevant*/ ); } @@ -2657,7 +2655,8 @@ SysRes am_munmap_both_wrk ( /*OUT*/Bool* need_discard, ( start, len, VKI_PROT_NONE )) goto eINVAL; } else { - if (!is_valid_for_valgrind( start, len )) + if (!VG_(am_is_valid_for_valgrind) + ( start, len, VKI_PROT_NONE )) goto eINVAL; } diff --git a/coregrind/m_gdbserver/target.c b/coregrind/m_gdbserver/target.c index faad83c20..a375bf074 100644 --- a/coregrind/m_gdbserver/target.c +++ b/coregrind/m_gdbserver/target.c @@ -452,9 +452,11 @@ int valgrind_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) { const void *sourceaddr = C2v (memaddr); dlog(2, "reading memory %p size %d\n", sourceaddr, len); - if (VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr) sourceaddr, - len, VKI_PROT_READ) - || (hostvisibility /* TBD: && check valgrind read accessibility */)) { + if (VG_(am_is_valid_for_client) ((Addr) sourceaddr, + len, VKI_PROT_READ) + || (hostvisibility + && VG_(am_is_valid_for_valgrind) ((Addr) sourceaddr, + len, VKI_PROT_READ))) { VG_(memcpy) (myaddr, sourceaddr, len); return 0; } else { @@ -469,10 +471,11 @@ int valgrind_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int l void *targetaddr = C2v (memaddr); dlog(2, "writing memory %p size %d\n", targetaddr, len); is_valid_client_memory - = VG_(am_is_valid_for_client_or_free_or_resvn) ((Addr)targetaddr, - len, VKI_PROT_WRITE); + = VG_(am_is_valid_for_client) ((Addr)targetaddr, len, VKI_PROT_WRITE); if (is_valid_client_memory - || (hostvisibility /* TBD: && check valgrind write accessibility */)) { + || (hostvisibility + && VG_(am_is_valid_for_valgrind) ((Addr) targetaddr, + len, VKI_PROT_READ))) { if (len > 0) { VG_(memcpy) (targetaddr, myaddr, len); if (is_valid_client_memory && VG_(tdict).track_post_mem_write) { diff --git a/coregrind/pub_core_aspacemgr.h b/coregrind/pub_core_aspacemgr.h index a9ea5302a..ba5df5abc 100644 --- a/coregrind/pub_core_aspacemgr.h +++ b/coregrind/pub_core_aspacemgr.h @@ -86,6 +86,12 @@ extern NSegment const* VG_(am_next_nsegment) ( const NSegment* here, // extern Bool VG_(am_is_valid_for_client) // ( Addr start, SizeT len, UInt prot ); +/* Same as VG_(am_is_valid_for_client) but for valgrind : + test if memory is addressable by valgrind with at least + the protection 'prot'. */ +extern Bool VG_(am_is_valid_for_valgrind) + ( Addr start, SizeT len, UInt prot ); + /* Variant of VG_(am_is_valid_for_client) which allows free areas to be consider part of the client's addressable space. It also considers reservations to be allowable, since from the client's