aboutsummaryrefslogtreecommitdiff
path: root/coregrind/m_syswrap
diff options
context:
space:
mode:
authoriraisr <iraisr@a5019735-40e9-0310-863c-91ae7b9d1cf9>2015-08-22 22:08:43 +0000
committeriraisr <iraisr@a5019735-40e9-0310-863c-91ae7b9d1cf9>2015-08-22 22:08:43 +0000
commitbcfaeedb1e1ac2625eea81951a785a777834321c (patch)
tree71933b69a25b270b1cf972bbf4c7279946773901 /coregrind/m_syswrap
parent913b580c090c25766cafd77a19993f89fb1271e3 (diff)
downloadvalgrind-bcfaeedb1e1ac2625eea81951a785a777834321c.tar.gz
Distinguish properly when to establish the client data segment.
Initial data segment is established (see initimg-solaris.c for rationale): - directly during client program image initialization, - or on demand when the executed program is the runtime linker itself, after it has loaded its target dynamic executable (see PRE(sys_mmapobj)), or when the first brk() syscall is made. More preparatory work for ldsoexec support. n-i-bz git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15583 a5019735-40e9-0310-863c-91ae7b9d1cf9
Diffstat (limited to 'coregrind/m_syswrap')
-rw-r--r--coregrind/m_syswrap/syswrap-solaris.c64
1 files changed, 39 insertions, 25 deletions
diff --git a/coregrind/m_syswrap/syswrap-solaris.c b/coregrind/m_syswrap/syswrap-solaris.c
index 4ea2463f4..54ad280f8 100644
--- a/coregrind/m_syswrap/syswrap-solaris.c
+++ b/coregrind/m_syswrap/syswrap-solaris.c
@@ -1806,8 +1806,13 @@ PRE(sys_time)
/* Data segment for brk (heap). It is an expandable anonymous mapping
abutting a 1-page reservation. The data segment starts at VG_(brk_base)
and runs up to VG_(brk_limit). None of these two values have to be
- page-aligned. Initial data segment is established on demand here (see
- initimg-solaris.c for rationale).
+ page-aligned.
+ Initial data segment is established (see initimg-solaris.c for rationale):
+ - directly during client program image initialization,
+ - or on demand when the executed program is the runtime linker itself,
+ after it has loaded its target dynamic executable (see PRE(sys_mmapobj)),
+ or when the first brk() syscall is made.
+
Notable facts:
- VG_(brk_base) is not page aligned; does not move
- VG_(brk_limit) moves between [VG_(brk_base), data segment end]
@@ -1838,9 +1843,23 @@ PRE(sys_time)
The page that contains VG_(brk_base) is already allocated by the program's
loaded data segment. The brk syscall wrapper handles this special case. */
+static Bool brk_segment_established = False;
+
/* Establishes initial data segment for brk (heap). */
-static Bool setup_client_dataseg(SizeT initial_size, ThreadId tid)
-{
+Bool VG_(setup_client_dataseg)(void)
+{
+ /* Segment size is initially at least 1 MB and at most 8 MB. */
+ SizeT m1 = 1024 * 1024;
+ SizeT m8 = 8 * m1;
+ SizeT initial_size = VG_(client_rlimit_data).rlim_cur;
+ VG_(debugLog)(1, "syswrap-solaris", "Setup client data (brk) segment "
+ "at %#lx\n", VG_(brk_base));
+ if (initial_size < m1)
+ initial_size = m1;
+ if (initial_size > m8)
+ initial_size = m8;
+ initial_size = VG_PGROUNDUP(initial_size);
+
Addr anon_start = VG_PGROUNDUP(VG_(brk_base));
SizeT anon_size = VG_PGROUNDUP(initial_size);
Addr resvn_start = anon_start + anon_size;
@@ -1873,18 +1892,22 @@ static Bool setup_client_dataseg(SizeT initial_size, ThreadId tid)
vg_assert(!sr_isError(sres));
vg_assert(sr_Res(sres) == anon_start);
- /* Tell the tool about the client data segment and then kill it which will
- make it initially inaccessible/unaddressable. */
- seg = VG_(am_find_nsegment)(anon_start);
+ brk_segment_established = True;
+ return True;
+}
+
+/* Tell the tool about the client data segment and then kill it which will
+ make it initially inaccessible/unaddressable. */
+void VG_(track_client_dataseg)(ThreadId tid)
+{
+ const NSegment *seg = VG_(am_find_nsegment)(VG_PGROUNDUP(VG_(brk_base)));
vg_assert(seg != NULL);
vg_assert(seg->kind == SkAnonC);
+
VG_TRACK(new_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base), tid);
VG_TRACK(die_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base));
- return True;
}
-static Bool brk_segment_established = False;
-
PRE(sys_brk)
{
/* unsigned long brk(caddr_t end_data_segment); */
@@ -1923,31 +1946,22 @@ PRE(sys_brk)
return;
}
+ /* The brk base and limit must have been already set. */
+ vg_assert(VG_(brk_base) != -1);
+ vg_assert(VG_(brk_limit) != -1);
+
if (!brk_segment_established) {
/* Stay sane (because there should have been no brk activity yet). */
vg_assert(VG_(brk_base) == VG_(brk_limit));
- /* Establish an initial data segment for brk (heap).
- Initially at least 1 MB and at most 8 MB large. */
- SizeT m1 = 1024 * 1024;
- SizeT m8 = 8 * m1;
- SizeT dseg_max_size = VG_(client_rlimit_data).rlim_cur;
- VG_(debugLog)(1, "syswrap-solaris", "Setup client data (brk) segment "
- "at %#lx\n", VG_(brk_base));
- if (dseg_max_size < m1)
- dseg_max_size = m1;
- if (dseg_max_size > m8)
- dseg_max_size = m8;
- dseg_max_size = VG_PGROUNDUP(dseg_max_size);
-
- if (!setup_client_dataseg(dseg_max_size, tid)) {
+ if (!VG_(setup_client_dataseg)()) {
VG_(umsg)("Cannot map memory to initialize brk segment in thread #%d "
"at %#lx\n", tid, VG_(brk_base));
SET_STATUS_Failure(VKI_ENOMEM);
return;
}
- brk_segment_established = True;
+ VG_(track_client_dataseg)(tid);
}
if (new_brk < old_brk_limit) {