new file: .syntastic_cpp_config
[dyninst.git] / proccontrol / src / mmapalloc.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  *
4  * We provide the Paradyn Tools (below described as "Paradyn")
5  * on an AS IS basis, and do not warrant its validity or performance.
6  * We reserve the right to update, modify, or discontinue this
7  * software at any time.  We shall have no obligation to supply such
8  * updates or modifications or any other form of support to you.
9  *
10  * By your use of Paradyn, you understand and agree that we (or any
11  * other person or entity with proprietary rights in Paradyn) are
12  * under no obligation to provide either maintenance services,
13  * update services, notices of latent defects, or correction of
14  * defects for Paradyn.
15  *
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29  */
30
31 #include "common/src/Types.h"
32 #include "mmapalloc.h"
33 #include <sys/mman.h>
34 #include <string.h>
35
36 static const unsigned int linux_x86_64_mmap_flags_position = 26;
37 static const unsigned int linux_x86_64_mmap_size_position = 43;
38 static const unsigned int linux_x86_64_mmap_addr_position = 49;
39 static const unsigned int linux_x86_64_mmap_start_position = 4;
40 static const unsigned char linux_x86_64_call_mmap[] = {
41    0x90, 0x90, 0x90, 0x90,                         //nop,nop,nop,nop
42    0x48, 0x8d, 0x64, 0x24, 0x80,                   //lea    -128(%rsp),%rsp
43    0x49, 0xc7, 0xc0, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0,%r8
44    0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0,%r9
45    0x49, 0xc7, 0xc2, 0x22, 0x00, 0x00, 0x00,       //mov    $0x22,%r10
46    0x48, 0xc7, 0xc2, 0x07, 0x00, 0x00, 0x00,       //mov    $0x7,%rdx
47    0x48, 0x31, 0xf6,                               //xor    %rsi,%rsi
48    0x48, 0xc7, 0xc6, 0x00, 0x00, 0x00, 0x00,       //mov    $<size>,%rsi
49    0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $<addr>,%rdi
50    0x00, 0x00, 0x00,                               //
51    0x48, 0xc7, 0xc0, 0x09, 0x00, 0x00, 0x00,       //mov    $0x9,%rax
52    0x0f, 0x05,                                     //syscall
53    0x48, 0x8d, 0xa4, 0x24, 0x80, 0x00, 0x00, 0x00, //lea    128(%rsp),%rsp
54    0xcc,                                           //Trap
55    0x90                                            //nop
56 };
57 static const unsigned int linux_x86_64_call_mmap_size = sizeof(linux_x86_64_call_mmap);
58
59 static const unsigned int linux_x86_64_munmap_size_position = 15;
60 static const unsigned int linux_x86_64_munmap_addr_position = 21;
61 static const unsigned int linux_x86_64_munmap_start_position = 4;
62 static const unsigned char linux_x86_64_call_munmap[] = {
63    0x90, 0x90, 0x90, 0x90,                         //nop,nop,nop,nop
64    0x48, 0x8d, 0x64, 0x24, 0x80,                   //lea    -128(%rsp),%rsp
65    0x48, 0x31, 0xf6,                               //xor    %rsi,%rsi
66    0x48, 0xc7, 0xc6, 0x00, 0x00, 0x00, 0x00,       //mov    $<size>,%rsi
67    0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $<addr>,%rdi
68    0x00, 0x00, 0x00,                               //
69    0x48, 0xc7, 0xc0, 0x0b, 0x00, 0x00, 0x00,       //mov    $0xb,%rax
70    0x0f, 0x05,                                     //syscall
71    0x48, 0x8d, 0xa4, 0x24, 0x80, 0x00, 0x00, 0x00, //lea    128(%rsp),%rsp
72    0xcc,                                           //Trap
73    0x90                                            //nop
74 };
75 static const unsigned int linux_x86_64_call_munmap_size = sizeof(linux_x86_64_call_munmap);
76
77 static const unsigned int linux_x86_mmap_flags_position = 20;
78 static const unsigned int linux_x86_mmap_size_position = 10;
79 static const unsigned int linux_x86_mmap_addr_position = 5;
80 static const unsigned int linux_x86_mmap_start_position = 4;
81 static const unsigned char linux_x86_call_mmap[] = {
82    0x90, 0x90, 0x90, 0x90,                //nop; nop; nop; nop
83    0xbb, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%ebx  (addr)
84    0xb9, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%ecx  (size)
85    0xba, 0x07, 0x00, 0x00, 0x00,          //mov    $0x7,%edx  (perms)
86    0xbe, 0x22, 0x00, 0x00, 0x00,          //mov    $0x22,%esi (flags)
87    0xbf, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%edi  (fd)
88    0xbd, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%ebp  (offset)
89    0xb8, 0xc0, 0x00, 0x00, 0x00,          //mov    $0xc0,%eax (syscall)
90    0xcd, 0x80,                            //int    $0x80
91    0xcc,                                  //Trap
92    0x90                                   //nop
93 };
94 static const unsigned int linux_x86_call_mmap_size = sizeof(linux_x86_call_mmap);
95
96 static const unsigned int linux_x86_munmap_size_position = 10;
97 static const unsigned int linux_x86_munmap_addr_position = 5;
98 static const unsigned int linux_x86_munmap_start_position = 4;
99 static const unsigned char linux_x86_call_munmap[] = {
100    0x90, 0x90, 0x90, 0x90,                //nop; nop; nop; nop
101    0xbb, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%ebx  (addr)
102    0xb9, 0x00, 0x00, 0x00, 0x00,          //mov    $0x0,%ecx  (size)
103    0xb8, 0xc0, 0x00, 0x00, 0x00,          //mov    $0x5b,%eax (syscall)
104    0xcd, 0x80,                            //int    $0x80
105    0xcc,                                  //Trap
106    0x90                                   //nop
107 };
108 static const unsigned int linux_x86_call_munmap_size = sizeof(linux_x86_call_munmap);
109
110 static const unsigned int linux_ppc32_mmap_flags_hi_position = 34;
111 static const unsigned int linux_ppc32_mmap_flags_lo_position = 38;
112 static const unsigned int linux_ppc32_mmap_size_hi_position = 18;
113 static const unsigned int linux_ppc32_mmap_size_lo_position = 22;
114 static const unsigned int linux_ppc32_mmap_addr_hi_position = 10;
115 static const unsigned int linux_ppc32_mmap_addr_lo_position = 14;
116 static const unsigned int linux_ppc32_mmap_start_position = 4;
117 static const unsigned char linux_ppc32_call_mmap[] = {
118    0x60, 0x00, 0x00, 0x00,            // nop
119    0x38, 0x00, 0x00, 0x5a,            // li      r0,<syscall>
120    0x3c, 0x60, 0x00, 0x00,            // lis     r3,<addr_hi>
121    0x60, 0x63, 0x00, 0x00,            // ori     r3,r3,<addr_lo>
122    0x3c, 0x80, 0x00, 0x00,            // lis     r4,<size_hi>
123    0x60, 0x84, 0x00, 0x00,            // ori     r4,r4,<size_lo>
124    0x3c, 0xa0, 0x00, 0x00,            // lis     r5,<perms_hi>
125    0x60, 0xa5, 0x00, 0x07,            // ori     r5,r5,<perms_lo>
126    0x3c, 0xc0, 0x00, 0x00,            // lis     r6,<flags_hi>
127    0x60, 0xc6, 0x00, 0x00,            // ori     r6,r6,<flags_lo>
128    0x3c, 0xe0, 0xff, 0xff,            // lis     r7,<fd_hi>
129    0x60, 0xe7, 0xff, 0xff,            // ori     r7,r7,<fd_lo>
130    0x3d, 0x00, 0x00, 0x00,            // lis     r8,<offset>
131    0x44, 0x00, 0x00, 0x02,            // sc
132    0x7d, 0x82, 0x10, 0x08,            // trap
133    0x60, 0x00, 0x00, 0x00             // nop
134 };
135 static const unsigned int linux_ppc32_call_mmap_size = sizeof(linux_ppc32_call_mmap);
136
137 static const unsigned int linux_ppc32_munmap_size_hi_position = 18;
138 static const unsigned int linux_ppc32_munmap_size_lo_position = 22;
139 static const unsigned int linux_ppc32_munmap_addr_hi_position = 10;
140 static const unsigned int linux_ppc32_munmap_addr_lo_position = 14;
141 static const unsigned int linux_ppc32_munmap_start_position = 4;
142 static const unsigned char linux_ppc32_call_munmap[] = {
143    0x60, 0x60, 0x60, 0x60,              // nop
144    0x38, 0x00, 0x00, 0x5b,              // li      r0,<syscall>
145    0x3c, 0x60, 0x00, 0x00,              // lis     r3,<addr_hi>
146    0x60, 0x63, 0x00, 0x00,              // ori     r3,r3,<addr_lo>
147    0x3c, 0x80, 0x00, 0x00,              // lis     r4,<size_hi>
148    0x60, 0x84, 0x00, 0x00,              // ori     r4,r4,<size_lo>
149    0x44, 0x00, 0x00, 0x02,              // sc
150    0x7d, 0x82, 0x10, 0x08,              // trap
151    0x60, 0x00, 0x00, 0x00               // nop
152 };
153 static const unsigned int linux_ppc32_call_munmap_size = sizeof(linux_ppc32_call_munmap);
154
155 static const unsigned int linux_ppc64_mmap_flags_highest_position = 70;
156 static const unsigned int linux_ppc64_mmap_flags_higher_position = 74;
157 static const unsigned int linux_ppc64_mmap_flags_hi_position = 82;
158 static const unsigned int linux_ppc64_mmap_flags_lo_position = 86;
159 static const unsigned int linux_ppc64_mmap_size_highest_position = 30;
160 static const unsigned int linux_ppc64_mmap_size_higher_position = 34;
161 static const unsigned int linux_ppc64_mmap_size_hi_position = 42;
162 static const unsigned int linux_ppc64_mmap_size_lo_position = 46;
163 static const unsigned int linux_ppc64_mmap_addr_highest_position = 10;
164 static const unsigned int linux_ppc64_mmap_addr_higher_position = 14;
165 static const unsigned int linux_ppc64_mmap_addr_hi_position = 22;
166 static const unsigned int linux_ppc64_mmap_addr_lo_position = 26;
167 static const unsigned int linux_ppc64_mmap_start_position = 4;
168 static const unsigned char linux_ppc64_call_mmap[] = {
169    0x60, 0x00, 0x00, 0x00,              // nop
170    0x38, 0x00, 0x00, 0x5a,              // li      r0,<syscall>
171    0x3c, 0x60, 0x00, 0x00,              // lis     r3,<addr_highest>
172    0x60, 0x63, 0x00, 0x00,              // ori     r3,r3,<addr_higher>
173    0x78, 0x63, 0x07, 0xc6,              // rldicr  r3,r3,0x32,0x31,
174    0x64, 0x63, 0x00, 0x00,              // oris    r3,r3,<addr_hi>
175    0x60, 0x63, 0x00, 0x00,              // ori     r3,r3,<addr_lo>
176    0x3c, 0x80, 0x00, 0x00,              // lis     r4,<size_highest>
177    0x60, 0x84, 0x00, 0x00,              // ori     r4,r4,<size_higher>
178    0x78, 0x84, 0x07, 0xc6,              // rldicr  r4,r4,0x32,0x31,
179    0x64, 0x84, 0x00, 0x00,              // oris    r4,r4,<size_hi>
180    0x60, 0x84, 0x00, 0x00,              // ori     r4,r4,<size_lo>
181    0x3c, 0xa0, 0x00, 0x00,              // lis     r5,<perms_highest>
182    0x60, 0xa5, 0x00, 0x00,              // ori     r5,r5,<perms_higher>
183    0x78, 0xa5, 0x07, 0xc6,              // rldicr  r5,r5,0x32,0x31,
184    0x64, 0xa5, 0x00, 0x00,              // oris    r5,r5,<perms_hi>
185    0x60, 0xa5, 0x00, 0x07,              // ori     r5,r5,<perms_lo>
186    0x3c, 0xc0, 0x00, 0x00,              // lis     r6,<flags_highest>
187    0x60, 0xc6, 0x00, 0x00,              // ori     r6,r6,<flags_higher>
188    0x78, 0xc6, 0x07, 0xc6,              // rldicr  r6,r6,0x32,0x31,
189    0x64, 0xc6, 0x00, 0x00,              // oris    r6,r6,<flags_hi>
190    0x60, 0xc6, 0x00, 0x00,              // ori     r6,r6,<flags_lo>
191    0x3c, 0xe0, 0x00, 0x00,              // lis     r7,<fd=-1>
192    0x7c, 0xe7, 0x3b, 0xb8,              // nand    r7,r7,r7
193    0x3d, 0x00, 0x00, 0x00,              // lis     r8,<offset>
194    0x44, 0x00, 0x00, 0x02,              // sc
195    0x7d, 0x82, 0x10, 0x08,              // trap
196    0x60, 0x00, 0x00, 0x00               // nop
197 };
198 static const unsigned int linux_ppc64_call_mmap_size = sizeof(linux_ppc64_call_mmap);
199
200 static const unsigned int linux_ppc64_munmap_size_highest_position = 30;
201 static const unsigned int linux_ppc64_munmap_size_higher_position = 34;
202 static const unsigned int linux_ppc64_munmap_size_hi_position = 42;
203 static const unsigned int linux_ppc64_munmap_size_lo_position = 46;
204 static const unsigned int linux_ppc64_munmap_addr_highest_position = 10;
205 static const unsigned int linux_ppc64_munmap_addr_higher_position = 14;
206 static const unsigned int linux_ppc64_munmap_addr_hi_position = 22;
207 static const unsigned int linux_ppc64_munmap_addr_lo_position = 26;
208 static const unsigned int linux_ppc64_munmap_start_position = 4;
209 static const unsigned char linux_ppc64_call_munmap[] = {
210    0x60, 0x00, 0x00, 0x00,              // nop
211    0x38, 0x00, 0x00, 0x5b,              // li      r0,<syscall>
212    0x3c, 0x60, 0x00, 0x00,              // lis     r3,<addr_highest>
213    0x60, 0x63, 0x00, 0x00,              // ori     r3,r3,<addr_higher>
214    0x78, 0x63, 0x07, 0xc6,              // rldicr  r3,r3,0x32,0x31,
215    0x64, 0x63, 0x00, 0x00,              // oris    r3,r3,<addr_hi>
216    0x60, 0x63, 0x00, 0x00,              // ori     r3,r3,<addr_lo>
217    0x3c, 0x80, 0x00, 0x00,              // lis     r4,<size_highest>
218    0x60, 0x84, 0x00, 0x00,              // ori     r4,r4,<size_higher>
219    0x78, 0x84, 0x07, 0xc6,              // rldicr  r4,r4,0x32,0x31,
220    0x64, 0x84, 0x00, 0x00,              // oris    r4,r4,<size_hi>
221    0x60, 0x84, 0x00, 0x00,              // ori     r4,r4,<size_lo>
222    0x44, 0x00, 0x00, 0x02,              // sc
223    0x7d, 0x82, 0x10, 0x08,              // trap
224    0x60, 0x00, 0x00, 0x00               // nop
225 };
226 static const unsigned int linux_ppc64_call_munmap_size = sizeof(linux_ppc64_call_munmap);
227
228 //aarch64
229 //mov
230 //31-21 | 20 - 5 | 4 - 0
231 //      | imm    | reg
232 static const unsigned int linux_aarch64_mmap_flags_position = 36;
233 static const unsigned int linux_aarch64_mmap_size_position =  20;
234 static const unsigned int linux_aarch64_mmap_addr_position =  4;
235 static const unsigned int linux_aarch64_mmap_start_position = 4;
236 static const unsigned char linux_aarch64_call_mmap[] = {
237     // _NR_mmap 1058
238     0xd5, 0x03, 0x20, 0x1f,         // nop              ;mmap(void *addr, size_t size, int _prot,
239                                     //                  ;   int _flags, int _fd, _off_t offset)
240     0xd2, 0x80, 0x00, 0x00,         // mov x0, #0           ;<addr>
241     0xf2, 0xa0, 0x00, 0x00,         // movk x0, #0, lsl #16     ;<addr>
242     0xf2, 0xc0, 0x00, 0x00,         // movk x0, #0, lsl #32     ;<addr>
243     0xf2, 0xe0, 0x00, 0x00,         // movk x0, #0, lsl #48     ;<addr>
244
245     0xd2, 0x80, 0x00, 0x01,         // mov x1, #0               ;<size>
246     0xf2, 0xa0, 0x00, 0x01,         // movk x1, #0, lsl #16      ;<size>
247     0xf2, 0xc0, 0x00, 0x01,         // movk x1, #0, lsl #32      ;<size>
248     0xf2, 0xe0, 0x00, 0x01,         // movk x1, #0, lsl #48      ;<size>
249
250     0xd2, 0x80, 0x00, 0x03,         // mov x3, #0x00            ;<flags>
251     0xf2, 0xa0, 0x00, 0x03,         // movk x3, #0x00, lsl #16      ;<flags>
252     //0xf2, 0xc0, 0x00, 0x03,         // mov x3, #0x00, lsl #32      ;<flags>
253     //0xf2, 0xe0, 0x00, 0x03,         // mov x3, #0x00, lsl #48      ;<flags>
254
255     0xd2, 0x80, 0x00, 0xe2,             // mov x2, #0x7     ;<prot>
256     0xd2, 0x80, 0x00, 0x04,             // mov x4  #0       ;fd
257     0xd2, 0x80, 0x00, 0x05,             // mov x5, #0       ;offset
258     0xd2, 0x80, 0x84, 0x48,             // mov x8, #d1058   ;pass sys call number
259     0xd4, 0x00, 0x00, 0x01,             // svc #0           ;system call
260     0xd4, 0x20, 0x00, 0x00,             // brk #0           ;trap?
261     0xd5, 0x03, 0x20, 0x1f              // nop
262 };
263 static const unsigned int linux_aarch64_call_mmap_size = sizeof(linux_aarch64_call_mmap);
264
265 static const unsigned int linux_aarch64_munmap_size_position = 20;
266 static const unsigned int linux_aarch64_munmap_addr_position =  4;
267 static const unsigned int linux_aarch64_munmap_start_position = 4;
268 static const unsigned char linux_aarch64_call_munmap[] = {
269     0xd5, 0x03, 0x20, 0x1f,             // nop              ;munmap(void *addr, int size)
270     0xd2, 0x80, 0x00, 0x00,         // mov x0, #0       ;&addr
271     0xf2, 0xa0, 0x00, 0x00,         // mov x0, #0, lsl #16     ;<addr>
272     0xf2, 0xc0, 0x00, 0x00,         // mov x0, #0, lsl #32     ;<addr>
273     0xf2, 0xe0, 0x00, 0x00,         // mov x0, #0, lsl #48     ;<addr>
274
275     0xd2, 0x80, 0x00, 0x01,         // mov x1, #0               ;size
276     0xf2, 0xa0, 0x00, 0x01,         // mov x1, #0, lsl #16      ;<size>
277     0xf2, 0xc0, 0x00, 0x01,         // mov x1, #0, lsl #32      ;<size>
278     0xf2, 0xe0, 0x00, 0x01,         // mov x1, #0, lsl #48      ;<size>
279
280     0xd2, 0x80, 0x1a, 0xe8,         // mov x8, #d215    ;pass sys call number
281     0xd4, 0x00, 0x00, 0x01,             // svc #0
282     0xd4, 0x20, 0x00, 0x00,             // brk #0
283     0xd5, 0x03, 0x20, 0x1f              // nop
284 };
285 static const unsigned int linux_aarch64_call_munmap_size = sizeof(linux_aarch64_call_munmap);
286
287 static const unsigned int freebsd_x86_64_mmap_flags_position = 21;
288 static const unsigned int freebsd_x86_64_mmap_size_position = 34;
289 static const unsigned int freebsd_x86_64_mmap_addr_position = 44;
290 static const unsigned int freebsd_x86_64_mmap_start_position = 4;
291 static const unsigned char freebsd_x86_64_call_mmap[] = {
292    0x90, 0x90, 0x90, 0x90,                         //nop sled
293    0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0,%r9 (offset)
294    0x49, 0xc7, 0xc0, 0xff, 0xff, 0xff, 0xff,       //mov    $0xffffffffffffffff,%r8 (fd)
295    0x49, 0xc7, 0xc2, 0x12, 0x10, 0x00, 0x00,       //mov    $0x1012,%r10 (flags)
296    0x48, 0xc7, 0xc2, 0x07, 0x00, 0x00, 0x00,       //mov    $0x7,%rdx (perms)
297    0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi (size)
298    0x00, 0x00, 0x00,                               //
299    0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi (addr)
300    0x00, 0x00, 0x00,                               //
301    0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
302    0x0f, 0x05,                                     //syscall
303    0xcc,                                           //trap
304    0x90                                            //nop
305 };
306 static const unsigned int freebsd_x86_64_call_mmap_size = sizeof(freebsd_x86_64_call_mmap);
307
308 static const unsigned int freebsd_x86_64_munmap_size_position = 6;
309 static const unsigned int freebsd_x86_64_munmap_addr_position = 16;
310 static const unsigned int freebsd_x86_64_munmap_start_position = 4;
311 static const unsigned char freebsd_x86_64_call_munmap[] = {
312    0x90, 0x90, 0x90, 0x90,                         //nop sled
313    0x48, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rsi
314    0x00, 0x00, 0x00,                               //
315    0x48, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00,       //mov    $0x0000000000000000,%rdi
316    0x00, 0x00, 0x00,                               //
317    0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax
318    0x0f, 0x05,                                     //syscall
319    0xcc,                                           //trap
320    0x90                                            //nop
321 };
322 static const unsigned int freebsd_x86_64_call_munmap_size = sizeof(freebsd_x86_64_call_munmap);
323
324 static const unsigned int freebsd_x86_mmap_flags_position = 9;
325 static const unsigned int freebsd_x86_mmap_size_position = 16;
326 static const unsigned int freebsd_x86_mmap_addr_position = 21;
327 static const unsigned int freebsd_x86_mmap_start_position = 4;
328 static const unsigned char freebsd_x86_call_mmap[] = {
329    0x90, 0x90, 0x90, 0x90,                         //nop sled
330    0x6a, 0x00,                                     //push   $0x0 (offset)
331    0x6a, 0xff,                                     //push   $0xffffffff (fd)
332    0x68, 0x12, 0x10, 0x00, 0x00,                   //push   $0x1012 (flags)
333    0x6a, 0x07,                                     //push   $0x7 (perms)
334    0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)
335    0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
336    0xb8, 0xdd, 0x01, 0x00, 0x00,                   //mov    $0x1dd,%eax (SYS_mmap)
337    0x50,                                           //push   %eax (required by calling convention)
338    0xcd, 0x80,                                     //int    $0x80
339    0x8d, 0x64, 0x24, 0x1c,                         //lea    0x1c(%esp),%esp
340    0xcc,                                           //trap
341    0x90                                            //nop
342 };
343 static const unsigned int freebsd_x86_call_mmap_size = sizeof(freebsd_x86_call_mmap);
344
345 static const unsigned int freebsd_x86_munmap_size_position = 5;
346 static const unsigned int freebsd_x86_munmap_addr_position = 10;
347 static const unsigned int freebsd_x86_munmap_start_position = 4;
348 static const unsigned char freebsd_x86_call_munmap[] = {
349    0x90, 0x90, 0x90, 0x90,                         //nop sled
350    0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (size)
351    0x68, 0x00, 0x00, 0x00, 0x00,                   //push   $0x0 (addr)
352    0xb8, 0x49, 0x00, 0x00, 0x00,                   //mov    $0x49,%eax (SYS_munmap)
353    0x50,                                           //push   %eax (required by calling convention)
354    0xcd, 0x80,                                     //int    $0x80
355    0x8d, 0x64, 0x24, 0x0c,                         //lea    0xc(%esp),%esp
356    0xcc,                                           //trap
357    0x90                                            //nop
358 };
359 static const unsigned int freebsd_x86_call_munmap_size = sizeof(freebsd_x86_call_munmap);
360
361 mmap_alloc_process::mmap_alloc_process(Dyninst::PID p, std::string e, std::vector<std::string> a,
362                                        std::vector<std::string> envp, std::map<int,int> f) :
363    int_process(p, e, a, envp, f)
364 {
365 }
366
367 mmap_alloc_process::mmap_alloc_process(Dyninst::PID pid_, int_process *p) :
368    int_process(pid_, p)
369 {
370 }
371
372 mmap_alloc_process::~mmap_alloc_process()
373 {
374 }
375
376 // For compatibility
377 #ifndef MAP_ANONYMOUS
378 #define MAP_ANONYMOUS MAP_ANON
379 #endif
380
381 bool mmap_alloc_process::plat_collectAllocationResult(int_thread *thr, reg_response::ptr resp)
382 {
383     switch (getTargetArch())
384     {
385         case Arch_x86_64: {
386             bool result = thr->getRegister(x86_64::rax, resp);
387             assert(result);
388             if(!result) return false;
389             break;
390         }
391         case Arch_x86: {
392             bool result = thr->getRegister(x86::eax, resp);
393             assert(result);
394             if(!result) return false;
395             break;
396         }
397         case Arch_ppc32: {
398             bool result = thr->getRegister(ppc32::r3, resp);
399             assert(result);
400             if(!result) return false;
401             break;
402         }
403         case Arch_ppc64: {
404             bool result = thr->getRegister(ppc64::r3, resp);
405             assert(result);
406                 if(!result) return false;
407             break;
408         }
409         case Arch_aarch64: {
410             bool result = thr->getRegister(aarch64::x0, resp);
411             pthrd_printf("ARM-info: createAllocaResult... \n");
412             assert(result);
413                     if(!result) return false;
414             break;
415         }
416         default:
417             assert(0);
418             break;
419     }
420     return true;
421 }
422
423 bool mmap_alloc_process::plat_createAllocationSnippet(Dyninst::Address addr, bool use_addr, unsigned long size,
424                                                       void* &buffer, unsigned long &buffer_size,
425                                                       unsigned long &start_offset)
426 {
427     int flags = MAP_ANONYMOUS | MAP_PRIVATE;
428     if (use_addr)
429         flags |= MAP_FIXED;
430     else
431         addr = 0x0;
432
433     if (getTargetArch() == Arch_x86_64 || getTargetArch() == Arch_x86) {
434         const void *buf_tmp = NULL;
435         unsigned addr_size = 0;
436         unsigned addr_pos = 0;
437         unsigned flags_pos = 0;
438         unsigned size_pos = 0;
439
440         bool use_linux = (getOS() == Dyninst::Linux);
441         bool use_bsd = (getOS() == Dyninst::FreeBSD);
442         bool use_64 = (getTargetArch() == Arch_x86_64);
443
444         if (use_linux && use_64) {
445            buf_tmp = linux_x86_64_call_mmap;
446            buffer_size = linux_x86_64_call_mmap_size;
447            start_offset = linux_x86_64_mmap_start_position;
448            addr_pos = linux_x86_64_mmap_addr_position;
449            flags_pos = linux_x86_64_mmap_flags_position;
450            size_pos = linux_x86_64_mmap_size_position;
451            addr_size = 8;
452         }
453         else if (use_bsd && use_64) {
454            buf_tmp = freebsd_x86_64_call_mmap;
455            buffer_size = freebsd_x86_64_call_mmap_size;
456            start_offset = freebsd_x86_64_mmap_start_position;
457            addr_pos = freebsd_x86_64_mmap_addr_position;
458            flags_pos = freebsd_x86_64_mmap_flags_position;
459            size_pos = freebsd_x86_64_mmap_size_position;
460            addr_size = 8;
461         }
462         else if (use_linux && !use_64) {
463            buf_tmp = linux_x86_call_mmap;
464            buffer_size = linux_x86_call_mmap_size;
465            start_offset = linux_x86_mmap_start_position;
466            addr_pos = linux_x86_mmap_addr_position;
467            flags_pos = linux_x86_mmap_flags_position;
468            size_pos = linux_x86_mmap_size_position;
469            addr_size = 4;
470         }
471         else if (use_bsd && !use_64) {
472            buf_tmp = freebsd_x86_call_mmap;
473            buffer_size = freebsd_x86_call_mmap_size;
474            start_offset = freebsd_x86_mmap_start_position;
475            addr_pos = freebsd_x86_mmap_addr_position;
476            flags_pos = freebsd_x86_mmap_flags_position;
477            size_pos = freebsd_x86_mmap_size_position;
478            addr_size = 4;
479         }
480         else {
481            assert(0); //Fill in the entry in mmapalloc.h for this system
482         }
483
484         buffer = malloc(buffer_size);
485         memcpy(buffer, buf_tmp, buffer_size);
486
487         //Assuming endianess of debugger and debugee match.
488         *((unsigned int *) (((char *) buffer)+size_pos)) = size;
489         *((unsigned int *) (((char *) buffer)+flags_pos)) = flags;
490         if (addr_size == 8)
491             *((unsigned long *) (((char *) buffer)+addr_pos)) = addr;
492         else if (addr_size == 4)
493             *((unsigned *) (((char *) buffer)+addr_pos)) = (unsigned) addr;
494         else
495             assert(0);
496    }
497     else  if (getTargetArch() == Arch_ppc32) {
498         unsigned int flags_hi_position;
499         unsigned int flags_lo_position;
500         unsigned int size_hi_position;
501         unsigned int size_lo_position;
502         unsigned int addr_hi_position;
503         unsigned int addr_lo_position;
504         const void *buf_tmp;
505
506         //BlueGene can share the linux allocation snippet.
507         bool use_linux = (getOS() == Linux || getOS() == BlueGeneP || getOS() == BlueGeneL);
508
509         if (use_linux) {
510            flags_hi_position = linux_ppc32_mmap_flags_hi_position;
511            flags_lo_position = linux_ppc32_mmap_flags_lo_position;
512            size_hi_position = linux_ppc32_mmap_size_hi_position;
513            size_lo_position = linux_ppc32_mmap_size_lo_position;
514            addr_hi_position = linux_ppc32_mmap_addr_hi_position;
515            addr_lo_position = linux_ppc32_mmap_addr_lo_position;
516            start_offset = linux_ppc32_mmap_start_position;
517            buffer_size = linux_ppc32_call_mmap_size;
518            buf_tmp = linux_ppc32_call_mmap;
519         }
520         else {
521            assert(0); //Fill in the entry in mmapalloc.h for this system
522         }
523
524         buffer = malloc(buffer_size);
525         memcpy(buffer, buf_tmp, buffer_size);
526
527         // Assuming endianess of debugger and debuggee match
528         *((uint16_t *) (((char *) buffer)+size_hi_position)) = (uint16_t)(size >> 16);
529         *((uint16_t *) (((char *) buffer)+size_lo_position)) = (uint16_t)size;
530         *((uint16_t *) (((char *) buffer)+flags_hi_position)) = (uint16_t)(flags >> 16);
531         *((uint16_t *) (((char *) buffer)+flags_lo_position)) = (uint16_t)flags;
532         *((uint16_t *) (((char *) buffer)+addr_hi_position)) = (uint16_t)(addr >> 16);
533         *((uint16_t *) (((char *) buffer)+addr_lo_position)) = (uint16_t)addr;
534    }
535    else if (getTargetArch() == Arch_ppc64) {
536       unsigned int flags_highest_position;
537       unsigned int flags_higher_position;
538       unsigned int flags_hi_position;
539       unsigned int flags_lo_position;
540       unsigned int size_highest_position;
541       unsigned int size_higher_position;
542       unsigned int size_hi_position;
543       unsigned int size_lo_position;
544       unsigned int addr_highest_position;
545       unsigned int addr_higher_position;
546       unsigned int addr_hi_position;
547       unsigned int addr_lo_position;
548       const void *buf_tmp;
549
550       //BlueGene can share the linux allocation snippet.
551       bool use_linux = (getOS() == Linux || getOS() == BlueGeneQ);
552
553       if (use_linux) {
554          flags_highest_position = linux_ppc64_mmap_flags_highest_position;
555          flags_higher_position = linux_ppc64_mmap_flags_higher_position;
556          flags_hi_position = linux_ppc64_mmap_flags_hi_position;
557          flags_lo_position = linux_ppc64_mmap_flags_lo_position;
558          size_highest_position = linux_ppc64_mmap_size_highest_position;
559          size_higher_position = linux_ppc64_mmap_size_higher_position;
560          size_hi_position = linux_ppc64_mmap_size_hi_position;
561          size_lo_position = linux_ppc64_mmap_size_lo_position;
562          addr_highest_position = linux_ppc64_mmap_addr_highest_position;
563          addr_higher_position = linux_ppc64_mmap_addr_higher_position;
564          addr_hi_position = linux_ppc64_mmap_addr_hi_position;
565          addr_lo_position = linux_ppc64_mmap_addr_lo_position;
566          start_offset = linux_ppc64_mmap_start_position;
567          buffer_size = linux_ppc64_call_mmap_size;
568          buf_tmp = linux_ppc64_call_mmap;
569       }
570       else {
571          assert(0); //Fill in the entry in mmapalloc.h for this system
572       }
573       buffer = malloc(buffer_size);
574       memcpy(buffer, buf_tmp, buffer_size);
575
576
577        // Assuming endianess of debugger and debuggee match
578        *((uint16_t *) (((char *) buffer)+size_highest_position)) = (uint16_t)((uint64_t)size >> 48);
579        *((uint16_t *) (((char *) buffer)+size_higher_position)) = (uint16_t)((uint64_t)size >> 32);
580        *((uint16_t *) (((char *) buffer)+size_hi_position)) = (uint16_t)(size >> 16);
581        *((uint16_t *) (((char *) buffer)+size_lo_position)) = (uint16_t)size;
582        *((uint16_t *) (((char *) buffer)+flags_highest_position)) = (uint16_t)((uint64_t)flags >> 48);
583        *((uint16_t *) (((char *) buffer)+flags_higher_position)) = (uint16_t)((uint64_t)flags >> 32);
584        *((uint16_t *) (((char *) buffer)+flags_hi_position)) = (uint16_t)(flags >> 16);
585        *((uint16_t *) (((char *) buffer)+flags_lo_position)) = (uint16_t)flags;
586        *((uint16_t *) (((char *) buffer)+addr_highest_position)) = (uint16_t)((uint64_t)addr >> 48);
587        *((uint16_t *) (((char *) buffer)+addr_higher_position)) = (uint16_t)((uint64_t)addr >> 32);
588        *((uint16_t *) (((char *) buffer)+addr_hi_position)) = (uint16_t)(addr >> 16);
589        *((uint16_t *) (((char *) buffer)+addr_lo_position)) = (uint16_t)addr;
590
591     }else if( getTargetArch() == Arch_aarch64 ){
592         const void *buf_tmp;
593         unsigned int addr_size;
594         unsigned int addr_pos, size_pos, flags_pos;
595
596         bool use_linux = ( getOS() == Linux );
597
598         if (use_linux) {
599            start_offset             = linux_aarch64_mmap_start_position;
600            buffer_size              = linux_aarch64_call_mmap_size;
601            buf_tmp                  = linux_aarch64_call_mmap;
602            addr_pos                 = linux_aarch64_mmap_addr_position;
603            size_pos                 = linux_aarch64_mmap_size_position;
604            flags_pos                = linux_aarch64_mmap_flags_position;
605            addr_size = 8;
606         }
607         else {
608            assert(0); //Fill in the entry in mmapalloc.h for this system
609         }
610         buffer = malloc(buffer_size);
611         memcpy(buffer, buf_tmp, buffer_size);
612
613         // To avoid the matter of endianness, I decided to operate on byte.
614         pthrd_printf("ARM-info: create alloc snippet...\n");
615 #define BYTE_ASSGN(POS, VAL)\
616         (*(((char *) buffer) + POS + 1)) |= ((VAL>>11)&0x1f);\
617         (*(((char *) buffer) + POS + 2)) |= ((VAL>> 3)&0xff);\
618         (*(((char *) buffer) + POS + 3)) |= ((VAL<< 5)&0xf0);
619
620         BYTE_ASSGN(addr_pos,    (uint16_t)(addr)     )
621         BYTE_ASSGN(addr_pos+4,  (uint16_t)(addr>>16) )
622         BYTE_ASSGN(addr_pos+8,  (uint16_t)(addr>>32) )
623         BYTE_ASSGN(addr_pos+12, (uint16_t)(addr>>48) )
624
625         BYTE_ASSGN(size_pos,    (uint16_t)(size) )
626         BYTE_ASSGN(size_pos+4,  (uint16_t)(size>>16) )
627         BYTE_ASSGN(size_pos+8,  (uint16_t)(size>>32) )
628         BYTE_ASSGN(size_pos+12, (uint16_t)(size>>48) )
629
630         BYTE_ASSGN(flags_pos,    (uint16_t)(flags) )
631         BYTE_ASSGN(flags_pos+4,  (uint16_t)(flags>>16) )
632
633         assert(addr_size == 8);
634
635     }else{
636         assert(0);
637     }
638
639     return true;
640 }
641
642 bool mmap_alloc_process::plat_createDeallocationSnippet(Dyninst::Address addr,
643                                                         unsigned long size, void* &buffer,
644                                                         unsigned long &buffer_size,
645                                                         unsigned long &start_offset)
646 {
647    if (getTargetArch() == Arch_x86_64 || getTargetArch() == Arch_x86) {
648        const void *buf_tmp = NULL;
649        unsigned addr_size = 0;
650        unsigned addr_pos = 0;
651        unsigned size_pos = 0;
652
653        bool use_linux = (getOS() == Dyninst::Linux);
654        bool use_bsd = (getOS() == Dyninst::FreeBSD);
655        bool use_64 = (getTargetArch() == Arch_x86_64);
656
657        if (use_linux && use_64) {
658           buf_tmp = linux_x86_64_call_munmap;
659           buffer_size = linux_x86_64_call_munmap_size;
660           start_offset = linux_x86_64_munmap_start_position;
661           addr_pos = linux_x86_64_munmap_addr_position;
662           size_pos = linux_x86_64_munmap_size_position;
663           addr_size = 8;
664        }
665        else if (use_bsd && use_64) {
666           buf_tmp = freebsd_x86_64_call_munmap;
667           buffer_size = freebsd_x86_64_call_munmap_size;
668           start_offset = freebsd_x86_64_munmap_start_position;
669           addr_pos = freebsd_x86_64_munmap_addr_position;
670           size_pos = freebsd_x86_64_munmap_size_position;
671           addr_size = 8;
672        }
673        else if (use_linux && !use_64) {
674           buf_tmp = linux_x86_call_munmap;
675           buffer_size = linux_x86_call_munmap_size;
676           start_offset = linux_x86_munmap_start_position;
677           addr_pos = linux_x86_munmap_addr_position;
678           size_pos = linux_x86_munmap_size_position;
679           addr_size = 4;
680        }
681        else if (use_bsd && !use_64) {
682           buf_tmp = freebsd_x86_call_munmap;
683           buffer_size = freebsd_x86_call_munmap_size;
684           start_offset = freebsd_x86_munmap_start_position;
685           addr_pos = freebsd_x86_munmap_addr_position;
686           size_pos = freebsd_x86_munmap_size_position;
687           addr_size = 4;
688        }
689        else {
690           assert(0);
691        }
692
693        buffer = malloc(buffer_size);
694        memcpy(buffer, buf_tmp, buffer_size);
695
696        //Assuming endianess of debugger and debugee match.
697        *((unsigned int *) (((char *) buffer)+size_pos)) = size;
698        if (addr_size == 8)
699           *((unsigned long *) (((char *) buffer)+addr_pos)) = addr;
700        else if (addr_size == 4)
701           *((unsigned *) (((char *) buffer)+addr_pos)) = (unsigned) addr;
702        else
703           assert(0);
704    }
705    else if (getTargetArch() == Arch_ppc32) {
706       unsigned int size_hi_position;
707       unsigned int size_lo_position;
708       unsigned int addr_hi_position;
709       unsigned int addr_lo_position;
710       const void *buf_tmp = NULL;
711
712       bool use_linux = (getOS() == Linux || getOS() == BlueGeneP || getOS() == BlueGeneL);
713       if (use_linux) {
714          buf_tmp = linux_ppc32_call_munmap;
715          size_hi_position = linux_ppc32_munmap_size_hi_position;
716          size_lo_position = linux_ppc32_munmap_size_lo_position;
717          addr_hi_position = linux_ppc32_munmap_addr_hi_position;
718          addr_lo_position = linux_ppc32_munmap_addr_lo_position;
719          buffer_size = linux_ppc32_call_munmap_size;
720          start_offset = linux_ppc32_munmap_start_position;
721       }
722       else {
723          assert(0);
724       }
725
726        buffer = malloc(buffer_size);
727        memcpy(buffer, buf_tmp, buffer_size);
728
729        // Assuming endianess of debugger and debuggee match
730        *((uint16_t *) (((char *) buffer)+size_hi_position)) = (uint16_t)(size >> 16);
731        *((uint16_t *) (((char *) buffer)+size_lo_position)) = (uint16_t)size;
732        *((uint16_t *) (((char *) buffer)+addr_hi_position)) = (uint16_t)(addr >> 16);
733        *((uint16_t *) (((char *) buffer)+addr_lo_position)) = (uint16_t)addr;
734    }
735    else if( getTargetArch() == Arch_ppc64 ) {
736       unsigned int size_highest_position;
737       unsigned int size_higher_position;
738       unsigned int size_hi_position;
739       unsigned int size_lo_position;
740       unsigned int addr_highest_position;
741       unsigned int addr_higher_position;
742       unsigned int addr_hi_position;
743       unsigned int addr_lo_position;
744       const void *buf_tmp = NULL;
745
746       bool use_linux = (getOS() == Linux || getOS() == BlueGeneQ);
747       if (use_linux) {
748          buf_tmp = linux_ppc64_call_munmap;
749          size_highest_position = linux_ppc64_munmap_size_highest_position;
750          size_higher_position = linux_ppc64_munmap_size_higher_position;
751          size_hi_position = linux_ppc64_munmap_size_hi_position;
752          size_lo_position = linux_ppc64_munmap_size_lo_position;
753          addr_highest_position = linux_ppc64_munmap_addr_highest_position;
754          addr_higher_position = linux_ppc64_munmap_addr_higher_position;
755          addr_hi_position = linux_ppc64_munmap_addr_hi_position;
756          addr_lo_position = linux_ppc64_munmap_addr_lo_position;
757          buffer_size = linux_ppc64_call_munmap_size;
758          start_offset = linux_ppc64_munmap_start_position;
759       }
760       else {
761          assert(0);
762       }
763
764       buffer = malloc(buffer_size);
765       memcpy(buffer, buf_tmp, buffer_size);
766
767       // Assuming endianess of debugger and debuggee match
768       *((uint16_t *) (((char *) buffer)+size_highest_position)) = (uint16_t)((uint64_t)size >> 48);
769       *((uint16_t *) (((char *) buffer)+size_higher_position)) = (uint16_t)((uint64_t)size >> 32);
770       *((uint16_t *) (((char *) buffer)+size_hi_position)) = (uint16_t)(size >> 16);
771       *((uint16_t *) (((char *) buffer)+size_lo_position)) = (uint16_t)size;
772       *((uint16_t *) (((char *) buffer)+addr_highest_position)) = (uint16_t)((uint64_t)addr >> 48);
773       *((uint16_t *) (((char *) buffer)+addr_higher_position)) = (uint16_t)((uint64_t)addr >> 32);
774       *((uint16_t *) (((char *) buffer)+addr_hi_position)) = (uint16_t)(addr >> 16);
775       *((uint16_t *) (((char *) buffer)+addr_lo_position)) = (uint16_t)addr;
776    }
777    else if( getTargetArch() == Arch_aarch64 ) {
778         const void *buf_tmp = NULL;
779         unsigned int addr_size;
780         unsigned int addr_pos;
781         unsigned int size_pos;
782
783         bool use_linux = (getOS() == Linux );
784         if (use_linux) {
785             buf_tmp             = linux_aarch64_call_munmap;
786             buffer_size         = linux_aarch64_call_munmap_size;
787             start_offset        = linux_aarch64_munmap_start_position;
788             addr_pos            = linux_aarch64_munmap_addr_position;
789             size_pos            = linux_aarch64_munmap_size_position;
790             addr_size           = 8;
791         }
792         else {
793            assert(0);
794         }
795
796         buffer = malloc(buffer_size);
797         memcpy(buffer, buf_tmp, buffer_size);
798
799         pthrd_printf("ARM-info: create de-alloc snippet...\n");
800
801         BYTE_ASSGN(addr_pos,    (uint16_t)(addr)     )
802         BYTE_ASSGN(addr_pos+4,  (uint16_t)(addr>>16) )
803         BYTE_ASSGN(addr_pos+8,  (uint16_t)(addr>>32) )
804         BYTE_ASSGN(addr_pos+12, (uint16_t)(addr>>48) )
805
806         BYTE_ASSGN(size_pos,    (uint16_t)(size) )
807         BYTE_ASSGN(size_pos+4,  (uint16_t)(size>>16) )
808         BYTE_ASSGN(size_pos+8,  (uint16_t)(size>>32) )
809         BYTE_ASSGN(size_pos+12, (uint16_t)(size>>48) )
810
811         // Assuming endianess of debugger and debuggee match
812         assert(addr_size == 8);
813    }
814    else {
815       assert(0);
816    }
817
818    return true;
819 }