• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From c050505bbee806f7389d1c7360eef08d6a39aad6 Mon Sep 17 00:00:00 2001
2From: Zhu Guodong <zhuguodong0001@163.com>
3Date: Fri, 10 May 2024 18:33:50 +0800
4Subject: [PATCH] mockcpp patch
5
6---
7 include/mockcpp/JmpCode.h |  1 +
8 include/mockcpp/mockcpp.h |  6 +++-
9 src/JmpCode.cpp           | 16 ++++++++-
10 src/JmpCodeAARCH64.h      | 69 +++++++++++++++++++++++++++++++++++++++
11 src/JmpCodeARM32.h        | 36 ++++++++++++++++++++
12 src/JmpCodeArch.h         | 20 +++++++++++-
13 src/JmpCodeX64.h          |  3 +-
14 src/JmpCodeX86.h          |  3 +-
15 src/JmpOnlyApiHook.cpp    |  1 +
16 src/UnixCodeModifier.cpp  |  2 ++
17 10 files changed, 152 insertions(+), 5 deletions(-)
18 create mode 100644 src/JmpCodeAARCH64.h
19 create mode 100644 src/JmpCodeARM32.h
20
21diff --git a/include/mockcpp/JmpCode.h b/include/mockcpp/JmpCode.h
22index 26f77b0..ed0fac6 100644
23--- a/include/mockcpp/JmpCode.h
24+++ b/include/mockcpp/JmpCode.h
25@@ -33,6 +33,7 @@ struct JmpCode
26
27     void*  getCodeData() const;
28     size_t getCodeSize() const;
29+    void flushCache() const;
30 private:
31 	JmpCodeImpl* This;
32 };
33diff --git a/include/mockcpp/mockcpp.h b/include/mockcpp/mockcpp.h
34index 306bc7a..8cc385d 100644
35--- a/include/mockcpp/mockcpp.h
36+++ b/include/mockcpp/mockcpp.h
37@@ -39,7 +39,11 @@
38 #endif
39
40
41-#if  ( defined (__LP64__) \
42+#if  defined (__aarch64__)
43+#define BUILD_FOR_AARCH64
44+#elif defined (__arm__)
45+#define BUILD_FOR_ARM32
46+#elif ( defined (__LP64__) \
47     || defined (__64BIT__) \
48     || defined (_LP64) \
49     || ((defined(__WORDSIZE)) && (__WORDSIZE == 64)) \
50diff --git a/src/JmpCode.cpp b/src/JmpCode.cpp
51index 35794fb..6aac228 100644
52--- a/src/JmpCode.cpp
53+++ b/src/JmpCode.cpp
54@@ -30,6 +30,7 @@ struct JmpCodeImpl
55    ////////////////////////////////////////////////
56    JmpCodeImpl(const void* from, const void* to)
57    {
58+      m_from = from;
59       ::memcpy(m_code, jmpCodeTemplate, JMP_CODE_SIZE);
60       SET_JMP_CODE(m_code, from, to);
61    }
62@@ -47,7 +48,14 @@ struct JmpCodeImpl
63    }
64
65    ////////////////////////////////////////////////
66+   void flushCache() const
67+   {
68+      FLUSH_CACHE((const char *)m_from, JMP_CODE_SIZE);
69+   }
70
71+   ////////////////////////////////////////////////
72+
73+   const void *m_from;
74    unsigned char m_code[JMP_CODE_SIZE];
75 };
76
77@@ -77,5 +85,11 @@ JmpCode::getCodeSize() const
78    return This->getCodeSize();
79 }
80
81-MOCKCPP_NS_END
82+///////////////////////////////////////////////////
83+void
84+JmpCode::flushCache() const
85+{
86+   return This->flushCache();
87+}
88
89+MOCKCPP_NS_END
90diff --git a/src/JmpCodeAARCH64.h b/src/JmpCodeAARCH64.h
91new file mode 100644
92index 0000000..4f5e90b
93--- /dev/null
94+++ b/src/JmpCodeAARCH64.h
95@@ -0,0 +1,69 @@
96+/***
97+   mockcpp is a C/C++ mock framework.
98+   Copyright [2008] [Darwin Yuan <darwin.yuan@gmail.com>]
99+                    [Chen Guodong <sinojelly@gmail.com>]
100+   Licensed under the Apache License, Version 2.0 (the "License");
101+   you may not use this file except in compliance with the License.
102+   You may obtain a copy of the License at
103+
104+      http://www.apache.org/licenses/LICENSE-2.0
105+
106+   Unless required by applicable law or agreed to in writing, software
107+   distributed under the License is distributed on an "AS IS" BASIS,
108+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
109+   See the License for the specific language governing permissions and
110+   limitations under the License.
111+***/
112+#ifndef __MOCKCPP_JMP_CODE_AARCH64_H__
113+#define __MOCKCPP_JMP_CODE_AARCH64_H__
114+
115+#include <asm/unistd.h>
116+#include <errno.h>
117+#include <fcntl.h>
118+#include <stdio.h>
119+#include <stdlib.h>
120+#include <sys/ioctl.h>
121+#include <sys/mman.h>
122+#include <sys/prctl.h>
123+#include <sys/stat.h>
124+#include <sys/syscall.h>
125+
126+MOCKCPP_NS_START
127+
128+struct l2cache_addr_range {
129+   uintptr_t start;
130+   uintptr_t end;
131+};
132+
133+MOCKCPP_NS_END
134+
135+#define ADDR_ALIGN_UP(addr) ((((addr) + ((4096) - 1)) & (~((4096) - 1))) & 0xffffffffffffffff)
136+#define ADDR_ALIGN_DOWN(addr) (((addr) & (~((4096) - 1))) & 0xffffffffffffffff)
137+#define OUTER_CACHE_INV_RANGE _IOWR('S', 0x00, struct l2cache_addr_range)
138+#define OUTER_CACHE_CLEAN_RANGE _IOWR('S', 0x01, struct l2cache_addr_range)
139+#define OUTER_CACHE_FLUSH_RANGE _IOWR('S', 0x02, struct l2cache_addr_range)
140+#define L1_INV_I_CACHE _IOWR('S', 0x03, struct l2cache_addr_range)
141+#define D_TO_I_CACHE_FLUSH_RANGE _IOWR('S', 0x04, struct l2cache_addr_range)
142+
143+const unsigned char jmpCodeTemplate[] =
144+   { 0x57, 0x00, 0x00, 0x58, 0xe0, 0x02, 0x1f, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
145+
146+#define SET_SJMP_CODE(base, from, to) do { \
147+      using instruct_t = signed int; \
148+      instruct_t offset = (intptr_t)to - (intptr_t)from; \
149+      offset = ((offset >> 2) & 0x03FFFFFF) | 0x14000000; \
150+      *(instruct_t *)(base) = offset; \
151+   } while(0)
152+
153+#define SET_JMP_CODE(base, from, to) do { \
154+      *(void **)(base + 8) = (void *)to; \
155+   } while(0)
156+
157+#define FLUSH_CACHE(from, length) do { \
158+   struct l2cache_addr_range usr_data; \
159+   usr_data.start = ADDR_ALIGN_DOWN((unsigned long long)from); \
160+   usr_data.end = ADDR_ALIGN_UP((unsigned long long)from) + length; \
161+   __builtin___clear_cache((char *)usr_data.start, (char *)usr_data.end); \
162+} while (0)
163+
164+#endif
165diff --git a/src/JmpCodeARM32.h b/src/JmpCodeARM32.h
166new file mode 100644
167index 0000000..1eec42b
168--- /dev/null
169+++ b/src/JmpCodeARM32.h
170@@ -0,0 +1,36 @@
171+/***
172+   mockcpp is a C/C++ mock framework.
173+   Copyright [2008] [Darwin Yuan <darwin.yuan@gmail.com>]
174+                    [Chen Guodong <sinojelly@gmail.com>]
175+   Licensed under the Apache License, Version 2.0 (the "License");
176+   you may not use this file except in compliance with the License.
177+   You may obtain a copy of the License at
178+
179+      http://www.apache.org/licenses/LICENSE-2.0
180+
181+   Unless required by applicable law or agreed to in writing, software
182+   distributed under the License is distributed on an "AS IS" BASIS,
183+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
184+   See the License for the specific language governing permissions and
185+   limitations under the License.
186+***/
187+#ifndef __MOCKCPP_JMP_CODE_ARM32_H__
188+#define __MOCKCPP_JMP_CODE_ARM32_H__
189+
190+#include <stdlib.h>
191+
192+const unsigned char jmpCodeTemplate[] =
193+   { 0xEA, 0x00, 0x00, 0x00 };
194+
195+#define SET_JMP_CODE(base, from, to) do { \
196+       int offset = (int)to - (int)from - 8; \
197+       offset = (offset >> 2) & 0x00FFFFFF; \
198+       int code = *(int *)(base) | offset; \
199+       *(int *)(base) = changeByteOrder(code); \
200+   } while(0)
201+
202+#define FLUSH_CACHE(from, length) do { \
203+   ::system("echo 3 > /proc/sys/vm/drop_caches"); \
204+} while (0)
205+
206+#endif
207diff --git a/src/JmpCodeArch.h b/src/JmpCodeArch.h
208index 26abd73..53353eb 100644
209--- a/src/JmpCodeArch.h
210+++ b/src/JmpCodeArch.h
211@@ -19,11 +19,29 @@
212
213 #include <mockcpp/mockcpp.h>
214
215+template <typename T>
216+inline T changeByteOrder(const T v) {
217+   enum { S = sizeof(T) };
218+   T rst = v;
219+   char *p = (char *)&rst;
220+   char tmp = 0;
221+   for (unsigned int i = 0; i < S / 2; ++i) {
222+      tmp = p[i];
223+      p[i] = p[S - i - 1];
224+      p [S - i - 1] = tmp;
225+   }
226+
227+   return rst;
228+}
229+
230 #if BUILD_FOR_X64
231 # include "JmpCodeX64.h"
232 #elif BUILD_FOR_X86
233 # include "JmpCodeX86.h"
234+#elif defined(BUILD_FOR_ARM32)
235+# include "JmpCodeARM32.h"
236+#elif defined(BUILD_FOR_AARCH64)
237+# include "JmpCodeAARCH64.h"
238 #endif
239
240 #endif
241-
242diff --git a/src/JmpCodeX64.h b/src/JmpCodeX64.h
243index 198507a..e5b4f31 100644
244--- a/src/JmpCodeX64.h
245+++ b/src/JmpCodeX64.h
246@@ -27,5 +27,6 @@ const unsigned char jmpCodeTemplate[]  =
247        *(uintptr_t *)(base + 6) = (uintptr_t)to; \
248    } while(0)
249
250-#endif
251+#define FLUSH_CACHE(from, length) ((void)0)
252
253+#endif
254diff --git a/src/JmpCodeX86.h b/src/JmpCodeX86.h
255index ebdc526..a06a02e 100644
256--- a/src/JmpCodeX86.h
257+++ b/src/JmpCodeX86.h
258@@ -23,5 +23,6 @@ const unsigned char jmpCodeTemplate[]  = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
259             (unsigned long long)to - (unsigned long long)from - sizeof(jmpCodeTemplate); \
260    } while(0)
261
262-#endif
263+#define FLUSH_CACHE(from, length) ((void)0)
264
265+#endif
266diff --git a/src/JmpOnlyApiHook.cpp b/src/JmpOnlyApiHook.cpp
267index d4cfa68..964828f 100644
268--- a/src/JmpOnlyApiHook.cpp
269+++ b/src/JmpOnlyApiHook.cpp
270@@ -68,6 +68,7 @@ struct JmpOnlyApiHookImpl
271    void changeCode(const void* data)
272    {
273       CodeModifier::modify(const_cast<void*>(m_api), data, m_jmpCode.getCodeSize());
274+      m_jmpCode.flushCache();
275    }
276
277    /////////////////////////////////////////////////////
278diff --git a/src/UnixCodeModifier.cpp b/src/UnixCodeModifier.cpp
279index ab4014e..8e7dde9 100644
280--- a/src/UnixCodeModifier.cpp
281+++ b/src/UnixCodeModifier.cpp
282@@ -20,6 +20,7 @@
283 #include <sys/mman.h>
284
285 #include <mockcpp/CodeModifier.h>
286+#include "JmpCodeArch.h"
287
288 #define PAGE_ALIGN_BITS  12
289
290@@ -39,6 +40,7 @@ bool CodeModifier::modify(void *dest, const void *src, size_t size)
291
292     ::memcpy(dest, src, size);
293
294+    FLUSH_CACHE(dest, size);
295
296 #if 0
297 	#if BUILD_FOR_X86
298--
2992.34.1
300