blob: 59a0df117f0dac4aed91d50a6b80aed4404245bd [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"
njn9abd6082005-06-17 21:31:45 +000038#include "pub_core_syscall.h"
njne9befc62005-06-11 15:51:30 +000039#include "vki_unistd.h"
40
njne9befc62005-06-11 15:51:30 +000041/* Returns -1 on failure. */
42void* VG_(mmap)( void* start, SizeT length,
43 UInt prot, UInt flags, UInt sf_flags, UInt fd, OffT offset)
44{
45 SysRes res;
46
47 if (!(flags & VKI_MAP_FIXED)) {
48 start = (void *)VG_(find_map_space)((Addr)start, length, !!(flags & VKI_MAP_CLIENT));
njne9befc62005-06-11 15:51:30 +000049 }
50 if (start == 0)
51 return (void *)-1;
52
53 res = VG_(mmap_native)(start, length, prot,
njna3823602005-06-28 02:45:29 +000054 (flags | VKI_MAP_FIXED) & ~(VKI_MAP_NOSYMS | VKI_MAP_CLIENT),
njne9befc62005-06-11 15:51:30 +000055 fd, offset);
56
57 // Check it ended up in the right place.
58 if (!res.isError) {
59 if (flags & VKI_MAP_CLIENT) {
60 vg_assert(VG_(client_base) <= res.val
61 && res.val+length <= VG_(client_end));
62 } else {
63 vg_assert(VG_(valgrind_base) <= res.val
64 && res.val+length-1 <= VG_(valgrind_last));
65 }
66
67 sf_flags |= SF_MMAP;
68 if ( flags & VKI_MAP_FIXED) sf_flags |= SF_FIXED;
69 if ( flags & VKI_MAP_SHARED) sf_flags |= SF_SHARED;
70 if (!(flags & VKI_MAP_ANONYMOUS)) sf_flags |= SF_FILE;
71 if (!(flags & VKI_MAP_CLIENT)) sf_flags |= SF_VALGRIND;
72 if ( flags & VKI_MAP_NOSYMS) sf_flags |= SF_NOSYMS;
73
74 VG_(map_fd_segment)(res.val, length, prot, sf_flags, fd, offset, NULL);
75 }
76
77 return res.isError ? (void*)-1 : (void*)res.val;
78}
79
njne9befc62005-06-11 15:51:30 +000080/* Returns -1 on failure. */
81Int VG_(munmap)( void* start, SizeT length )
82{
njn83407492005-06-19 16:10:47 +000083 SysRes res = VG_(munmap_native)(start, length);
njne9befc62005-06-11 15:51:30 +000084 if (!res.isError) {
85 VG_(unmap_range)((Addr)start, length);
86 return 0;
87 } else {
88 return -1;
89 }
90}
91
njne9befc62005-06-11 15:51:30 +000092Int VG_(mprotect)( void *start, SizeT length, UInt prot )
93{
94 SysRes res = VG_(mprotect_native)(start, length, prot);
95 if (!res.isError) {
96 VG_(mprotect_range)((Addr)start, length, prot);
97 return 0;
98 } else {
99 return -1;
100 }
101}
102
103void* VG_(get_memory_from_mmap) ( SizeT nBytes, Char* who )
104{
105 static SizeT tot_alloc = 0;
106 void* p;
107 p = VG_(mmap)(0, nBytes,
108 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC,
109 VKI_MAP_PRIVATE|VKI_MAP_ANONYMOUS, 0, -1, 0);
110
111 if (p != ((void*)(-1))) {
112 vg_assert((void*)VG_(valgrind_base) <= p && p <= (void*)VG_(valgrind_last));
113 tot_alloc += nBytes;
114 if (0)
115 VG_(printf)(
116 "get_memory_from_mmap: %llu tot, %llu req = %p .. %p, caller %s\n",
117 (ULong)tot_alloc, (ULong)nBytes, p, ((char*)p) + nBytes - 1, who );
118 return p;
119 }
120
121 VG_(printf)("\n");
122 VG_(printf)("VG_(get_memory_from_mmap): %s's request for %llu bytes failed.\n",
123 who, (ULong)nBytes);
124 VG_(printf)("VG_(get_memory_from_mmap): %llu bytes already allocated.\n",
125 (ULong)tot_alloc);
126 VG_(printf)("\n");
127 VG_(printf)("Sorry. You could try using a tool that uses less memory;\n");
128 VG_(printf)("eg. addrcheck instead of memcheck.\n");
129 VG_(printf)("\n");
130 VG_(exit)(1);
131}
132
njn9260c782005-06-19 21:57:54 +0000133// Returns 0 on failure.
134Addr VG_(get_memory_from_mmap_for_client)
135 (Addr addr, SizeT len, UInt prot, UInt sf_flags)
136{
137 len = VG_PGROUNDUP(len);
138
139 tl_assert(!(sf_flags & SF_FIXED));
140 tl_assert(0 == addr);
141
142 addr = (Addr)VG_(mmap)((void *)addr, len, prot,
143 VKI_MAP_PRIVATE | VKI_MAP_ANONYMOUS | VKI_MAP_CLIENT,
144 sf_flags | SF_CORE, -1, 0);
145 if ((Addr)-1 != addr)
146 return addr;
147 else
148 return 0;
149}
150
151
njne9befc62005-06-11 15:51:30 +0000152/*--------------------------------------------------------------------*/
153/*--- end ---*/
154/*--------------------------------------------------------------------*/
155