blob: 442d11847e665d593cba04c58122f3956d6d89f1 [file] [log] [blame]
njne9befc62005-06-11 15:51:30 +00001
2/*--------------------------------------------------------------------*/
3/*--- Memory management libc stuff. m_libcmman.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2000-2005 Julian Seward
11 jseward@acm.org
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
njnc7561b92005-06-19 01:24:32 +000031#include "pub_core_basics.h"
njn899ce732005-06-21 00:28:11 +000032#include "pub_core_debuginfo.h" // Needed for pub_core_aspacemgr :(
njne9befc62005-06-11 15:51:30 +000033#include "pub_core_aspacemgr.h"
34#include "pub_core_libcbase.h"
35#include "pub_core_libcassert.h"
36#include "pub_core_libcmman.h"
37#include "pub_core_libcprint.h"
njne9befc62005-06-11 15:51:30 +000038
njne9befc62005-06-11 15:51:30 +000039/* Returns -1 on failure. */
40void* VG_(mmap)( void* start, SizeT length,
41 UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
42{
43 SysRes res;
44
45 if (!(flags & VKI_MAP_FIXED)) {
46 start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
njne9befc62005-06-11 15:51:30 +000047 }
48 if (start == 0)
49 return (void *)-1;
50
51 res = VG_(mmap_native)(start, length, prot,
njna3823602005-06-28 02:45:29 +000052 (flags | VKI_MAP_FIXED) & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
njne9befc62005-06-11 15:51:30 +000053 fd, offset);
54
55 // Check it ended up in the right place.
56 if (!res.isError) {
57 if (flags & VKI_MAP_CLIENT) {
58 vg_assert(VG_(client_base) <= res.val
59 && res.val+length <= VG_(client_end));
60 } else {
61 vg_assert(VG_(valgrind_base) <= res.val
62 && res.val+length-1 <= VG_(valgrind_last));
63 }
64
65 sf_flags |= SF_MMAP;
njne9befc62005-06-11 15:51:30 +000066 if ( flags & VKI_MAP_SHARED) sf_flags |= SF_SHARED;
67 if (!(flags & VKI_MAP_ANONYMOUS)) sf_flags |= SF_FILE;
68 if (!(flags & VKI_MAP_CLIENT)) sf_flags |= SF_VALGRIND;
69 if ( flags & VKI_MAP_NOSYMS) sf_flags |= SF_NOSYMS;
70
71 VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
72 }
73
74 return res.isError ? (void*)-1 : (void*)res.val;
75}
76
njne9befc62005-06-11 15:51:30 +000077/* Returns -1 on failure. */
78Int VG_(munmap)( void* start, SizeT length )
79{
njn83407492005-06-19 16:10:47 +000080 SysRes res = VG_(munmap_native)(start, length);
njne9befc62005-06-11 15:51:30 +000081 if (!res.isError) {
82 VG_(unmap_range)((Addr)start, length);
83 return 0;
84 } else {
85 return -1;
86 }
87}
88
njne9befc62005-06-11 15:51:30 +000089Int VG_(mprotect)( void *start, SizeT length, UInt prot )
90{
91 SysRes res = VG_(mprotect_native)(start, length, prot);
92 if (!res.isError) {
93 VG_(mprotect_range)((Addr)start, length, prot);
94 return 0;
95 } else {
96 return -1;
97 }
98}
99
100void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
101{
102 static SizeT tot_alloc = 0;
103 void* p;
104 p = VG_(mmap)(0, nBytes,
105 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
njn0ae787c2005-06-28 22:14:53 +0000106 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, SF_VALGRIND, -1, 0);
njne9befc62005-06-11 15:51:30 +0000107
108 if (p != ((void*)(-1))) {
109 vg_assert((void*)VG_(valgrind_base) <= p && p <= (void*)VG_(valgrind_last));
110 tot_alloc += nBytes;
111 if (0)
112 VG_(printf)(
113 "get_memory_from_mmap: %llu tot, %llu req = %p .. %p, caller %s\n",
114 (ULong)tot_alloc, (ULong)nBytes, p, ((char*)p) + nBytes - 1, who );
115 return p;
116 }
117
118 VG_(printf)("\n");
119 VG_(printf)("VG_(get_memory_from_mmap): %s's request for %llu bytes failed.\n",
120 who, (ULong)nBytes);
121 VG_(printf)("VG_(get_memory_from_mmap): %llu bytes already allocated.\n",
122 (ULong)tot_alloc);
123 VG_(printf)("\n");
124 VG_(printf)("Sorry. You could try using a tool that uses less memory;\n");
125 VG_(printf)("eg. addrcheck instead of memcheck.\n");
126 VG_(printf)("\n");
127 VG_(exit)(1);
128}
129
njn9260c782005-06-19 21:57:54 +0000130// Returns 0 on failure.
njn0ae787c2005-06-28 22:14:53 +0000131Addr VG_(get_memory_from_mmap_for_client) (SizeT len)
njn9260c782005-06-19 21:57:54 +0000132{
njn0ae787c2005-06-28 22:14:53 +0000133 Addr addr;
134
njn9260c782005-06-19 21:57:54 +0000135 len = VG_PGROUNDUP(len);
136
njn0ae787c2005-06-28 22:14:53 +0000137 addr = (Addr)VG_(mmap)(NULL, len,
138 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
139 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS|VKI_MAP_CLIENT,
140 SF_CORE, -1, 0);
njn9260c782005-06-19 21:57:54 +0000141 if ((Addr)-1 != addr)
142 return addr;
143 else
144 return 0;
145}
146
147
njne9befc62005-06-11 15:51:30 +0000148/*--------------------------------------------------------------------*/
149/*--- end ---*/
150/*--------------------------------------------------------------------*/
151