From: Florian Krohm Date: Thu, 26 Feb 2015 21:48:19 +0000 (+0000) Subject: Simplify do_brk X-Git-Tag: svn/VALGRIND_3_11_0~625 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eb4228077ac39f60a983a532e32b2968284ef93c;p=thirdparty%2Fvalgrind.git Simplify do_brk - remove redundant asserts - let VG_(am_extend_into_adjacent_reservation_client) worry about - whether delta is too large - whether the segment abutting this one exists and is a reservation segment The function already checks these things. No need to do it again here. - do_brk does not need to know that a reservation segment must not shrink beyond a single page. That detail ought to be hidden in the address space manager. Also, turn a few conditions into asserts. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14967 --- diff --git a/coregrind/m_syswrap/syswrap-generic.c b/coregrind/m_syswrap/syswrap-generic.c index d6a460bef8..be32e7a0f3 100644 --- a/coregrind/m_syswrap/syswrap-generic.c +++ b/coregrind/m_syswrap/syswrap-generic.c @@ -1,3 +1,4 @@ +/* -*- mode: C; c-basic-offset: 3; -*- */ /*--------------------------------------------------------------------*/ /*--- Wrappers for generic Unix system calls ---*/ @@ -1187,7 +1188,6 @@ void ML_(buf_and_len_post_check) ( ThreadId tid, SysRes res, static Addr do_brk ( Addr newbrk ) { NSegment const* aseg; - NSegment const* rseg; Addr newbrkP; SizeT delta; Bool debug = False; @@ -1196,19 +1196,19 @@ static Addr do_brk ( Addr newbrk ) VG_(printf)("\ndo_brk: brk_base=%#lx brk_limit=%#lx newbrk=%#lx\n", VG_(brk_base), VG_(brk_limit), newbrk); -# if 0 - if (0) show_segments("in_brk"); -# endif + if (0) VG_(am_show_nsegments)(0, "in_brk"); if (newbrk < VG_(brk_base)) /* Clearly impossible. */ goto bad; - if (newbrk >= VG_(brk_base) && newbrk < VG_(brk_limit)) { + if (newbrk < VG_(brk_limit)) { /* shrinking the data segment. Be lazy and don't munmap the excess area. */ NSegment const * seg = VG_(am_find_nsegment)(newbrk); - if (seg && seg->hasT) + vg_assert(seg); + + if (seg->hasT) VG_(discard_translations)( newbrk, VG_(brk_limit) - newbrk, "do_brk(shrink)" ); /* Since we're being lazy and not unmapping pages, we have to @@ -1218,15 +1218,16 @@ static Addr do_brk ( Addr newbrk ) try hard to ensure we're not going to segfault by doing the write - check both ends of the range are in the same segment and that segment is writable. */ - if (seg) { - /* pre: newbrk < VG_(brk_limit) - => newbrk <= VG_(brk_limit)-1 */ - NSegment const * seg2; - vg_assert(newbrk < VG_(brk_limit)); + NSegment const * seg2; + + if (VG_(brk_limit) > VG_(brk_base)) seg2 = VG_(am_find_nsegment)( VG_(brk_limit)-1 ); - if (seg2 && seg == seg2 && seg->hasW) - VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk ); - } + else + seg2 = VG_(am_find_nsegment)( VG_(brk_limit) ); + vg_assert(seg2); + + if (seg == seg2 && seg->hasW) + VG_(memset)( (void*)newbrk, 0, VG_(brk_limit) - newbrk ); VG_(brk_limit) = newbrk; return newbrk; @@ -1237,31 +1238,19 @@ static Addr do_brk ( Addr newbrk ) aseg = VG_(am_find_nsegment)( VG_(brk_limit)-1 ); else aseg = VG_(am_find_nsegment)( VG_(brk_limit) ); - rseg = VG_(am_next_nsegment)( aseg, True/*forwards*/ ); /* These should be assured by setup_client_dataseg in m_main. */ vg_assert(aseg); - vg_assert(rseg); vg_assert(aseg->kind == SkAnonC); - vg_assert(rseg->kind == SkResvn); - vg_assert(aseg->end+1 == rseg->start); - vg_assert(newbrk >= VG_(brk_base)); - if (newbrk <= rseg->start) { + if (newbrk <= aseg->end + 1) { /* still fits within the anon segment. */ VG_(brk_limit) = newbrk; return newbrk; } - if (newbrk > rseg->end+1 - VKI_PAGE_SIZE) { - /* request is too large -- the resvn would fall below 1 page, - which isn't allowed. */ - goto bad; - } - newbrkP = VG_PGROUNDUP(newbrk); - vg_assert(newbrkP > rseg->start && newbrkP <= rseg->end+1 - VKI_PAGE_SIZE); - delta = newbrkP - rseg->start; + delta = newbrkP - (aseg->end + 1); vg_assert(delta > 0); vg_assert(VG_IS_PAGE_ALIGNED(delta));