Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
S
SandHook
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
SandHook
Commits
10c7897b
Commit
10c7897b
authored
Aug 21, 2019
by
swift_gan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
temp save
parent
74883690
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
14207 additions
and
17 deletions
+14207
-17
MyApp.java
app/src/main/java/com/swift/sandhook/MyApp.java
+20
-12
build.gradle
build.gradle
+1
-1
CMakeLists.txt
nativehook/CMakeLists.txt
+22
-4
hook_arm64.cpp
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
+5
-0
hook.h
nativehook/src/main/cpp/includes/hook.h
+1
-0
arguments.cpp
nativehook/src/main/cpp/javabridge/arguments.cpp
+5
-0
arguments.h
nativehook/src/main/cpp/javabridge/arguments.h
+5
-0
type_bridge.cpp
nativehook/src/main/cpp/javabridge/type_bridge.cpp
+46
-0
type_bridge.h
nativehook/src/main/cpp/javabridge/type_bridge.h
+135
-0
ffi_arm64.c
nativehook/src/main/cpp/libffi/aarch64/ffi_arm64.c
+946
-0
internal.h
nativehook/src/main/cpp/libffi/aarch64/internal.h
+72
-0
sysv_arm64.S
nativehook/src/main/cpp/libffi/aarch64/sysv_arm64.S
+441
-0
ffi_armv7.c
nativehook/src/main/cpp/libffi/arm/ffi_armv7.c
+824
-0
internal.h
nativehook/src/main/cpp/libffi/arm/internal.h
+12
-0
sysv_armv7.S
nativehook/src/main/cpp/libffi/arm/sysv_armv7.S
+388
-0
closures.c
nativehook/src/main/cpp/libffi/closures.c
+966
-0
debug.c
nativehook/src/main/cpp/libffi/debug.c
+64
-0
dlmalloc.c
nativehook/src/main/cpp/libffi/dlmalloc.c
+5169
-0
ffi.h
nativehook/src/main/cpp/libffi/ffi.h
+24
-0
ffi_cfi.h
nativehook/src/main/cpp/libffi/ffi_cfi.h
+55
-0
ffi_common.h
nativehook/src/main/cpp/libffi/ffi_common.h
+149
-0
ffi_cxx.cc
nativehook/src/main/cpp/libffi/ffi_cxx.cc
+68
-0
ffi_cxx.h
nativehook/src/main/cpp/libffi/ffi_cxx.h
+118
-0
fficonfig.h
nativehook/src/main/cpp/libffi/fficonfig.h
+21
-0
ffitarget.h
nativehook/src/main/cpp/libffi/ffitarget.h
+24
-0
java_raw_api.c
nativehook/src/main/cpp/libffi/java_raw_api.c
+374
-0
ffi_arm64.h
nativehook/src/main/cpp/libffi/platform_include/ffi_arm64.h
+516
-0
ffi_armv7.h
nativehook/src/main/cpp/libffi/platform_include/ffi_armv7.h
+516
-0
ffi_i386.h
nativehook/src/main/cpp/libffi/platform_include/ffi_i386.h
+516
-0
ffi_x86_64.h
nativehook/src/main/cpp/libffi/platform_include/ffi_x86_64.h
+516
-0
fficonfig_arm64.h
...ok/src/main/cpp/libffi/platform_include/fficonfig_arm64.h
+224
-0
fficonfig_armv7.h
...ok/src/main/cpp/libffi/platform_include/fficonfig_armv7.h
+224
-0
fficonfig_i386.h
...ook/src/main/cpp/libffi/platform_include/fficonfig_i386.h
+220
-0
fficonfig_x86_64.h
...k/src/main/cpp/libffi/platform_include/fficonfig_x86_64.h
+220
-0
ffitarget_arm64.h
...ok/src/main/cpp/libffi/platform_include/ffitarget_arm64.h
+86
-0
ffitarget_armv7.h
...ok/src/main/cpp/libffi/platform_include/ffitarget_armv7.h
+87
-0
ffitarget_i386.h
...ook/src/main/cpp/libffi/platform_include/ffitarget_i386.h
+152
-0
ffitarget_x86_64.h
...k/src/main/cpp/libffi/platform_include/ffitarget_x86_64.h
+152
-0
prep_cif.c
nativehook/src/main/cpp/libffi/prep_cif.c
+261
-0
raw_api.c
nativehook/src/main/cpp/libffi/raw_api.c
+267
-0
types.c
nativehook/src/main/cpp/libffi/types.c
+108
-0
sandhook_native.cpp
nativehook/src/main/cpp/sandhook_native.cpp
+187
-0
No files found.
app/src/main/java/com/swift/sandhook/MyApp.java
View file @
10c7897b
...
@@ -5,6 +5,7 @@ import android.app.Application;
...
@@ -5,6 +5,7 @@ import android.app.Application;
import
android.os.Build
;
import
android.os.Build
;
import
android.util.Log
;
import
android.util.Log
;
import
com.swift.sandhook.nativehook.NativeHook
;
import
com.swift.sandhook.test.TestClass
;
import
com.swift.sandhook.test.TestClass
;
import
com.swift.sandhook.testHookers.ActivityHooker
;
import
com.swift.sandhook.testHookers.ActivityHooker
;
import
com.swift.sandhook.testHookers.CtrHook
;
import
com.swift.sandhook.testHookers.CtrHook
;
...
@@ -36,6 +37,8 @@ public class MyApp extends Application {
...
@@ -36,6 +37,8 @@ public class MyApp extends Application {
SandHookConfig
.
SDK_INT
=
29
;
SandHookConfig
.
SDK_INT
=
29
;
}
}
NativeHook
.
test
();
SandHook
.
disableVMInline
();
SandHook
.
disableVMInline
();
SandHook
.
tryDisableProfile
(
getPackageName
());
SandHook
.
tryDisableProfile
(
getPackageName
());
SandHook
.
disableDex2oatInline
(
false
);
SandHook
.
disableDex2oatInline
(
false
);
...
@@ -80,20 +83,25 @@ public class MyApp extends Application {
...
@@ -80,20 +83,25 @@ public class MyApp extends Application {
});
});
XposedHelpers
.
findAndHookMethod
(
MainActivity
.
class
,
"testStub"
,
TestClass
.
class
,
int
.
class
,
String
.
class
,
boolean
.
class
,
char
.
class
,
String
.
class
,
new
XC_MethodHook
()
{
new
Thread
(
new
Runnable
()
{
@Override
@Override
protected
void
beforeHookedMethod
(
MethodHookParam
param
)
throws
Throwable
{
public
void
run
()
{
super
.
beforeHookedMethod
(
param
);
XposedHelpers
.
findAndHookMethod
(
MainActivity
.
class
,
"testStub"
,
TestClass
.
class
,
int
.
class
,
String
.
class
,
boolean
.
class
,
char
.
class
,
String
.
class
,
new
XC_MethodHook
()
{
param
.
args
[
1
]
=
2
;
@Override
Log
.
e
(
"XposedCompat"
,
"beforeHookedMethod: "
+
param
.
method
.
getName
());
protected
void
beforeHookedMethod
(
MethodHookParam
param
)
throws
Throwable
{
super
.
beforeHookedMethod
(
param
);
param
.
args
[
1
]
=
2
;
Log
.
e
(
"XposedCompat"
,
"beforeHookedMethod: "
+
param
.
method
.
getName
());
}
@Override
protected
void
afterHookedMethod
(
MethodHookParam
param
)
throws
Throwable
{
super
.
afterHookedMethod
(
param
);
Log
.
e
(
"XposedCompat"
,
"afterHookedMethod: "
+
param
.
method
.
getName
());
}
});
}
}
}).
start
();
@Override
protected
void
afterHookedMethod
(
MethodHookParam
param
)
throws
Throwable
{
super
.
afterHookedMethod
(
param
);
Log
.
e
(
"XposedCompat"
,
"afterHookedMethod: "
+
param
.
method
.
getName
());
}
});
try
{
try
{
ClassLoader
classLoader
=
getClassLoader
();
ClassLoader
classLoader
=
getClassLoader
();
...
...
build.gradle
View file @
10c7897b
...
@@ -7,7 +7,7 @@ buildscript {
...
@@ -7,7 +7,7 @@ buildscript {
jcenter
()
jcenter
()
}
}
dependencies
{
dependencies
{
classpath
'com.android.tools.build:gradle:3.
1.3
'
classpath
'com.android.tools.build:gradle:3.
3.1
'
classpath
'com.novoda:bintray-release:0.8.1'
classpath
'com.novoda:bintray-release:0.8.1'
// NOTE: Do not place your application dependencies here; they belong
// NOTE: Do not place your application dependencies here; they belong
...
...
nativehook/CMakeLists.txt
View file @
10c7897b
...
@@ -17,7 +17,9 @@ if(${CMAKE_ANDROID_ARCH_ABI} STREQUAL "arm64-v8a")
...
@@ -17,7 +17,9 @@ if(${CMAKE_ANDROID_ARCH_ABI} STREQUAL "arm64-v8a")
src/main/cpp/archs/arm/arm64/register/register_list_arm64.cpp
src/main/cpp/archs/arm/arm64/register/register_list_arm64.cpp
src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm/arm64/decoder/decoder_arm64.cpp
src/main/cpp/archs/arm/arm64/relocate/code_relocate_arm64.cpp
src/main/cpp/archs/arm/arm64/relocate/code_relocate_arm64.cpp
src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
)
src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
src/main/cpp/libffi/aarch64/ffi_arm64.c
src/main/cpp/libffi/aarch64/sysv_arm64.S
)
elseif
(
${
CMAKE_ANDROID_ARCH_ABI
}
STREQUAL
"armeabi-v7a"
)
elseif
(
${
CMAKE_ANDROID_ARCH_ABI
}
STREQUAL
"armeabi-v7a"
)
set
(
OS_DEPENDENDED_SRC
set
(
OS_DEPENDENDED_SRC
...
@@ -30,7 +32,9 @@ elseif (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi-v7a")
...
@@ -30,7 +32,9 @@ elseif (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi-v7a")
src/main/cpp/archs/arm/arm32/decoder/decoder_arm32.cpp
src/main/cpp/archs/arm/arm32/decoder/decoder_arm32.cpp
src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
src/main/cpp/archs/arm/arm32/hook/hook_arm32.cpp
src/main/cpp/archs/arm/arm32/hook/breakpoint_shellcode.S
src/main/cpp/archs/arm/arm32/hook/breakpoint_shellcode.S
src/main/cpp/archs/arm/arm32/relocate/code_relocate_arm32.cpp
)
src/main/cpp/archs/arm/arm32/relocate/code_relocate_arm32.cpp
src/main/cpp/libffi/arm/ffi_armv7.c
src/main/cpp/libffi/arm/sysv_armv7.S
)
endif
()
endif
()
add_library
(
# Sets the name of the library.
add_library
(
# Sets the name of the library.
...
@@ -48,6 +52,17 @@ add_library( # Sets the name of the library.
...
@@ -48,6 +52,17 @@ add_library( # Sets the name of the library.
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/buffer/code_buffer.cpp
src/main/cpp/utils/platform.cpp
src/main/cpp/utils/platform.cpp
src/main/cpp/hook/hook.cpp
src/main/cpp/hook/hook.cpp
src/main/cpp/javabridge/type_bridge.cpp
src/main/cpp/javabridge/arguments.cpp
src/main/cpp/libffi/closures.c
src/main/cpp/libffi/debug.c
src/main/cpp/libffi/dlmalloc.c
src/main/cpp/libffi/java_raw_api.c
src/main/cpp/libffi/prep_cif.c
src/main/cpp/libffi/raw_api.c
src/main/cpp/libffi/types.c
src/main/cpp/libffi/ffi_cxx.cc
${
OS_DEPENDENDED_SRC
}
)
${
OS_DEPENDENDED_SRC
}
)
...
@@ -71,7 +86,10 @@ include_directories(
...
@@ -71,7 +86,10 @@ include_directories(
src/main/cpp/archs/arm/arm32/decoder
src/main/cpp/archs/arm/arm32/decoder
src/main/cpp/archs/arm/arm32/hook
src/main/cpp/archs/arm/arm32/hook
src/main/cpp/archs/arm/arm32/relocate
src/main/cpp/archs/arm/arm32/relocate
src/main/cpp/antihook
src/main/cpp
src/main/javabridge
src/main/cpp/libffi
src/main/cpp/libffi/platform_include
)
)
# Searches for a specified prebuilt library and stores the path as a
# Searches for a specified prebuilt library and stores the path as a
...
@@ -99,6 +117,6 @@ target_link_libraries( # Specifies the target library.
...
@@ -99,6 +117,6 @@ target_link_libraries( # Specifies the target library.
${
log-lib
}
)
${
log-lib
}
)
add_definitions
(
-std=c++11
)
set
(
CMAKE_CXX_STANDARD 14
)
ENABLE_LANGUAGE
(
ASM
)
ENABLE_LANGUAGE
(
ASM
)
\ No newline at end of file
nativehook/src/main/cpp/archs/arm/arm64/hook/hook_arm64.cpp
View file @
10c7897b
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
//
//
#include <cstdlib>
#include <cstdlib>
#include <unistd.h>
#include "hook_arm64.h"
#include "hook_arm64.h"
#include "code_buffer.h"
#include "code_buffer.h"
#include "lock.h"
#include "lock.h"
...
@@ -181,4 +182,8 @@ void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) {
...
@@ -181,4 +182,8 @@ void InlineHookArm64Android::ExceptionHandler(int num, sigcontext *context) {
return
;
return
;
HookInfo
&
hook_info
=
hook_infos
[
hvc
.
imme
];
HookInfo
&
hook_info
=
hook_infos
[
hvc
.
imme
];
context
->
pc
=
reinterpret_cast
<
U64
>
(
hook_info
.
replace
);
context
->
pc
=
reinterpret_cast
<
U64
>
(
hook_info
.
replace
);
if
(
callback
!=
nullptr
)
{
callback
();
callback
=
nullptr
;
}
}
}
nativehook/src/main/cpp/includes/hook.h
View file @
10c7897b
...
@@ -43,6 +43,7 @@ namespace SandHook {
...
@@ -43,6 +43,7 @@ namespace SandHook {
std
::
mutex
hook_lock
;
std
::
mutex
hook_lock
;
public
:
public
:
static
InlineHook
*
instance
;
static
InlineHook
*
instance
;
void
(
*
callback
)(
void
)
=
nullptr
;
};
};
}
}
...
...
nativehook/src/main/cpp/javabridge/arguments.cpp
0 → 100644
View file @
10c7897b
//
// Created by 甘尧 on 2019-07-22.
//
#include "arguments.h"
nativehook/src/main/cpp/javabridge/arguments.h
0 → 100644
View file @
10c7897b
//
// Created by 甘尧 on 2019-07-22.
//
#pragma once
nativehook/src/main/cpp/javabridge/type_bridge.cpp
0 → 100644
View file @
10c7897b
//
// Created by 甘尧 on 2019-07-22.
//
#include "type_bridge.h"
using
namespace
SandHook
::
JavaBridge
;
void
Types
::
Load
(
JNIEnv
*
env
)
{
jclass
clazz
;
env
->
PushLocalFrame
(
16
);
#define LOAD_CLASS(c, s) clazz = env->FindClass(s); (c) = reinterpret_cast<jclass>(env->NewWeakGlobalRef(clazz))
#define LOAD_LANG_CLASS(c, s) LOAD_CLASS(java_lang_##c, "java/lang/" #c); java_lang_##c##_init = env->GetMethodID(java_lang_##c, "<init>", s)
LOAD_LANG_CLASS
(
Integer
,
"(I)V"
);
LOAD_LANG_CLASS
(
Long
,
"(J)V"
);
LOAD_LANG_CLASS
(
Float
,
"(F)V"
);
LOAD_LANG_CLASS
(
Double
,
"(D)V"
);
LOAD_LANG_CLASS
(
Byte
,
"(B)V"
);
LOAD_LANG_CLASS
(
Short
,
"(S)V"
);
LOAD_LANG_CLASS
(
Boolean
,
"(Z)V"
);
LOAD_LANG_CLASS
(
Character
,
"(C)V"
);
#undef LOAD_CLASS
#undef LOAD_LANG_CLASS
#define LOAD_METHOD(k, c, r, s) java_value_##c = env->GetMethodID(k, r "Value", s)
#define LOAD_NUMBER(c, r, s) LOAD_METHOD(java_lang_Number, c, r, s)
jclass
java_lang_Number
=
env
->
FindClass
(
"java/lang/Number"
);
LOAD_NUMBER
(
Integer
,
"int"
,
"()I"
);
LOAD_NUMBER
(
Long
,
"long"
,
"()J"
);
LOAD_NUMBER
(
Float
,
"float"
,
"()F"
);
LOAD_NUMBER
(
Double
,
"double"
,
"()D"
);
LOAD_NUMBER
(
Byte
,
"byte"
,
"()B"
);
LOAD_NUMBER
(
Short
,
"short"
,
"()S"
);
LOAD_METHOD
(
java_lang_Boolean
,
Boolean
,
"boolean"
,
"()Z"
);
LOAD_METHOD
(
java_lang_Character
,
Character
,
"char"
,
"()C"
);
env
->
PopLocalFrame
(
nullptr
);
#undef LOAD_METHOD
#undef LOAD_NUMBER
}
nativehook/src/main/cpp/javabridge/type_bridge.h
0 → 100644
View file @
10c7897b
//
// Created by 甘尧 on 2019-07-22.
//
#pragma once
#include "jni.h"
namespace
SandHook
{
namespace
JavaBridge
{
struct
Types
{
#define LANG_ClASS(c) static jclass java_lang_##c; static jmethodID java_lang_##c##_init; static jmethodID java_value_##c;
LANG_ClASS
(
Integer
);
LANG_ClASS
(
Long
);
LANG_ClASS
(
Float
);
LANG_ClASS
(
Double
);
LANG_ClASS
(
Byte
);
LANG_ClASS
(
Short
);
LANG_ClASS
(
Boolean
);
LANG_ClASS
(
Character
);
#undef LANG_ClASS
static
void
Load
(
JNIEnv
*
env
);
#define LANG_BOX_DEF(c, t) static jobject To##c(JNIEnv *env, t v);
#define LANG_UNBOX_V_DEF(k, c, t) static t From##c(JNIEnv *env, jobject j);
#define LANG_UNBOX_DEF(c, t) LANG_UNBOX_V_DEF(c, c, t)
LANG_BOX_DEF
(
Object
,
jobject
);
LANG_BOX_DEF
(
Integer
,
jint
);
LANG_BOX_DEF
(
Long
,
jlong
);
LANG_BOX_DEF
(
Float
,
jfloat
);
LANG_BOX_DEF
(
Double
,
jdouble
);
LANG_BOX_DEF
(
Byte
,
jbyte
);
LANG_BOX_DEF
(
Short
,
jshort
);
LANG_BOX_DEF
(
Boolean
,
jboolean
);
LANG_BOX_DEF
(
Character
,
jchar
);
LANG_UNBOX_V_DEF
(
Int
,
Integer
,
jint
);
LANG_UNBOX_DEF
(
Object
,
jobject
);
LANG_UNBOX_DEF
(
Long
,
jlong
);
LANG_UNBOX_DEF
(
Float
,
jfloat
);
LANG_UNBOX_DEF
(
Double
,
jdouble
);
LANG_UNBOX_DEF
(
Byte
,
jbyte
);
LANG_UNBOX_DEF
(
Short
,
jshort
);
LANG_UNBOX_DEF
(
Boolean
,
jboolean
);
LANG_UNBOX_V_DEF
(
Char
,
Character
,
jchar
);
#undef LANG_BOX_DEF
#undef LANG_UNBOX_V_DEF
#undef LANG_UNBOX_DEF
};
#define EXPORT_LANG_ClASS(c) jclass Types::java_lang_##c; jmethodID Types::java_lang_##c##_init; jmethodID Types::java_value_##c;
EXPORT_LANG_ClASS
(
Integer
);
EXPORT_LANG_ClASS
(
Long
);
EXPORT_LANG_ClASS
(
Float
);
EXPORT_LANG_ClASS
(
Double
);
EXPORT_LANG_ClASS
(
Byte
);
EXPORT_LANG_ClASS
(
Short
);
EXPORT_LANG_ClASS
(
Boolean
);
EXPORT_LANG_ClASS
(
Character
);
#undef EXPORT_LANG_ClASS
#define LANG_BOX(c, t) jobject Types::To##c(JNIEnv *env, t v) { \
return env->NewObject(Types::java_lang_##c, Types::java_lang_##c##_init, v); \
}
#define LANG_UNBOX_V(k, c, t) t Types::From##c(JNIEnv *env, jobject j) { \
return env->Call##k##Method(j, Types::java_value_##c); \
}
#define LANG_UNBOX(c, t) LANG_UNBOX_V(c, c, t)
LANG_BOX
(
Integer
,
jint
);
LANG_BOX
(
Long
,
jlong
);
LANG_BOX
(
Float
,
jfloat
);
LANG_BOX
(
Double
,
jdouble
);
LANG_BOX
(
Byte
,
jbyte
);
LANG_BOX
(
Short
,
jshort
);
LANG_BOX
(
Boolean
,
jboolean
);
LANG_BOX
(
Character
,
jchar
);
jobject
Types
::
ToObject
(
JNIEnv
*
env
,
jobject
obj
)
{
return
obj
;
}
LANG_UNBOX_V
(
Int
,
Integer
,
jint
);
LANG_UNBOX
(
Long
,
jlong
);
LANG_UNBOX
(
Float
,
jfloat
);
LANG_UNBOX
(
Double
,
jdouble
);
LANG_UNBOX
(
Byte
,
jbyte
);
LANG_UNBOX
(
Short
,
jshort
);
LANG_UNBOX
(
Boolean
,
jboolean
);
LANG_UNBOX_V
(
Char
,
Character
,
jchar
);
jobject
Types
::
FromObject
(
JNIEnv
*
env
,
jobject
obj
)
{
return
obj
;
}
#undef LANG_BOX
#undef LANG_UNBOX_V
#undef LANG_UNBOX
}
}
nativehook/src/main/cpp/libffi/aarch64/ffi_arm64.c
0 → 100755
View file @
10c7897b
#if defined(__aarch64__) || defined(__arm64__)
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_common.h>
#include "internal.h"
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
all further uses in this file will refer to the 128-bit type. */
#if FFI_TYPE_DOUBLE != FFI_TYPE_LONGDOUBLE
# if FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
#else
# undef FFI_TYPE_LONGDOUBLE
# define FFI_TYPE_LONGDOUBLE 4
#endif
union
_d
{
UINT64
d
;
UINT32
s
[
2
];
};
struct
_v
{
union
_d
d
[
2
]
__attribute__
((
aligned
(
16
)));
};
struct
call_context
{
struct
_v
v
[
N_V_ARG_REG
];
UINT64
x
[
N_X_ARG_REG
];
};
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#include <mach/vm_param.h>
#endif
#else
#if defined (__clang__) && defined (__APPLE__)
extern
void
sys_icache_invalidate
(
void
*
start
,
size_t
len
);
#endif
static
inline
void
ffi_clear_cache
(
void
*
start
,
void
*
end
)
{
#if defined (__clang__) && defined (__APPLE__)
sys_icache_invalidate
(
start
,
(
char
*
)
end
-
(
char
*
)
start
);
#elif defined (__GNUC__)
__builtin___clear_cache
(
start
,
end
);
#else
#error "Missing builtin to flush instruction cache"
#endif
}
#endif
/* A subroutine of is_vfp_type. Given a structure type, return the type code
of the first non-structure element. Recurse for structure elements.
Return -1 if the structure is in fact empty, i.e. no nested elements. */
static
int
is_hfa0
(
const
ffi_type
*
ty
)
{
ffi_type
**
elements
=
ty
->
elements
;
int
i
,
ret
=
-
1
;
if
(
elements
!=
NULL
)
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
ret
=
elements
[
i
]
->
type
;
if
(
ret
==
FFI_TYPE_STRUCT
||
ret
==
FFI_TYPE_COMPLEX
)
{
ret
=
is_hfa0
(
elements
[
i
]);
if
(
ret
<
0
)
continue
;
}
break
;
}
return
ret
;
}
/* A subroutine of is_vfp_type. Given a structure type, return true if all
of the non-structure elements are the same as CANDIDATE. */
static
int
is_hfa1
(
const
ffi_type
*
ty
,
int
candidate
)
{
ffi_type
**
elements
=
ty
->
elements
;
int
i
;
if
(
elements
!=
NULL
)
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
int
t
=
elements
[
i
]
->
type
;
if
(
t
==
FFI_TYPE_STRUCT
||
t
==
FFI_TYPE_COMPLEX
)
{
if
(
!
is_hfa1
(
elements
[
i
],
candidate
))
return
0
;
}
else
if
(
t
!=
candidate
)
return
0
;
}
return
1
;
}
/* Determine if TY may be allocated to the FP registers. This is both an
fp scalar type as well as an homogenous floating point aggregate (HFA).
That is, a structure consisting of 1 to 4 members of all the same type,
where that type is an fp scalar.
Returns non-zero iff TY is an HFA. The result is the AARCH64_RET_*
constant for the type. */
static
int
is_vfp_type
(
const
ffi_type
*
ty
)
{
ffi_type
**
elements
;
int
candidate
,
i
;
size_t
size
,
ele_count
;
/* Quickest tests first. */
candidate
=
ty
->
type
;
switch
(
candidate
)
{
default:
return
0
;
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
case
FFI_TYPE_LONGDOUBLE
:
ele_count
=
1
;
goto
done
;
case
FFI_TYPE_COMPLEX
:
candidate
=
ty
->
elements
[
0
]
->
type
;
switch
(
candidate
)
{
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
case
FFI_TYPE_LONGDOUBLE
:
ele_count
=
2
;
goto
done
;
}
return
0
;
case
FFI_TYPE_STRUCT
:
break
;
}
/* No HFA types are smaller than 4 bytes, or larger than 64 bytes. */
size
=
ty
->
size
;
if
(
size
<
4
||
size
>
64
)
return
0
;
/* Find the type of the first non-structure member. */
elements
=
ty
->
elements
;
candidate
=
elements
[
0
]
->
type
;
if
(
candidate
==
FFI_TYPE_STRUCT
||
candidate
==
FFI_TYPE_COMPLEX
)
{
for
(
i
=
0
;
;
++
i
)
{
candidate
=
is_hfa0
(
elements
[
i
]);
if
(
candidate
>=
0
)
break
;
}
}
/* If the first member is not a floating point type, it's not an HFA.
Also quickly re-check the size of the structure. */
switch
(
candidate
)
{
case
FFI_TYPE_FLOAT
:
ele_count
=
size
/
sizeof
(
float
);
if
(
size
!=
ele_count
*
sizeof
(
float
))
return
0
;
break
;
case
FFI_TYPE_DOUBLE
:
ele_count
=
size
/
sizeof
(
double
);
if
(
size
!=
ele_count
*
sizeof
(
double
))
return
0
;
break
;
case
FFI_TYPE_LONGDOUBLE
:
ele_count
=
size
/
sizeof
(
long
double
);
if
(
size
!=
ele_count
*
sizeof
(
long
double
))
return
0
;
break
;
default:
return
0
;
}
if
(
ele_count
>
4
)
return
0
;
/* Finally, make sure that all scalar elements are the same type. */
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
int
t
=
elements
[
i
]
->
type
;
if
(
t
==
FFI_TYPE_STRUCT
||
t
==
FFI_TYPE_COMPLEX
)
{
if
(
!
is_hfa1
(
elements
[
i
],
candidate
))
return
0
;
}
else
if
(
t
!=
candidate
)
return
0
;
}
/* All tests succeeded. Encode the result. */
done:
return
candidate
*
4
+
(
4
-
(
int
)
ele_count
);
}
/* Representation of the procedure call argument marshalling
state.
The terse state variable names match the names used in the AARCH64
PCS. */
struct
arg_state
{
unsigned
ngrn
;
/* Next general-purpose register number. */
unsigned
nsrn
;
/* Next vector register number. */
size_t
nsaa
;
/* Next stack offset. */
#if defined (__APPLE__)
unsigned
allocating_variadic
;
#endif
};
/* Initialize a procedure call argument marshalling state. */
static
void
arg_init
(
struct
arg_state
*
state
)
{
state
->
ngrn
=
0
;
state
->
nsrn
=
0
;
state
->
nsaa
=
0
;
#if defined (__APPLE__)
state
->
allocating_variadic
=
0
;
#endif
}
/* Allocate an aligned slot on the stack and return a pointer to it. */
static
void
*
allocate_to_stack
(
struct
arg_state
*
state
,
void
*
stack
,
size_t
alignment
,
size_t
size
)
{
size_t
nsaa
=
state
->
nsaa
;
/* Round up the NSAA to the larger of 8 or the natural
alignment of the argument's type. */
#if defined (__APPLE__)
if
(
state
->
allocating_variadic
&&
alignment
<
8
)
alignment
=
8
;
#else
if
(
alignment
<
8
)
alignment
=
8
;
#endif
nsaa
=
FFI_ALIGN
(
nsaa
,
alignment
);
state
->
nsaa
=
nsaa
+
size
;
return
(
char
*
)
stack
+
nsaa
;
}
static
ffi_arg
extend_integer_type
(
void
*
source
,
int
type
)
{
switch
(
type
)
{
case
FFI_TYPE_UINT8
:
return
*
(
UINT8
*
)
source
;
case
FFI_TYPE_SINT8
:
return
*
(
SINT8
*
)
source
;
case
FFI_TYPE_UINT16
:
return
*
(
UINT16
*
)
source
;
case
FFI_TYPE_SINT16
:
return
*
(
SINT16
*
)
source
;
case
FFI_TYPE_UINT32
:
return
*
(
UINT32
*
)
source
;
case
FFI_TYPE_INT
:
case
FFI_TYPE_SINT32
:
return
*
(
SINT32
*
)
source
;
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
return
*
(
UINT64
*
)
source
;
break
;
case
FFI_TYPE_POINTER
:
return
*
(
uintptr_t
*
)
source
;
default:
abort
();
}
}
static
void
extend_hfa_type
(
void
*
dest
,
void
*
src
,
int
h
)
{
ssize_t
f
=
h
-
AARCH64_RET_S4
;
void
*
x0
;
asm
volatile
(
"adr %0, 0f
\n
"
" add %0, %0, %1
\n
"
" br %0
\n
"
"0: ldp s16, s17, [%3]
\n
"
/* S4 */
" ldp s18, s19, [%3, #8]
\n
"
" b 4f
\n
"
" ldp s16, s17, [%3]
\n
"
/* S3 */
" ldr s18, [%3, #8]
\n
"
" b 3f
\n
"
" ldp s16, s17, [%3]
\n
"
/* S2 */
" b 2f
\n
"
" nop
\n
"
" ldr s16, [%3]
\n
"
/* S1 */
" b 1f
\n
"
" nop
\n
"
" ldp d16, d17, [%3]
\n
"
/* D4 */
" ldp d18, d19, [%3, #16]
\n
"
" b 4f
\n
"
" ldp d16, d17, [%3]
\n
"
/* D3 */
" ldr d18, [%3, #16]
\n
"
" b 3f
\n
"
" ldp d16, d17, [%3]
\n
"
/* D2 */
" b 2f
\n
"
" nop
\n
"
" ldr d16, [%3]
\n
"
/* D1 */
" b 1f
\n
"
" nop
\n
"
" ldp q16, q17, [%3]
\n
"
/* Q4 */
" ldp q18, q19, [%3, #32]
\n
"
" b 4f
\n
"
" ldp q16, q17, [%3]
\n
"
/* Q3 */
" ldr q18, [%3, #32]
\n
"
" b 3f
\n
"
" ldp q16, q17, [%3]
\n
"
/* Q2 */
" b 2f
\n
"
" nop
\n
"
" ldr q16, [%3]
\n
"
/* Q1 */
" b 1f
\n
"
"4: str q19, [%2, #48]
\n
"
"3: str q18, [%2, #32]
\n
"
"2: str q17, [%2, #16]
\n
"
"1: str q16, [%2]"
:
"=&r"
(
x0
)
:
"r"
(
f
*
12
),
"r"
(
dest
),
"r"
(
src
)
:
"memory"
,
"v16"
,
"v17"
,
"v18"
,
"v19"
);
}
static
void
*
compress_hfa_type
(
void
*
dest
,
void
*
reg
,
int
h
)
{
switch
(
h
)
{
case
AARCH64_RET_S1
:
if
(
dest
==
reg
)
{
#ifdef __AARCH64EB__
dest
+=
12
;
#endif
}
else
*
(
float
*
)
dest
=
*
(
float
*
)
reg
;
break
;
case
AARCH64_RET_S2
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"st2 { v16.s, v17.s }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
);
break
;
case
AARCH64_RET_S3
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"ldr q18, [%1, #32]
\n\t
"
"st3 { v16.s, v17.s, v18.s }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
,
"v18"
);
break
;
case
AARCH64_RET_S4
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"ldp q18, q19, [%1, #32]
\n\t
"
"st4 { v16.s, v17.s, v18.s, v19.s }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
,
"v18"
,
"v19"
);
break
;
case
AARCH64_RET_D1
:
if
(
dest
==
reg
)
{
#ifdef __AARCH64EB__
dest
+=
8
;
#endif
}
else
*
(
double
*
)
dest
=
*
(
double
*
)
reg
;
break
;
case
AARCH64_RET_D2
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"st2 { v16.d, v17.d }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
);
break
;
case
AARCH64_RET_D3
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"ldr q18, [%1, #32]
\n\t
"
"st3 { v16.d, v17.d, v18.d }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
,
"v18"
);
break
;
case
AARCH64_RET_D4
:
asm
(
"ldp q16, q17, [%1]
\n\t
"
"ldp q18, q19, [%1, #32]
\n\t
"
"st4 { v16.d, v17.d, v18.d, v19.d }[0], [%0]"
:
:
"r"
(
dest
),
"r"
(
reg
)
:
"memory"
,
"v16"
,
"v17"
,
"v18"
,
"v19"
);
break
;
default:
if
(
dest
!=
reg
)
return
memcpy
(
dest
,
reg
,
16
*
(
4
-
(
h
&
3
)));
break
;
}
return
dest
;
}
/* Either allocate an appropriate register for the argument type, or if
none are available, allocate a stack slot and return a pointer
to the allocated space. */
static
void
*
allocate_int_to_reg_or_stack
(
struct
call_context
*
context
,
struct
arg_state
*
state
,
void
*
stack
,
size_t
size
)
{
if
(
state
->
ngrn
<
N_X_ARG_REG
)
return
&
context
->
x
[
state
->
ngrn
++
];
state
->
ngrn
=
N_X_ARG_REG
;
return
allocate_to_stack
(
state
,
stack
,
size
,
size
);
}
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
)
{
ffi_type
*
rtype
=
cif
->
rtype
;
size_t
bytes
=
cif
->
bytes
;
int
flags
,
i
,
n
;
switch
(
rtype
->
type
)
{
case
FFI_TYPE_VOID
:
flags
=
AARCH64_RET_VOID
;
break
;
case
FFI_TYPE_UINT8
:
flags
=
AARCH64_RET_UINT8
;
break
;
case
FFI_TYPE_UINT16
:
flags
=
AARCH64_RET_UINT16
;
break
;
case
FFI_TYPE_UINT32
:
flags
=
AARCH64_RET_UINT32
;
break
;
case
FFI_TYPE_SINT8
:
flags
=
AARCH64_RET_SINT8
;
break
;
case
FFI_TYPE_SINT16
:
flags
=
AARCH64_RET_SINT16
;
break
;
case
FFI_TYPE_INT
:
case
FFI_TYPE_SINT32
:
flags
=
AARCH64_RET_SINT32
;
break
;
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_UINT64
:
flags
=
AARCH64_RET_INT64
;
break
;
case
FFI_TYPE_POINTER
:
flags
=
(
sizeof
(
void
*
)
==
4
?
AARCH64_RET_UINT32
:
AARCH64_RET_INT64
);
break
;
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
case
FFI_TYPE_LONGDOUBLE
:
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_COMPLEX
:
flags
=
is_vfp_type
(
rtype
);
if
(
flags
==
0
)
{
size_t
s
=
rtype
->
size
;
if
(
s
>
16
)
{
flags
=
AARCH64_RET_VOID
|
AARCH64_RET_IN_MEM
;
bytes
+=
8
;
}
else
if
(
s
==
16
)
flags
=
AARCH64_RET_INT128
;
else
if
(
s
==
8
)
flags
=
AARCH64_RET_INT64
;
else
flags
=
AARCH64_RET_INT128
|
AARCH64_RET_NEED_COPY
;
}
break
;
default:
abort
();
}
for
(
i
=
0
,
n
=
cif
->
nargs
;
i
<
n
;
i
++
)
if
(
is_vfp_type
(
cif
->
arg_types
[
i
]))
{
flags
|=
AARCH64_FLAG_ARG_V
;
break
;
}
/* Round the stack up to a multiple of the stack alignment requirement. */
cif
->
bytes
=
(
unsigned
)
FFI_ALIGN
(
bytes
,
16
);
cif
->
flags
=
flags
;
#if defined (__APPLE__)
cif
->
aarch64_nfixedargs
=
0
;
#endif
return
FFI_OK
;
}
#if defined (__APPLE__)
/* Perform Apple-specific cif processing for variadic calls */
ffi_status
ffi_prep_cif_machdep_var
(
ffi_cif
*
cif
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
)
{
ffi_status
status
=
ffi_prep_cif_machdep
(
cif
);
cif
->
aarch64_nfixedargs
=
nfixedargs
;
return
status
;
}
#endif
/* __APPLE__ */
extern
void
ffi_call_SYSV
(
struct
call_context
*
context
,
void
*
frame
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
int
flags
,
void
*
closure
)
FFI_HIDDEN
;
/* Call a function with the provided arguments and capture the return
value. */
static
void
ffi_call_int
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
orig_rvalue
,
void
**
avalue
,
void
*
closure
)
{
struct
call_context
*
context
;
void
*
stack
,
*
frame
,
*
rvalue
;
struct
arg_state
state
;
size_t
stack_bytes
,
rtype_size
,
rsize
;
int
i
,
nargs
,
flags
;
ffi_type
*
rtype
;
flags
=
cif
->
flags
;
rtype
=
cif
->
rtype
;
rtype_size
=
rtype
->
size
;
stack_bytes
=
cif
->
bytes
;
/* If the target function returns a structure via hidden pointer,
then we cannot allow a null rvalue. Otherwise, mash a null
rvalue to void return type. */
rsize
=
0
;
if
(
flags
&
AARCH64_RET_IN_MEM
)
{
if
(
orig_rvalue
==
NULL
)
rsize
=
rtype_size
;
}
else
if
(
orig_rvalue
==
NULL
)
flags
&=
AARCH64_FLAG_ARG_V
;
else
if
(
flags
&
AARCH64_RET_NEED_COPY
)
rsize
=
16
;
/* Allocate consectutive stack for everything we'll need. */
context
=
alloca
(
sizeof
(
struct
call_context
)
+
stack_bytes
+
32
+
rsize
);
stack
=
context
+
1
;
frame
=
stack
+
stack_bytes
;
rvalue
=
(
rsize
?
frame
+
32
:
orig_rvalue
);
arg_init
(
&
state
);
for
(
i
=
0
,
nargs
=
cif
->
nargs
;
i
<
nargs
;
i
++
)
{
ffi_type
*
ty
=
cif
->
arg_types
[
i
];
size_t
s
=
ty
->
size
;
void
*
a
=
avalue
[
i
];
int
h
,
t
;
t
=
ty
->
type
;
switch
(
t
)
{
case
FFI_TYPE_VOID
:
FFI_ASSERT
(
0
);
break
;
/* If the argument is a basic type the argument is allocated to an
appropriate register, or if none are available, to the stack. */
case
FFI_TYPE_INT
:
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_POINTER
:
do_pointer:
{
ffi_arg
ext
=
extend_integer_type
(
a
,
t
);
if
(
state
.
ngrn
<
N_X_ARG_REG
)
context
->
x
[
state
.
ngrn
++
]
=
ext
;
else
{
void
*
d
=
allocate_to_stack
(
&
state
,
stack
,
ty
->
alignment
,
s
);
state
.
ngrn
=
N_X_ARG_REG
;
/* Note that the default abi extends each argument
to a full 64-bit slot, while the iOS abi allocates
only enough space. */
#ifdef __APPLE__
memcpy
(
d
,
a
,
s
);
#else
*
(
ffi_arg
*
)
d
=
ext
;
#endif
}
}
break
;
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
case
FFI_TYPE_LONGDOUBLE
:
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_COMPLEX
:
{
void
*
dest
;
h
=
is_vfp_type
(
ty
);
if
(
h
)
{
int
elems
=
4
-
(
h
&
3
);
if
(
state
.
nsrn
+
elems
<=
N_V_ARG_REG
)
{
dest
=
&
context
->
v
[
state
.
nsrn
];
state
.
nsrn
+=
elems
;
extend_hfa_type
(
dest
,
a
,
h
);
break
;
}
state
.
nsrn
=
N_V_ARG_REG
;
dest
=
allocate_to_stack
(
&
state
,
stack
,
ty
->
alignment
,
s
);
}
else
if
(
s
>
16
)
{
/* If the argument is a composite type that is larger than 16
bytes, then the argument has been copied to memory, and
the argument is replaced by a pointer to the copy. */
a
=
&
avalue
[
i
];
t
=
FFI_TYPE_POINTER
;
s
=
sizeof
(
void
*
);
goto
do_pointer
;
}
else
{
size_t
n
=
(
s
+
7
)
/
8
;
if
(
state
.
ngrn
+
n
<=
N_X_ARG_REG
)
{
/* If the argument is a composite type and the size in
double-words is not more than the number of available
X registers, then the argument is copied into
consecutive X registers. */
dest
=
&
context
->
x
[
state
.
ngrn
];
state
.
ngrn
+=
n
;
}
else
{
/* Otherwise, there are insufficient X registers. Further
X register allocations are prevented, the NSAA is
adjusted and the argument is copied to memory at the
adjusted NSAA. */
state
.
ngrn
=
N_X_ARG_REG
;
dest
=
allocate_to_stack
(
&
state
,
stack
,
ty
->
alignment
,
s
);
}
}
memcpy
(
dest
,
a
,
s
);
}
break
;
default:
abort
();
}
#if defined (__APPLE__)
if
(
i
+
1
==
cif
->
aarch64_nfixedargs
)
{
state
.
ngrn
=
N_X_ARG_REG
;
state
.
nsrn
=
N_V_ARG_REG
;
state
.
allocating_variadic
=
1
;
}
#endif
}
ffi_call_SYSV
(
context
,
frame
,
fn
,
rvalue
,
flags
,
closure
);
if
(
flags
&
AARCH64_RET_NEED_COPY
)
memcpy
(
orig_rvalue
,
rvalue
,
rtype_size
);
}
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)
(
void
),
void
*
rvalue
,
void
**
avalue
)
{
ffi_call_int
(
cif
,
fn
,
rvalue
,
avalue
,
NULL
);
}
#ifdef FFI_GO_CLOSURES
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)
(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
)
{
ffi_call_int
(
cif
,
fn
,
rvalue
,
avalue
,
closure
);
}
#endif
/* FFI_GO_CLOSURES */
/* Build a trampoline. */
extern
void
ffi_closure_SYSV
(
void
)
FFI_HIDDEN
;
extern
void
ffi_closure_SYSV_V
(
void
)
FFI_HIDDEN
;
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
)
{
if
(
cif
->
abi
!=
FFI_SYSV
)
return
FFI_BAD_ABI
;
void
(
*
start
)(
void
);
if
(
cif
->
flags
&
AARCH64_FLAG_ARG_V
)
start
=
ffi_closure_SYSV_V
;
else
start
=
ffi_closure_SYSV
;
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
void
**
config
=
(
void
**
)((
uint8_t
*
)
codeloc
-
PAGE_MAX_SIZE
);
config
[
0
]
=
closure
;
config
[
1
]
=
start
;
#endif
#else
static
const
unsigned
char
trampoline
[
16
]
=
{
0x90
,
0x00
,
0x00
,
0x58
,
/* ldr x16, tramp+16 */
0xf1
,
0xff
,
0xff
,
0x10
,
/* adr x17, tramp+0 */
0x00
,
0x02
,
0x1f
,
0xd6
/* br x16 */
};
char
*
tramp
=
closure
->
tramp
;
memcpy
(
tramp
,
trampoline
,
sizeof
(
trampoline
));
*
(
UINT64
*
)(
tramp
+
16
)
=
(
uintptr_t
)
start
;
ffi_clear_cache
(
tramp
,
tramp
+
FFI_TRAMPOLINE_SIZE
);
#endif
closure
->
cif
=
cif
;
closure
->
fun
=
fun
;
closure
->
user_data
=
user_data
;
return
FFI_OK
;
}
#ifdef FFI_GO_CLOSURES
extern
void
ffi_go_closure_SYSV
(
void
)
FFI_HIDDEN
;
extern
void
ffi_go_closure_SYSV_V
(
void
)
FFI_HIDDEN
;
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
))
{
void
(
*
start
)(
void
);
if
(
cif
->
abi
!=
FFI_SYSV
)
return
FFI_BAD_ABI
;
if
(
cif
->
flags
&
AARCH64_FLAG_ARG_V
)
start
=
ffi_go_closure_SYSV_V
;
else
start
=
ffi_go_closure_SYSV
;
closure
->
tramp
=
start
;
closure
->
cif
=
cif
;
closure
->
fun
=
fun
;
return
FFI_OK
;
}
#endif
/* FFI_GO_CLOSURES */
/* Primary handler to setup and invoke a function within a closure.
A closure when invoked enters via the assembler wrapper
ffi_closure_SYSV(). The wrapper allocates a call context on the
stack, saves the interesting registers (from the perspective of
the calling convention) into the context then passes control to
ffi_closure_SYSV_inner() passing the saved context and a pointer to
the stack at the point ffi_closure_SYSV() was invoked.
On the return path the assembler wrapper will reload call context
registers.
ffi_closure_SYSV_inner() marshalls the call context into ffi value
descriptors, invokes the wrapped function, then marshalls the return
value back into the call context. */
int
FFI_HIDDEN
ffi_closure_SYSV_inner
(
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
struct
call_context
*
context
,
void
*
stack
,
void
*
rvalue
,
void
*
struct_rvalue
)
{
void
**
avalue
=
(
void
**
)
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
int
i
,
h
,
nargs
,
flags
;
struct
arg_state
state
;
arg_init
(
&
state
);
for
(
i
=
0
,
nargs
=
cif
->
nargs
;
i
<
nargs
;
i
++
)
{
ffi_type
*
ty
=
cif
->
arg_types
[
i
];
int
t
=
ty
->
type
;
size_t
n
,
s
=
ty
->
size
;
switch
(
t
)
{
case
FFI_TYPE_VOID
:
FFI_ASSERT
(
0
);
break
;
case
FFI_TYPE_INT
:
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_POINTER
:
avalue
[
i
]
=
allocate_int_to_reg_or_stack
(
context
,
&
state
,
stack
,
s
);
break
;
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
case
FFI_TYPE_LONGDOUBLE
:
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_COMPLEX
:
h
=
is_vfp_type
(
ty
);
if
(
h
)
{
n
=
4
-
(
h
&
3
);
if
(
state
.
nsrn
+
n
<=
N_V_ARG_REG
)
{
void
*
reg
=
&
context
->
v
[
state
.
nsrn
];
state
.
nsrn
+=
n
;
/* Eeek! We need a pointer to the structure, however the
homogeneous float elements are being passed in individual
registers, therefore for float and double the structure
is not represented as a contiguous sequence of bytes in
our saved register context. We don't need the original
contents of the register storage, so we reformat the
structure into the same memory. */
avalue
[
i
]
=
compress_hfa_type
(
reg
,
reg
,
h
);
}
else
{
state
.
nsrn
=
N_V_ARG_REG
;
avalue
[
i
]
=
allocate_to_stack
(
&
state
,
stack
,
ty
->
alignment
,
s
);
}
}
else
if
(
s
>
16
)
{
/* Replace Composite type of size greater than 16 with a
pointer. */
avalue
[
i
]
=
*
(
void
**
)
allocate_int_to_reg_or_stack
(
context
,
&
state
,
stack
,
sizeof
(
void
*
));
}
else
{
n
=
(
s
+
7
)
/
8
;
if
(
state
.
ngrn
+
n
<=
N_X_ARG_REG
)
{
avalue
[
i
]
=
&
context
->
x
[
state
.
ngrn
];
state
.
ngrn
+=
n
;
}
else
{
state
.
ngrn
=
N_X_ARG_REG
;
avalue
[
i
]
=
allocate_to_stack
(
&
state
,
stack
,
ty
->
alignment
,
s
);
}
}
break
;
default:
abort
();
}
#if defined (__APPLE__)
if
(
i
+
1
==
cif
->
aarch64_nfixedargs
)
{
state
.
ngrn
=
N_X_ARG_REG
;
state
.
nsrn
=
N_V_ARG_REG
;
state
.
allocating_variadic
=
1
;
}
#endif
}
flags
=
cif
->
flags
;
if
(
flags
&
AARCH64_RET_IN_MEM
)
rvalue
=
struct_rvalue
;
fun
(
cif
,
rvalue
,
avalue
,
user_data
);
return
flags
;
}
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/aarch64/internal.h
0 → 100755
View file @
10c7897b
#if defined(__aarch64__) || defined(__arm64__)
/*
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define AARCH64_RET_VOID 0
#define AARCH64_RET_INT64 1
#define AARCH64_RET_INT128 2
#define AARCH64_RET_UNUSED3 3
#define AARCH64_RET_UNUSED4 4
#define AARCH64_RET_UNUSED5 5
#define AARCH64_RET_UNUSED6 6
#define AARCH64_RET_UNUSED7 7
/* Note that FFI_TYPE_FLOAT == 2, _DOUBLE == 3, _LONGDOUBLE == 4,
so _S4 through _Q1 are layed out as (TYPE * 4) + (4 - COUNT). */
#define AARCH64_RET_S4 8
#define AARCH64_RET_S3 9
#define AARCH64_RET_S2 10
#define AARCH64_RET_S1 11
#define AARCH64_RET_D4 12
#define AARCH64_RET_D3 13
#define AARCH64_RET_D2 14
#define AARCH64_RET_D1 15
#define AARCH64_RET_Q4 16
#define AARCH64_RET_Q3 17
#define AARCH64_RET_Q2 18
#define AARCH64_RET_Q1 19
/* Note that each of the sub-64-bit integers gets two entries. */
#define AARCH64_RET_UINT8 20
#define AARCH64_RET_UINT16 22
#define AARCH64_RET_UINT32 24
#define AARCH64_RET_SINT8 26
#define AARCH64_RET_SINT16 28
#define AARCH64_RET_SINT32 30
#define AARCH64_RET_MASK 31
#define AARCH64_RET_IN_MEM (1 << 5)
#define AARCH64_RET_NEED_COPY (1 << 6)
#define AARCH64_FLAG_ARG_V_BIT 7
#define AARCH64_FLAG_ARG_V (1 << AARCH64_FLAG_ARG_V_BIT)
#define N_X_ARG_REG 8
#define N_V_ARG_REG 8
#define CALL_CONTEXT_SIZE (N_V_ARG_REG * 16 + N_X_ARG_REG * 8)
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/aarch64/sysv_arm64.S
0 → 100755
View file @
10c7897b
#if defined(__aarch64__)
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_cfi.h>
#include "internal.h"
#ifdef HAVE_MACHINE_ASM_H
#include <machine/asm.h>
#else
#ifdef __USER_LABEL_PREFIX__
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
/* Use the right prefix for global labels. */
#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
#else
#define CNAME(x) x
#endif
#endif
#ifdef __AARCH64EB__
# define BE(X) X
#else
# define BE(X) 0
#endif
#ifdef __ILP32__
#define PTR_REG(n) w##n
#else
#define PTR_REG(n) x##n
#endif
#ifdef __ILP32__
#define PTR_SIZE 4
#else
#define PTR_SIZE 8
#endif
.text
.align 4
/* ffi_call_SYSV
extern void ffi_call_SYSV (void *stack, void *frame,
void (*fn)(void), void *rvalue,
int flags, void *closure);
Therefore on entry we have:
x0 stack
x1 frame
x2 fn
x3 rvalue
x4 flags
x5 closure
*/
cfi_startproc
CNAME(ffi_call_SYSV):
/* Use a stack frame allocated by our caller. */
cfi_def_cfa(x1, 32);
stp x29, x30, [x1]
mov x29, x1
mov sp, x0
cfi_def_cfa_register(x29)
cfi_rel_offset (x29, 0)
cfi_rel_offset (x30, 8)
mov x9, x2 /* save fn */
mov x8, x3 /* install structure return */
#ifdef FFI_GO_CLOSURES
mov x18, x5 /* install static chain */
#endif
stp x3, x4, [x29, #16] /* save rvalue and flags */
/* Load the vector argument passing registers, if necessary. */
tbz w4, #AARCH64_FLAG_ARG_V_BIT, 1f
ldp q0, q1, [sp, #0]
ldp q2, q3, [sp, #32]
ldp q4, q5, [sp, #64]
ldp q6, q7, [sp, #96]
1:
/* Load the core argument passing registers, including
the structure return pointer. */
ldp x0, x1, [sp, #16*N_V_ARG_REG + 0]
ldp x2, x3, [sp, #16*N_V_ARG_REG + 16]
ldp x4, x5, [sp, #16*N_V_ARG_REG + 32]
ldp x6, x7, [sp, #16*N_V_ARG_REG + 48]
/* Deallocate the context, leaving the stacked arguments. */
add sp, sp, #CALL_CONTEXT_SIZE
blr x9 /* call fn */
ldp x3, x4, [x29, #16] /* reload rvalue and flags */
/* Partially deconstruct the stack frame. */
mov sp, x29
cfi_def_cfa_register (sp)
ldp x29, x30, [x29]
/* Save the return value as directed. */
adr x5, 0f
and w4, w4, #AARCH64_RET_MASK
add x5, x5, x4, lsl #3
br x5
/* Note that each table entry is 2 insns, and thus 8 bytes.
For integer data, note that we're storing into ffi_arg
and therefore we want to extend to 64 bits; these types
have two consecutive entries allocated for them. */
.align 4
0: ret /* VOID */
nop
1: str x0, [x3] /* INT64 */
ret
2: stp x0, x1, [x3] /* INT128 */
ret
3: brk #1000 /* UNUSED */
ret
4: brk #1000 /* UNUSED */
ret
5: brk #1000 /* UNUSED */
ret
6: brk #1000 /* UNUSED */
ret
7: brk #1000 /* UNUSED */
ret
8: st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */
ret
9: st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */
ret
10: stp s0, s1, [x3] /* S2 */
ret
11: str s0, [x3] /* S1 */
ret
12: st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */
ret
13: st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */
ret
14: stp d0, d1, [x3] /* D2 */
ret
15: str d0, [x3] /* D1 */
ret
16: str q3, [x3, #48] /* Q4 */
nop
17: str q2, [x3, #32] /* Q3 */
nop
18: stp q0, q1, [x3] /* Q2 */
ret
19: str q0, [x3] /* Q1 */
ret
20: uxtb w0, w0 /* UINT8 */
str x0, [x3]
21: ret /* reserved */
nop
22: uxth w0, w0 /* UINT16 */
str x0, [x3]
23: ret /* reserved */
nop
24: mov w0, w0 /* UINT32 */
str x0, [x3]
25: ret /* reserved */
nop
26: sxtb x0, w0 /* SINT8 */
str x0, [x3]
27: ret /* reserved */
nop
28: sxth x0, w0 /* SINT16 */
str x0, [x3]
29: ret /* reserved */
nop
30: sxtw x0, w0 /* SINT32 */
str x0, [x3]
31: ret /* reserved */
nop
cfi_endproc
.globl CNAME(ffi_call_SYSV)
#ifdef __ELF__
.type CNAME(ffi_call_SYSV), #function
.hidden CNAME(ffi_call_SYSV)
.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
#endif
/* ffi_closure_SYSV
Closure invocation glue. This is the low level code invoked directly by
the closure trampoline to setup and call a closure.
On entry x17 points to a struct ffi_closure, x16 has been clobbered
all other registers are preserved.
We allocate a call context and save the argument passing registers,
then invoked the generic C ffi_closure_SYSV_inner() function to do all
the real work, on return we load the result passing registers back from
the call context.
*/
#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
.align 4
CNAME(ffi_closure_SYSV_V):
cfi_startproc
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
cfi_rel_offset (x29, 0)
cfi_rel_offset (x30, 8)
/* Save the argument passing vector registers. */
stp q0, q1, [sp, #16 + 0]
stp q2, q3, [sp, #16 + 32]
stp q4, q5, [sp, #16 + 64]
stp q6, q7, [sp, #16 + 96]
b 0f
cfi_endproc
.globl CNAME(ffi_closure_SYSV_V)
#ifdef __ELF__
.type CNAME(ffi_closure_SYSV_V), #function
.hidden CNAME(ffi_closure_SYSV_V)
.size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)
#endif
.align 4
cfi_startproc
CNAME(ffi_closure_SYSV):
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
cfi_rel_offset (x29, 0)
cfi_rel_offset (x30, 8)
0:
mov x29, sp
/* Save the argument passing core registers. */
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
/* Load ffi_closure_inner arguments. */
ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */
ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */
.Ldo_closure:
add x3, sp, #16 /* load context */
add x4, sp, #ffi_closure_SYSV_FS /* load stack */
add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */
mov x6, x8 /* load struct_rval */
bl CNAME(ffi_closure_SYSV_inner)
/* Load the return value as directed. */
adr x1, 0f
and w0, w0, #AARCH64_RET_MASK
add x1, x1, x0, lsl #3
add x3, sp, #16+CALL_CONTEXT_SIZE
br x1
/* Note that each table entry is 2 insns, and thus 8 bytes. */
.align 4
0: b 99f /* VOID */
nop
1: ldr x0, [x3] /* INT64 */
b 99f
2: ldp x0, x1, [x3] /* INT128 */
b 99f
3: brk #1000 /* UNUSED */
nop
4: brk #1000 /* UNUSED */
nop
5: brk #1000 /* UNUSED */
nop
6: brk #1000 /* UNUSED */
nop
7: brk #1000 /* UNUSED */
nop
8: ldr s3, [x3, #12] /* S4 */
nop
9: ldr s2, [x3, #8] /* S3 */
nop
10: ldp s0, s1, [x3] /* S2 */
b 99f
11: ldr s0, [x3] /* S1 */
b 99f
12: ldr d3, [x3, #24] /* D4 */
nop
13: ldr d2, [x3, #16] /* D3 */
nop
14: ldp d0, d1, [x3] /* D2 */
b 99f
15: ldr d0, [x3] /* D1 */
b 99f
16: ldr q3, [x3, #48] /* Q4 */
nop
17: ldr q2, [x3, #32] /* Q3 */
nop
18: ldp q0, q1, [x3] /* Q2 */
b 99f
19: ldr q0, [x3] /* Q1 */
b 99f
20: ldrb w0, [x3, #BE(7)] /* UINT8 */
b 99f
21: brk #1000 /* reserved */
nop
22: ldrh w0, [x3, #BE(6)] /* UINT16 */
b 99f
23: brk #1000 /* reserved */
nop
24: ldr w0, [x3, #BE(4)] /* UINT32 */
b 99f
25: brk #1000 /* reserved */
nop
26: ldrsb x0, [x3, #BE(7)] /* SINT8 */
b 99f
27: brk #1000 /* reserved */
nop
28: ldrsh x0, [x3, #BE(6)] /* SINT16 */
b 99f
29: brk #1000 /* reserved */
nop
30: ldrsw x0, [x3, #BE(4)] /* SINT32 */
nop
31: /* reserved */
99: ldp x29, x30, [sp], #ffi_closure_SYSV_FS
cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
cfi_restore (x29)
cfi_restore (x30)
ret
cfi_endproc
.globl CNAME(ffi_closure_SYSV)
#ifdef __ELF__
.type CNAME(ffi_closure_SYSV), #function
.hidden CNAME(ffi_closure_SYSV)
.size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)
#endif
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#include <mach/machine/vm_param.h>
.align PAGE_MAX_SHIFT
CNAME(ffi_closure_trampoline_table_page):
.rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
adr x16, -PAGE_MAX_SIZE
ldp x17, x16, [x16]
br x16
nop /* each entry in the trampoline config page is 2*sizeof(void*) so the trampoline itself cannot be smaller that 16 bytes */
.endr
.globl CNAME(ffi_closure_trampoline_table_page)
#ifdef __ELF__
.type CNAME(ffi_closure_trampoline_table_page), #function
.hidden CNAME(ffi_closure_trampoline_table_page)
.size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)
#endif
#endif
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
#ifdef FFI_GO_CLOSURES
.align 4
CNAME(ffi_go_closure_SYSV_V):
cfi_startproc
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
cfi_rel_offset (x29, 0)
cfi_rel_offset (x30, 8)
/* Save the argument passing vector registers. */
stp q0, q1, [sp, #16 + 0]
stp q2, q3, [sp, #16 + 32]
stp q4, q5, [sp, #16 + 64]
stp q6, q7, [sp, #16 + 96]
b 0f
cfi_endproc
.globl CNAME(ffi_go_closure_SYSV_V)
#ifdef __ELF__
.type CNAME(ffi_go_closure_SYSV_V), #function
.hidden CNAME(ffi_go_closure_SYSV_V)
.size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)
#endif
.align 4
cfi_startproc
CNAME(ffi_go_closure_SYSV):
stp x29, x30, [sp, #-ffi_closure_SYSV_FS]!
cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
cfi_rel_offset (x29, 0)
cfi_rel_offset (x30, 8)
0:
mov x29, sp
/* Save the argument passing core registers. */
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
/* Load ffi_closure_inner arguments. */
ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
mov x2, x18 /* load user_data */
b .Ldo_closure
cfi_endproc
.globl CNAME(ffi_go_closure_SYSV)
#ifdef __ELF__
.type CNAME(ffi_go_closure_SYSV), #function
.hidden CNAME(ffi_go_closure_SYSV)
.size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)
#endif
#endif /* FFI_GO_CLOSURES */
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif
#endif
nativehook/src/main/cpp/libffi/arm/ffi_armv7.c
0 → 100755
View file @
10c7897b
#ifdef __arm__
/* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2011 Timothy Wall
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
Copyright (c) 2011 Anthony Green
Copyright (c) 2011 Free Software Foundation
Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_common.h>
#include <stdint.h>
#include <stdlib.h>
#include "internal.h"
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#include <mach/machine/vm_param.h>
#endif
#else
extern
unsigned
int
ffi_arm_trampoline
[
2
]
FFI_HIDDEN
;
#endif
/* Forward declares. */
static
int
vfp_type_p
(
const
ffi_type
*
);
static
void
layout_vfp_args
(
ffi_cif
*
);
static
void
*
ffi_align
(
ffi_type
*
ty
,
void
*
p
)
{
/* Align if necessary */
size_t
alignment
;
#ifdef _WIN32_WCE
alignment
=
4
;
#else
alignment
=
ty
->
alignment
;
if
(
alignment
<
4
)
alignment
=
4
;
#endif
return
(
void
*
)
FFI_ALIGN
(
p
,
alignment
);
}
static
size_t
ffi_put_arg
(
ffi_type
*
ty
,
void
*
src
,
void
*
dst
)
{
size_t
z
=
ty
->
size
;
switch
(
ty
->
type
)
{
case
FFI_TYPE_SINT8
:
*
(
UINT32
*
)
dst
=
*
(
SINT8
*
)
src
;
break
;
case
FFI_TYPE_UINT8
:
*
(
UINT32
*
)
dst
=
*
(
UINT8
*
)
src
;
break
;
case
FFI_TYPE_SINT16
:
*
(
UINT32
*
)
dst
=
*
(
SINT16
*
)
src
;
break
;
case
FFI_TYPE_UINT16
:
*
(
UINT32
*
)
dst
=
*
(
UINT16
*
)
src
;
break
;
case
FFI_TYPE_INT
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_POINTER
:
case
FFI_TYPE_FLOAT
:
*
(
UINT32
*
)
dst
=
*
(
UINT32
*
)
src
;
break
;
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_DOUBLE
:
*
(
UINT64
*
)
dst
=
*
(
UINT64
*
)
src
;
break
;
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_COMPLEX
:
memcpy
(
dst
,
src
,
z
);
break
;
default:
abort
();
}
return
FFI_ALIGN
(
z
,
4
);
}
/* ffi_prep_args is called once stack space has been allocated
for the function's arguments.
The vfp_space parameter is the load area for VFP regs, the return
value is cif->vfp_used (word bitset of VFP regs used for passing
arguments). These are only used for the VFP hard-float ABI.
*/
static
void
ffi_prep_args_SYSV
(
ffi_cif
*
cif
,
int
flags
,
void
*
rvalue
,
void
**
avalue
,
char
*
argp
)
{
ffi_type
**
arg_types
=
cif
->
arg_types
;
int
i
,
n
;
if
(
flags
==
ARM_TYPE_STRUCT
)
{
*
(
void
**
)
argp
=
rvalue
;
argp
+=
4
;
}
for
(
i
=
0
,
n
=
cif
->
nargs
;
i
<
n
;
i
++
)
{
ffi_type
*
ty
=
arg_types
[
i
];
argp
=
ffi_align
(
ty
,
argp
);
argp
+=
ffi_put_arg
(
ty
,
avalue
[
i
],
argp
);
}
}
static
void
ffi_prep_args_VFP
(
ffi_cif
*
cif
,
int
flags
,
void
*
rvalue
,
void
**
avalue
,
char
*
stack
,
char
*
vfp_space
)
{
ffi_type
**
arg_types
=
cif
->
arg_types
;
int
i
,
n
,
vi
=
0
;
char
*
argp
,
*
regp
,
*
eo_regp
;
char
stack_used
=
0
;
char
done_with_regs
=
0
;
/* The first 4 words on the stack are used for values
passed in core registers. */
regp
=
stack
;
eo_regp
=
argp
=
regp
+
16
;
/* If the function returns an FFI_TYPE_STRUCT in memory,
that address is passed in r0 to the function. */
if
(
flags
==
ARM_TYPE_STRUCT
)
{
*
(
void
**
)
regp
=
rvalue
;
regp
+=
4
;
}
for
(
i
=
0
,
n
=
cif
->
nargs
;
i
<
n
;
i
++
)
{
ffi_type
*
ty
=
arg_types
[
i
];
void
*
a
=
avalue
[
i
];
int
is_vfp_type
=
vfp_type_p
(
ty
);
/* Allocated in VFP registers. */
if
(
vi
<
cif
->
vfp_nargs
&&
is_vfp_type
)
{
char
*
vfp_slot
=
vfp_space
+
cif
->
vfp_args
[
vi
++
]
*
4
;
ffi_put_arg
(
ty
,
a
,
vfp_slot
);
continue
;
}
/* Try allocating in core registers. */
else
if
(
!
done_with_regs
&&
!
is_vfp_type
)
{
char
*
tregp
=
ffi_align
(
ty
,
regp
);
size_t
size
=
ty
->
size
;
size
=
(
size
<
4
)
?
4
:
size
;
// pad
/* Check if there is space left in the aligned register
area to place the argument. */
if
(
tregp
+
size
<=
eo_regp
)
{
regp
=
tregp
+
ffi_put_arg
(
ty
,
a
,
tregp
);
done_with_regs
=
(
regp
==
argp
);
// ensure we did not write into the stack area
FFI_ASSERT
(
regp
<=
argp
);
continue
;
}
/* In case there are no arguments in the stack area yet,
the argument is passed in the remaining core registers
and on the stack. */
else
if
(
!
stack_used
)
{
stack_used
=
1
;
done_with_regs
=
1
;
argp
=
tregp
+
ffi_put_arg
(
ty
,
a
,
tregp
);
FFI_ASSERT
(
eo_regp
<
argp
);
continue
;
}
}
/* Base case, arguments are passed on the stack */
stack_used
=
1
;
argp
=
ffi_align
(
ty
,
argp
);
argp
+=
ffi_put_arg
(
ty
,
a
,
argp
);
}
}
/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
)
{
int
flags
=
0
,
cabi
=
cif
->
abi
;
size_t
bytes
=
cif
->
bytes
;
/* Map out the register placements of VFP register args. The VFP
hard-float calling conventions are slightly more sophisticated
than the base calling conventions, so we do it here instead of
in ffi_prep_args(). */
if
(
cabi
==
FFI_VFP
)
layout_vfp_args
(
cif
);
/* Set the return type flag */
switch
(
cif
->
rtype
->
type
)
{
case
FFI_TYPE_VOID
:
flags
=
ARM_TYPE_VOID
;
break
;
case
FFI_TYPE_INT
:
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_POINTER
:
flags
=
ARM_TYPE_INT
;
break
;
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_UINT64
:
flags
=
ARM_TYPE_INT64
;
break
;
case
FFI_TYPE_FLOAT
:
flags
=
(
cabi
==
FFI_VFP
?
ARM_TYPE_VFP_S
:
ARM_TYPE_INT
);
break
;
case
FFI_TYPE_DOUBLE
:
flags
=
(
cabi
==
FFI_VFP
?
ARM_TYPE_VFP_D
:
ARM_TYPE_INT64
);
break
;
case
FFI_TYPE_STRUCT
:
case
FFI_TYPE_COMPLEX
:
if
(
cabi
==
FFI_VFP
)
{
int
h
=
vfp_type_p
(
cif
->
rtype
);
flags
=
ARM_TYPE_VFP_N
;
if
(
h
==
0x100
+
FFI_TYPE_FLOAT
)
flags
=
ARM_TYPE_VFP_S
;
if
(
h
==
0x100
+
FFI_TYPE_DOUBLE
)
flags
=
ARM_TYPE_VFP_D
;
if
(
h
!=
0
)
break
;
}
/* A Composite Type not larger than 4 bytes is returned in r0.
A Composite Type larger than 4 bytes, or whose size cannot
be determined statically ... is stored in memory at an
address passed [in r0]. */
if
(
cif
->
rtype
->
size
<=
4
)
flags
=
ARM_TYPE_INT
;
else
{
flags
=
ARM_TYPE_STRUCT
;
bytes
+=
4
;
}
break
;
default:
abort
();
}
/* Round the stack up to a multiple of 8 bytes. This isn't needed
everywhere, but it is on some platforms, and it doesn't harm anything
when it isn't needed. */
bytes
=
FFI_ALIGN
(
bytes
,
8
);
/* Minimum stack space is the 4 register arguments that we pop. */
if
(
bytes
<
4
*
4
)
bytes
=
4
*
4
;
cif
->
bytes
=
bytes
;
cif
->
flags
=
flags
;
return
FFI_OK
;
}
/* Perform machine dependent cif processing for variadic calls */
ffi_status
ffi_prep_cif_machdep_var
(
ffi_cif
*
cif
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
)
{
/* VFP variadic calls actually use the SYSV ABI */
if
(
cif
->
abi
==
FFI_VFP
)
cif
->
abi
=
FFI_SYSV
;
return
ffi_prep_cif_machdep
(
cif
);
}
/* Prototypes for assembly functions, in sysv.S. */
struct
call_frame
{
void
*
fp
;
void
*
lr
;
void
*
rvalue
;
int
flags
;
void
*
closure
;
};
extern
void
ffi_call_SYSV
(
void
*
stack
,
struct
call_frame
*
,
void
(
*
fn
)
(
void
))
FFI_HIDDEN
;
extern
void
ffi_call_VFP
(
void
*
vfp_space
,
struct
call_frame
*
,
void
(
*
fn
)
(
void
),
unsigned
vfp_used
)
FFI_HIDDEN
;
static
void
ffi_call_int
(
ffi_cif
*
cif
,
void
(
*
fn
)
(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
)
{
int
flags
=
cif
->
flags
;
ffi_type
*
rtype
=
cif
->
rtype
;
size_t
bytes
,
rsize
,
vfp_size
;
char
*
stack
,
*
vfp_space
,
*
new_rvalue
;
struct
call_frame
*
frame
;
rsize
=
0
;
if
(
rvalue
==
NULL
)
{
/* If the return value is a struct and we don't have a return
value address then we need to make one. Otherwise the return
value is in registers and we can ignore them. */
if
(
flags
==
ARM_TYPE_STRUCT
)
rsize
=
rtype
->
size
;
else
flags
=
ARM_TYPE_VOID
;
}
else
if
(
flags
==
ARM_TYPE_VFP_N
)
{
/* Largest case is double x 4. */
rsize
=
32
;
}
else
if
(
flags
==
ARM_TYPE_INT
&&
rtype
->
type
==
FFI_TYPE_STRUCT
)
rsize
=
4
;
/* Largest case. */
vfp_size
=
(
cif
->
abi
==
FFI_VFP
&&
cif
->
vfp_used
?
8
*
8
:
0
);
bytes
=
cif
->
bytes
;
stack
=
alloca
(
vfp_size
+
bytes
+
sizeof
(
struct
call_frame
)
+
rsize
);
vfp_space
=
NULL
;
if
(
vfp_size
)
{
vfp_space
=
stack
;
stack
+=
vfp_size
;
}
frame
=
(
struct
call_frame
*
)(
stack
+
bytes
);
new_rvalue
=
rvalue
;
if
(
rsize
)
new_rvalue
=
(
void
*
)(
frame
+
1
);
frame
->
rvalue
=
new_rvalue
;
frame
->
flags
=
flags
;
frame
->
closure
=
closure
;
if
(
vfp_space
)
{
ffi_prep_args_VFP
(
cif
,
flags
,
new_rvalue
,
avalue
,
stack
,
vfp_space
);
ffi_call_VFP
(
vfp_space
,
frame
,
fn
,
cif
->
vfp_used
);
}
else
{
ffi_prep_args_SYSV
(
cif
,
flags
,
new_rvalue
,
avalue
,
stack
);
ffi_call_SYSV
(
stack
,
frame
,
fn
);
}
if
(
rvalue
&&
rvalue
!=
new_rvalue
)
memcpy
(
rvalue
,
new_rvalue
,
rtype
->
size
);
}
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)
(
void
),
void
*
rvalue
,
void
**
avalue
)
{
ffi_call_int
(
cif
,
fn
,
rvalue
,
avalue
,
NULL
);
}
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)
(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
)
{
ffi_call_int
(
cif
,
fn
,
rvalue
,
avalue
,
closure
);
}
static
void
*
ffi_prep_incoming_args_SYSV
(
ffi_cif
*
cif
,
void
*
rvalue
,
char
*
argp
,
void
**
avalue
)
{
ffi_type
**
arg_types
=
cif
->
arg_types
;
int
i
,
n
;
if
(
cif
->
flags
==
ARM_TYPE_STRUCT
)
{
rvalue
=
*
(
void
**
)
argp
;
argp
+=
4
;
}
else
{
if
(
cif
->
rtype
->
size
&&
cif
->
rtype
->
size
<
4
)
*
(
uint32_t
*
)
rvalue
=
0
;
}
for
(
i
=
0
,
n
=
cif
->
nargs
;
i
<
n
;
i
++
)
{
ffi_type
*
ty
=
arg_types
[
i
];
size_t
z
=
ty
->
size
;
argp
=
ffi_align
(
ty
,
argp
);
avalue
[
i
]
=
(
void
*
)
argp
;
argp
+=
z
;
}
return
rvalue
;
}
static
void
*
ffi_prep_incoming_args_VFP
(
ffi_cif
*
cif
,
void
*
rvalue
,
char
*
stack
,
char
*
vfp_space
,
void
**
avalue
)
{
ffi_type
**
arg_types
=
cif
->
arg_types
;
int
i
,
n
,
vi
=
0
;
char
*
argp
,
*
regp
,
*
eo_regp
;
char
done_with_regs
=
0
;
char
stack_used
=
0
;
regp
=
stack
;
eo_regp
=
argp
=
regp
+
16
;
if
(
cif
->
flags
==
ARM_TYPE_STRUCT
)
{
rvalue
=
*
(
void
**
)
regp
;
regp
+=
4
;
}
for
(
i
=
0
,
n
=
cif
->
nargs
;
i
<
n
;
i
++
)
{
ffi_type
*
ty
=
arg_types
[
i
];
int
is_vfp_type
=
vfp_type_p
(
ty
);
size_t
z
=
ty
->
size
;
if
(
vi
<
cif
->
vfp_nargs
&&
is_vfp_type
)
{
avalue
[
i
]
=
vfp_space
+
cif
->
vfp_args
[
vi
++
]
*
4
;
continue
;
}
else
if
(
!
done_with_regs
&&
!
is_vfp_type
)
{
char
*
tregp
=
ffi_align
(
ty
,
regp
);
z
=
(
z
<
4
)
?
4
:
z
;
// pad
/* If the arguments either fits into the registers or uses registers
and stack, while we haven't read other things from the stack */
if
(
tregp
+
z
<=
eo_regp
||
!
stack_used
)
{
/* Because we're little endian, this is what it turns into. */
avalue
[
i
]
=
(
void
*
)
tregp
;
regp
=
tregp
+
z
;
/* If we read past the last core register, make sure we
have not read from the stack before and continue
reading after regp. */
if
(
regp
>
eo_regp
)
{
FFI_ASSERT
(
!
stack_used
);
argp
=
regp
;
}
if
(
regp
>=
eo_regp
)
{
done_with_regs
=
1
;
stack_used
=
1
;
}
continue
;
}
}
stack_used
=
1
;
argp
=
ffi_align
(
ty
,
argp
);
avalue
[
i
]
=
(
void
*
)
argp
;
argp
+=
z
;
}
return
rvalue
;
}
struct
closure_frame
{
char
vfp_space
[
8
*
8
]
__attribute__
((
aligned
(
8
)));
char
result
[
8
*
4
];
char
argp
[];
};
int
FFI_HIDDEN
ffi_closure_inner_SYSV
(
ffi_cif
*
cif
,
void
(
*
fun
)
(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
struct
closure_frame
*
frame
)
{
void
**
avalue
=
(
void
**
)
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
void
*
rvalue
=
ffi_prep_incoming_args_SYSV
(
cif
,
frame
->
result
,
frame
->
argp
,
avalue
);
fun
(
cif
,
rvalue
,
avalue
,
user_data
);
return
cif
->
flags
;
}
int
FFI_HIDDEN
ffi_closure_inner_VFP
(
ffi_cif
*
cif
,
void
(
*
fun
)
(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
struct
closure_frame
*
frame
)
{
void
**
avalue
=
(
void
**
)
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
void
*
rvalue
=
ffi_prep_incoming_args_VFP
(
cif
,
frame
->
result
,
frame
->
argp
,
frame
->
vfp_space
,
avalue
);
fun
(
cif
,
rvalue
,
avalue
,
user_data
);
return
cif
->
flags
;
}
void
ffi_closure_SYSV
(
void
)
FFI_HIDDEN
;
void
ffi_closure_VFP
(
void
)
FFI_HIDDEN
;
void
ffi_go_closure_SYSV
(
void
)
FFI_HIDDEN
;
void
ffi_go_closure_VFP
(
void
)
FFI_HIDDEN
;
/* the cif must already be prep'ed */
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)
(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
)
{
void
(
*
closure_func
)
(
void
)
=
ffi_closure_SYSV
;
if
(
cif
->
abi
==
FFI_VFP
)
{
/* We only need take the vfp path if there are vfp arguments. */
if
(
cif
->
vfp_used
)
closure_func
=
ffi_closure_VFP
;
}
else
if
(
cif
->
abi
!=
FFI_SYSV
)
return
FFI_BAD_ABI
;
#if FFI_EXEC_TRAMPOLINE_TABLE
void
**
config
=
(
void
**
)((
uint8_t
*
)
codeloc
-
PAGE_MAX_SIZE
);
config
[
0
]
=
closure
;
config
[
1
]
=
closure_func
;
#else
memcpy
(
closure
->
tramp
,
ffi_arm_trampoline
,
8
);
#if defined (__QNX__)
msync
(
closure
->
tramp
,
8
,
0x1000000
);
/* clear data map */
msync
(
codeloc
,
8
,
0x1000000
);
/* clear insn map */
#else
__clear_cache
(
closure
->
tramp
,
closure
->
tramp
+
8
);
/* clear data map */
__clear_cache
(
codeloc
,
codeloc
+
8
);
/* clear insn map */
#endif
*
(
void
(
**
)(
void
))(
closure
->
tramp
+
8
)
=
closure_func
;
#endif
closure
->
cif
=
cif
;
closure
->
fun
=
fun
;
closure
->
user_data
=
user_data
;
return
FFI_OK
;
}
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)
(
ffi_cif
*
,
void
*
,
void
**
,
void
*
))
{
void
(
*
closure_func
)
(
void
)
=
ffi_go_closure_SYSV
;
if
(
cif
->
abi
==
FFI_VFP
)
{
/* We only need take the vfp path if there are vfp arguments. */
if
(
cif
->
vfp_used
)
closure_func
=
ffi_go_closure_VFP
;
}
else
if
(
cif
->
abi
!=
FFI_SYSV
)
return
FFI_BAD_ABI
;
closure
->
tramp
=
closure_func
;
closure
->
cif
=
cif
;
closure
->
fun
=
fun
;
return
FFI_OK
;
}
/* Below are routines for VFP hard-float support. */
/* A subroutine of vfp_type_p. Given a structure type, return the type code
of the first non-structure element. Recurse for structure elements.
Return -1 if the structure is in fact empty, i.e. no nested elements. */
static
int
is_hfa0
(
const
ffi_type
*
ty
)
{
ffi_type
**
elements
=
ty
->
elements
;
int
i
,
ret
=
-
1
;
if
(
elements
!=
NULL
)
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
ret
=
elements
[
i
]
->
type
;
if
(
ret
==
FFI_TYPE_STRUCT
||
ret
==
FFI_TYPE_COMPLEX
)
{
ret
=
is_hfa0
(
elements
[
i
]);
if
(
ret
<
0
)
continue
;
}
break
;
}
return
ret
;
}
/* A subroutine of vfp_type_p. Given a structure type, return true if all
of the non-structure elements are the same as CANDIDATE. */
static
int
is_hfa1
(
const
ffi_type
*
ty
,
int
candidate
)
{
ffi_type
**
elements
=
ty
->
elements
;
int
i
;
if
(
elements
!=
NULL
)
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
int
t
=
elements
[
i
]
->
type
;
if
(
t
==
FFI_TYPE_STRUCT
||
t
==
FFI_TYPE_COMPLEX
)
{
if
(
!
is_hfa1
(
elements
[
i
],
candidate
))
return
0
;
}
else
if
(
t
!=
candidate
)
return
0
;
}
return
1
;
}
/* Determine if TY is an homogenous floating point aggregate (HFA).
That is, a structure consisting of 1 to 4 members of all the same type,
where that type is a floating point scalar.
Returns non-zero iff TY is an HFA. The result is an encoded value where
bits 0-7 contain the type code, and bits 8-10 contain the element count. */
static
int
vfp_type_p
(
const
ffi_type
*
ty
)
{
ffi_type
**
elements
;
int
candidate
,
i
;
size_t
size
,
ele_count
;
/* Quickest tests first. */
candidate
=
ty
->
type
;
switch
(
ty
->
type
)
{
default:
return
0
;
case
FFI_TYPE_FLOAT
:
case
FFI_TYPE_DOUBLE
:
ele_count
=
1
;
goto
done
;
case
FFI_TYPE_COMPLEX
:
candidate
=
ty
->
elements
[
0
]
->
type
;
if
(
candidate
!=
FFI_TYPE_FLOAT
&&
candidate
!=
FFI_TYPE_DOUBLE
)
return
0
;
ele_count
=
2
;
goto
done
;
case
FFI_TYPE_STRUCT
:
break
;
}
/* No HFA types are smaller than 4 bytes, or larger than 32 bytes. */
size
=
ty
->
size
;
if
(
size
<
4
||
size
>
32
)
return
0
;
/* Find the type of the first non-structure member. */
elements
=
ty
->
elements
;
candidate
=
elements
[
0
]
->
type
;
if
(
candidate
==
FFI_TYPE_STRUCT
||
candidate
==
FFI_TYPE_COMPLEX
)
{
for
(
i
=
0
;
;
++
i
)
{
candidate
=
is_hfa0
(
elements
[
i
]);
if
(
candidate
>=
0
)
break
;
}
}
/* If the first member is not a floating point type, it's not an HFA.
Also quickly re-check the size of the structure. */
switch
(
candidate
)
{
case
FFI_TYPE_FLOAT
:
ele_count
=
size
/
sizeof
(
float
);
if
(
size
!=
ele_count
*
sizeof
(
float
))
return
0
;
break
;
case
FFI_TYPE_DOUBLE
:
ele_count
=
size
/
sizeof
(
double
);
if
(
size
!=
ele_count
*
sizeof
(
double
))
return
0
;
break
;
default:
return
0
;
}
if
(
ele_count
>
4
)
return
0
;
/* Finally, make sure that all scalar elements are the same type. */
for
(
i
=
0
;
elements
[
i
];
++
i
)
{
int
t
=
elements
[
i
]
->
type
;
if
(
t
==
FFI_TYPE_STRUCT
||
t
==
FFI_TYPE_COMPLEX
)
{
if
(
!
is_hfa1
(
elements
[
i
],
candidate
))
return
0
;
}
else
if
(
t
!=
candidate
)
return
0
;
}
/* All tests succeeded. Encode the result. */
done:
return
(
ele_count
<<
8
)
|
candidate
;
}
static
int
place_vfp_arg
(
ffi_cif
*
cif
,
int
h
)
{
unsigned
short
reg
=
cif
->
vfp_reg_free
;
int
align
=
1
,
nregs
=
h
>>
8
;
if
((
h
&
0xff
)
==
FFI_TYPE_DOUBLE
)
align
=
2
,
nregs
*=
2
;
/* Align register number. */
if
((
reg
&
1
)
&&
align
==
2
)
reg
++
;
while
(
reg
+
nregs
<=
16
)
{
int
s
,
new_used
=
0
;
for
(
s
=
reg
;
s
<
reg
+
nregs
;
s
++
)
{
new_used
|=
(
1
<<
s
);
if
(
cif
->
vfp_used
&
(
1
<<
s
))
{
reg
+=
align
;
goto
next_reg
;
}
}
/* Found regs to allocate. */
cif
->
vfp_used
|=
new_used
;
cif
->
vfp_args
[
cif
->
vfp_nargs
++
]
=
reg
;
/* Update vfp_reg_free. */
if
(
cif
->
vfp_used
&
(
1
<<
cif
->
vfp_reg_free
))
{
reg
+=
nregs
;
while
(
cif
->
vfp_used
&
(
1
<<
reg
))
reg
+=
1
;
cif
->
vfp_reg_free
=
reg
;
}
return
0
;
next_reg:
;
}
// done, mark all regs as used
cif
->
vfp_reg_free
=
16
;
cif
->
vfp_used
=
0xFFFF
;
return
1
;
}
static
void
layout_vfp_args
(
ffi_cif
*
cif
)
{
int
i
;
/* Init VFP fields */
cif
->
vfp_used
=
0
;
cif
->
vfp_nargs
=
0
;
cif
->
vfp_reg_free
=
0
;
memset
(
cif
->
vfp_args
,
-
1
,
16
);
/* Init to -1. */
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
)
{
int
h
=
vfp_type_p
(
cif
->
arg_types
[
i
]);
if
(
h
&&
place_vfp_arg
(
cif
,
h
)
==
1
)
break
;
}
}
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/arm/internal.h
0 → 100755
View file @
10c7897b
#ifdef __arm__
#define ARM_TYPE_VFP_S 0
#define ARM_TYPE_VFP_D 1
#define ARM_TYPE_VFP_N 2
#define ARM_TYPE_INT64 3
#define ARM_TYPE_INT 4
#define ARM_TYPE_VOID 5
#define ARM_TYPE_STRUCT 6
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/arm/sysv_armv7.S
0 → 100755
View file @
10c7897b
#ifdef __arm__
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
ARM Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#define LIBFFI_ASM
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_cfi.h>
#include "internal.h"
/* GCC 4.8 provides __ARM_ARCH; construct it otherwise. */
#ifndef __ARM_ARCH
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__)
# define __ARM_ARCH 7
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) \
|| defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) \
|| defined(__ARM_ARCH_6M__)
# define __ARM_ARCH 6
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) \
|| defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) \
|| defined(__ARM_ARCH_5TEJ__)
# define __ARM_ARCH 5
# else
# define __ARM_ARCH 4
# endif
#endif
/* Conditionally compile unwinder directives. */
#ifdef __ARM_EABI__
# define UNWIND(...) __VA_ARGS__
#else
# define UNWIND(...)
#endif
#if defined(HAVE_AS_CFI_PSEUDO_OP) && defined(__ARM_EABI__)
.cfi_sections .debug_frame
#endif
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
#ifdef __USER_LABEL_PREFIX__
# define CNAME(X) CONCAT (__USER_LABEL_PREFIX__, X)
#else
# define CNAME(X) X
#endif
#ifdef __ELF__
# define SIZE(X) .size CNAME(X), . - CNAME(X)
# define TYPE(X, Y) .type CNAME(X), Y
#else
# define SIZE(X)
# define TYPE(X, Y)
#endif
#define ARM_FUNC_START_LOCAL(name) \
.align 3; \
TYPE(CNAME(name), %function); \
CNAME(name):
#define ARM_FUNC_START(name) \
.globl CNAME(name); \
FFI_HIDDEN(CNAME(name)); \
ARM_FUNC_START_LOCAL(name)
#define ARM_FUNC_END(name) \
SIZE(name)
/* Aid in defining a jump table with 8 bytes between entries. */
/* ??? The clang assembler doesn't handle .if with symbolic expressions. */
#ifdef __clang__
# define E(index)
#else
# define E(index) \
.if . - 0b - 8*index; \
.error "type table out of sync"; \
.endif
#endif
.text
.syntax unified
.arm
#ifndef __clang__
/* We require interworking on LDM, which implies ARMv5T,
which implies the existance of BLX. */
.arch armv5t
#endif
/* Note that we use STC and LDC to encode VFP instructions,
so that we do not need ".fpu vfp", nor get that added to
the object file attributes. These will not be executed
unless the FFI_VFP abi is used. */
@ r0: stack
@ r1: frame
@ r2: fn
@ r3: vfp_used
ARM_FUNC_START(ffi_call_VFP)
UNWIND(.fnstart)
cfi_startproc
cmp r3, #3 @ load only d0 if possible
#ifdef __clang__
vldrle d0, [sp]
vldmgt sp, {d0-d7}
#else
ldcle p11, cr0, [r0] @ vldrle d0, [sp]
ldcgt p11, cr0, [r0], {16} @ vldmgt sp, {d0-d7}
#endif
add r0, r0, #64 @ discard the vfp register args
/* FALLTHRU */
ARM_FUNC_END(ffi_call_VFP)
ARM_FUNC_START(ffi_call_SYSV)
stm r1, {fp, lr}
mov fp, r1
@ This is a bit of a lie wrt the origin of the unwind info, but
@ now we've got the usual frame pointer and two saved registers.
UNWIND(.save {fp,lr})
UNWIND(.setfp fp, sp)
cfi_def_cfa(fp, 8)
cfi_rel_offset(fp, 0)
cfi_rel_offset(lr, 4)
mov sp, r0 @ install the stack pointer
mov lr, r2 @ move the fn pointer out of the way
ldr ip, [fp, #16] @ install the static chain
ldmia sp!, {r0-r3} @ move first 4 parameters in registers.
blx lr @ call fn
@ Load r2 with the pointer to storage for the return value
@ Load r3 with the return type code
ldr r2, [fp, #8]
ldr r3, [fp, #12]
@ Deallocate the stack with the arguments.
mov sp, fp
cfi_def_cfa_register(sp)
@ Store values stored in registers.
.align 3
add pc, pc, r3, lsl #3
nop
0:
E(ARM_TYPE_VFP_S)
#ifdef __clang__
vstr s0, [r2]
#else
stc p10, cr0, [r2] @ vstr s0, [r2]
#endif
pop {fp,pc}
E(ARM_TYPE_VFP_D)
#ifdef __clang__
vstr d0, [r2]
#else
stc p11, cr0, [r2] @ vstr d0, [r2]
#endif
pop {fp,pc}
E(ARM_TYPE_VFP_N)
#ifdef __clang__
vstm r2, {d0-d3}
#else
stc p11, cr0, [r2], {8} @ vstm r2, {d0-d3}
#endif
pop {fp,pc}
E(ARM_TYPE_INT64)
str r1, [r2, #4]
nop
E(ARM_TYPE_INT)
str r0, [r2]
pop {fp,pc}
E(ARM_TYPE_VOID)
pop {fp,pc}
nop
E(ARM_TYPE_STRUCT)
pop {fp,pc}
cfi_endproc
UNWIND(.fnend)
ARM_FUNC_END(ffi_call_SYSV)
/*
int ffi_closure_inner_* (cif, fun, user_data, frame)
*/
ARM_FUNC_START(ffi_go_closure_SYSV)
cfi_startproc
stmdb sp!, {r0-r3} @ save argument regs
cfi_adjust_cfa_offset(16)
ldr r0, [ip, #4] @ load cif
ldr r1, [ip, #8] @ load fun
mov r2, ip @ load user_data
b 0f
cfi_endproc
ARM_FUNC_END(ffi_go_closure_SYSV)
ARM_FUNC_START(ffi_closure_SYSV)
UNWIND(.fnstart)
cfi_startproc
stmdb sp!, {r0-r3} @ save argument regs
cfi_adjust_cfa_offset(16)
#if FFI_EXEC_TRAMPOLINE_TABLE
ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
#endif
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
0:
add ip, sp, #16 @ compute entry sp
sub sp, sp, #64+32 @ allocate frame
cfi_adjust_cfa_offset(64+32)
stmdb sp!, {ip,lr}
/* Remember that EABI unwind info only applies at call sites.
We need do nothing except note the save of the stack pointer
and the link registers. */
UNWIND(.save {sp,lr})
cfi_adjust_cfa_offset(8)
cfi_rel_offset(lr, 4)
add r3, sp, #8 @ load frame
bl CNAME(ffi_closure_inner_SYSV)
@ Load values returned in registers.
add r2, sp, #8+64 @ load result
adr r3, CNAME(ffi_closure_ret)
add pc, r3, r0, lsl #3
cfi_endproc
UNWIND(.fnend)
ARM_FUNC_END(ffi_closure_SYSV)
ARM_FUNC_START(ffi_go_closure_VFP)
cfi_startproc
stmdb sp!, {r0-r3} @ save argument regs
cfi_adjust_cfa_offset(16)
ldr r0, [ip, #4] @ load cif
ldr r1, [ip, #8] @ load fun
mov r2, ip @ load user_data
b 0f
cfi_endproc
ARM_FUNC_END(ffi_go_closure_VFP)
ARM_FUNC_START(ffi_closure_VFP)
UNWIND(.fnstart)
cfi_startproc
stmdb sp!, {r0-r3} @ save argument regs
cfi_adjust_cfa_offset(16)
#if FFI_EXEC_TRAMPOLINE_TABLE
ldr ip, [ip] @ ip points to the config page, dereference to get the ffi_closure*
#endif
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] @ load cif
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] @ load fun
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] @ load user_data
0:
add ip, sp, #16
sub sp, sp, #64+32 @ allocate frame
cfi_adjust_cfa_offset(64+32)
#ifdef __clang__
vstm sp, {d0-d7}
#else
stc p11, cr0, [sp], {16} @ vstm sp, {d0-d7}
#endif
stmdb sp!, {ip,lr}
/* See above. */
UNWIND(.save {sp,lr})
cfi_adjust_cfa_offset(8)
cfi_rel_offset(lr, 4)
add r3, sp, #8 @ load frame
bl CNAME(ffi_closure_inner_VFP)
@ Load values returned in registers.
add r2, sp, #8+64 @ load result
adr r3, CNAME(ffi_closure_ret)
add pc, r3, r0, lsl #3
cfi_endproc
UNWIND(.fnend)
ARM_FUNC_END(ffi_closure_VFP)
/* Load values returned in registers for both closure entry points.
Note that we use LDM with SP in the register set. This is deprecated
by ARM, but not yet unpredictable. */
ARM_FUNC_START_LOCAL(ffi_closure_ret)
cfi_startproc
cfi_rel_offset(sp, 0)
cfi_rel_offset(lr, 4)
0:
E(ARM_TYPE_VFP_S)
#ifdef __clang__
vldr s0, [r2]
#else
ldc p10, cr0, [r2] @ vldr s0, [r2]
#endif
ldm sp, {sp,pc}
E(ARM_TYPE_VFP_D)
#ifdef __clang__
vldr d0, [r2]
#else
ldc p11, cr0, [r2] @ vldr d0, [r2]
#endif
ldm sp, {sp,pc}
E(ARM_TYPE_VFP_N)
#ifdef __clang__
vldm r2, {d0-d3}
#else
ldc p11, cr0, [r2], {8} @ vldm r2, {d0-d3}
#endif
ldm sp, {sp,pc}
E(ARM_TYPE_INT64)
ldr r1, [r2, #4]
nop
E(ARM_TYPE_INT)
ldr r0, [r2]
ldm sp, {sp,pc}
E(ARM_TYPE_VOID)
ldm sp, {sp,pc}
nop
E(ARM_TYPE_STRUCT)
ldm sp, {sp,pc}
cfi_endproc
ARM_FUNC_END(ffi_closure_ret)
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#include <mach/machine/vm_param.h>
.align PAGE_MAX_SHIFT
ARM_FUNC_START(ffi_closure_trampoline_table_page)
.rept PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE
adr ip, #-PAGE_MAX_SIZE @ the config page is PAGE_MAX_SIZE behind the trampoline page
sub ip, #8 @ account for pc bias
ldr pc, [ip, #4] @ jump to ffi_closure_SYSV or ffi_closure_VFP
.endr
ARM_FUNC_END(ffi_closure_trampoline_table_page)
#endif
#else
ARM_FUNC_START(ffi_arm_trampoline)
0: adr ip, 0b
ldr pc, 1f
1: .long 0
ARM_FUNC_END(ffi_arm_trampoline)
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
#if defined __ELF__ && defined __linux__
.section .note.GNU-stack,"",%progbits
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/closures.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
closures.c - Copyright (c) 2007, 2009, 2010 Red Hat, Inc.
Copyright (C) 2007, 2009, 2010 Free Software Foundation, Inc
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
Code to allocate and deallocate memory for closures.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#if defined __linux__ && !defined _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <fficonfig.h>
#include <ffi.h>
#include <ffi_common.h>
#ifdef __NetBSD__
#include <sys/param.h>
#endif
#if __NetBSD_Version__ - 0 >= 799007200
/* NetBSD with PROT_MPROTECT */
#include <sys/mman.h>
#include <stddef.h>
#include <unistd.h>
static
const
size_t
overhead
=
(
sizeof
(
max_align_t
)
>
sizeof
(
void
*
)
+
sizeof
(
size_t
))
?
sizeof
(
max_align_t
)
:
sizeof
(
void
*
)
+
sizeof
(
size_t
);
#define ADD_TO_POINTER(p, d) ((void *)((uintptr_t)(p) + (d)))
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
)
{
static
size_t
page_size
;
size_t
rounded_size
;
void
*
codeseg
,
*
dataseg
;
int
prot
;
/* Expect that PAX mprotect is active and a separate code mapping is necessary. */
if
(
!
code
)
return
NULL
;
/* Obtain system page size. */
if
(
!
page_size
)
page_size
=
sysconf
(
_SC_PAGESIZE
);
/* Round allocation size up to the next page, keeping in mind the size field and pointer to code map. */
rounded_size
=
(
size
+
overhead
+
page_size
-
1
)
&
~
(
page_size
-
1
);
/* Primary mapping is RW, but request permission to switch to PROT_EXEC later. */
prot
=
PROT_READ
|
PROT_WRITE
|
PROT_MPROTECT
(
PROT_EXEC
);
dataseg
=
mmap
(
NULL
,
rounded_size
,
prot
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
if
(
dataseg
==
MAP_FAILED
)
return
NULL
;
/* Create secondary mapping and switch it to RX. */
codeseg
=
mremap
(
dataseg
,
rounded_size
,
NULL
,
rounded_size
,
MAP_REMAPDUP
);
if
(
codeseg
==
MAP_FAILED
)
{
munmap
(
dataseg
,
rounded_size
);
return
NULL
;
}
if
(
mprotect
(
codeseg
,
rounded_size
,
PROT_READ
|
PROT_EXEC
)
==
-
1
)
{
munmap
(
codeseg
,
rounded_size
);
munmap
(
dataseg
,
rounded_size
);
return
NULL
;
}
/* Remember allocation size and location of the secondary mapping for ffi_closure_free. */
memcpy
(
dataseg
,
&
rounded_size
,
sizeof
(
rounded_size
));
memcpy
(
ADD_TO_POINTER
(
dataseg
,
sizeof
(
size_t
)),
&
codeseg
,
sizeof
(
void
*
));
*
code
=
ADD_TO_POINTER
(
codeseg
,
overhead
);
return
ADD_TO_POINTER
(
dataseg
,
overhead
);
}
void
ffi_closure_free
(
void
*
ptr
)
{
void
*
codeseg
,
*
dataseg
;
size_t
rounded_size
;
dataseg
=
ADD_TO_POINTER
(
ptr
,
-
overhead
);
memcpy
(
&
rounded_size
,
dataseg
,
sizeof
(
rounded_size
));
memcpy
(
&
codeseg
,
ADD_TO_POINTER
(
dataseg
,
sizeof
(
size_t
)),
sizeof
(
void
*
));
munmap
(
dataseg
,
rounded_size
);
munmap
(
codeseg
,
rounded_size
);
}
#else
/* !NetBSD with PROT_MPROTECT */
#if !FFI_MMAP_EXEC_WRIT && !FFI_EXEC_TRAMPOLINE_TABLE
# if __linux__ && !defined(__ANDROID__)
/* This macro indicates it may be forbidden to map anonymous memory
with both write and execute permission. Code compiled when this
option is defined will attempt to map such pages once, but if it
fails, it falls back to creating a temporary file in a writable and
executable filesystem and mapping pages from it into separate
locations in the virtual memory space, one location writable and
another executable. */
# define FFI_MMAP_EXEC_WRIT 1
# define HAVE_MNTENT 1
# endif
# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
/* Windows systems may have Data Execution Protection (DEP) enabled,
which requires the use of VirtualMalloc/VirtualFree to alloc/free
executable memory. */
# define FFI_MMAP_EXEC_WRIT 1
# endif
#endif
#if FFI_MMAP_EXEC_WRIT && !defined FFI_MMAP_EXEC_SELINUX
# if defined(__linux__) && !defined(__ANDROID__)
/* When defined to 1 check for SELinux and if SELinux is active,
don't attempt PROT_EXEC|PROT_WRITE mapping at all, as that
might cause audit messages. */
# define FFI_MMAP_EXEC_SELINUX 1
# endif
#endif
#if FFI_CLOSURES
#if FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#include <mach/mach.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
extern
void
*
ffi_closure_trampoline_table_page
;
typedef
struct
ffi_trampoline_table
ffi_trampoline_table
;
typedef
struct
ffi_trampoline_table_entry
ffi_trampoline_table_entry
;
struct
ffi_trampoline_table
{
/* contiguous writable and executable pages */
vm_address_t
config_page
;
vm_address_t
trampoline_page
;
/* free list tracking */
uint16_t
free_count
;
ffi_trampoline_table_entry
*
free_list
;
ffi_trampoline_table_entry
*
free_list_pool
;
ffi_trampoline_table
*
prev
;
ffi_trampoline_table
*
next
;
};
struct
ffi_trampoline_table_entry
{
void
*
(
*
trampoline
)
();
ffi_trampoline_table_entry
*
next
;
};
/* Total number of trampolines that fit in one trampoline table */
#define FFI_TRAMPOLINE_COUNT (PAGE_MAX_SIZE / FFI_TRAMPOLINE_SIZE)
static
pthread_mutex_t
ffi_trampoline_lock
=
PTHREAD_MUTEX_INITIALIZER
;
static
ffi_trampoline_table
*
ffi_trampoline_tables
=
NULL
;
static
ffi_trampoline_table
*
ffi_trampoline_table_alloc
(
void
)
{
ffi_trampoline_table
*
table
;
vm_address_t
config_page
;
vm_address_t
trampoline_page
;
vm_address_t
trampoline_page_template
;
vm_prot_t
cur_prot
;
vm_prot_t
max_prot
;
kern_return_t
kt
;
uint16_t
i
;
/* Allocate two pages -- a config page and a placeholder page */
config_page
=
0x0
;
kt
=
vm_allocate
(
mach_task_self
(),
&
config_page
,
PAGE_MAX_SIZE
*
2
,
VM_FLAGS_ANYWHERE
);
if
(
kt
!=
KERN_SUCCESS
)
return
NULL
;
/* Remap the trampoline table on top of the placeholder page */
trampoline_page
=
config_page
+
PAGE_MAX_SIZE
;
trampoline_page_template
=
(
vm_address_t
)
&
ffi_closure_trampoline_table_page
;
#ifdef __arm__
/* ffi_closure_trampoline_table_page can be thumb-biased on some ARM archs */
trampoline_page_template
&=
~
1UL
;
#endif
kt
=
vm_remap
(
mach_task_self
(),
&
trampoline_page
,
PAGE_MAX_SIZE
,
0x0
,
VM_FLAGS_OVERWRITE
,
mach_task_self
(),
trampoline_page_template
,
FALSE
,
&
cur_prot
,
&
max_prot
,
VM_INHERIT_SHARE
);
if
(
kt
!=
KERN_SUCCESS
)
{
vm_deallocate
(
mach_task_self
(),
config_page
,
PAGE_MAX_SIZE
*
2
);
return
NULL
;
}
/* We have valid trampoline and config pages */
table
=
calloc
(
1
,
sizeof
(
ffi_trampoline_table
));
table
->
free_count
=
FFI_TRAMPOLINE_COUNT
;
table
->
config_page
=
config_page
;
table
->
trampoline_page
=
trampoline_page
;
/* Create and initialize the free list */
table
->
free_list_pool
=
calloc
(
FFI_TRAMPOLINE_COUNT
,
sizeof
(
ffi_trampoline_table_entry
));
for
(
i
=
0
;
i
<
table
->
free_count
;
i
++
)
{
ffi_trampoline_table_entry
*
entry
=
&
table
->
free_list_pool
[
i
];
entry
->
trampoline
=
(
void
*
)
(
table
->
trampoline_page
+
(
i
*
FFI_TRAMPOLINE_SIZE
));
if
(
i
<
table
->
free_count
-
1
)
entry
->
next
=
&
table
->
free_list_pool
[
i
+
1
];
}
table
->
free_list
=
table
->
free_list_pool
;
return
table
;
}
static
void
ffi_trampoline_table_free
(
ffi_trampoline_table
*
table
)
{
/* Remove from the list */
if
(
table
->
prev
!=
NULL
)
table
->
prev
->
next
=
table
->
next
;
if
(
table
->
next
!=
NULL
)
table
->
next
->
prev
=
table
->
prev
;
/* Deallocate pages */
vm_deallocate
(
mach_task_self
(),
table
->
config_page
,
PAGE_MAX_SIZE
*
2
);
/* Deallocate free list */
free
(
table
->
free_list_pool
);
free
(
table
);
}
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
)
{
/* Create the closure */
ffi_closure
*
closure
=
malloc
(
size
);
if
(
closure
==
NULL
)
return
NULL
;
pthread_mutex_lock
(
&
ffi_trampoline_lock
);
/* Check for an active trampoline table with available entries. */
ffi_trampoline_table
*
table
=
ffi_trampoline_tables
;
if
(
table
==
NULL
||
table
->
free_list
==
NULL
)
{
table
=
ffi_trampoline_table_alloc
();
if
(
table
==
NULL
)
{
pthread_mutex_unlock
(
&
ffi_trampoline_lock
);
free
(
closure
);
return
NULL
;
}
/* Insert the new table at the top of the list */
table
->
next
=
ffi_trampoline_tables
;
if
(
table
->
next
!=
NULL
)
table
->
next
->
prev
=
table
;
ffi_trampoline_tables
=
table
;
}
/* Claim the free entry */
ffi_trampoline_table_entry
*
entry
=
ffi_trampoline_tables
->
free_list
;
ffi_trampoline_tables
->
free_list
=
entry
->
next
;
ffi_trampoline_tables
->
free_count
--
;
entry
->
next
=
NULL
;
pthread_mutex_unlock
(
&
ffi_trampoline_lock
);
/* Initialize the return values */
*
code
=
entry
->
trampoline
;
closure
->
trampoline_table
=
table
;
closure
->
trampoline_table_entry
=
entry
;
return
closure
;
}
void
ffi_closure_free
(
void
*
ptr
)
{
ffi_closure
*
closure
=
ptr
;
pthread_mutex_lock
(
&
ffi_trampoline_lock
);
/* Fetch the table and entry references */
ffi_trampoline_table
*
table
=
closure
->
trampoline_table
;
ffi_trampoline_table_entry
*
entry
=
closure
->
trampoline_table_entry
;
/* Return the entry to the free list */
entry
->
next
=
table
->
free_list
;
table
->
free_list
=
entry
;
table
->
free_count
++
;
/* If all trampolines within this table are free, and at least one other table exists, deallocate
* the table */
if
(
table
->
free_count
==
FFI_TRAMPOLINE_COUNT
&&
ffi_trampoline_tables
!=
table
)
{
ffi_trampoline_table_free
(
table
);
}
else
if
(
ffi_trampoline_tables
!=
table
)
{
/* Otherwise, bump this table to the top of the list */
table
->
prev
=
NULL
;
table
->
next
=
ffi_trampoline_tables
;
if
(
ffi_trampoline_tables
!=
NULL
)
ffi_trampoline_tables
->
prev
=
table
;
ffi_trampoline_tables
=
table
;
}
pthread_mutex_unlock
(
&
ffi_trampoline_lock
);
/* Free the closure */
free
(
closure
);
}
#endif
// Per-target implementation; It's unclear what can reasonable be shared between two OS/architecture implementations.
#elif FFI_MMAP_EXEC_WRIT
/* !FFI_EXEC_TRAMPOLINE_TABLE */
#define USE_LOCKS 1
#define USE_DL_PREFIX 1
#ifdef __GNUC__
#ifndef USE_BUILTIN_FFS
#define USE_BUILTIN_FFS 1
#endif
#endif
/* We need to use mmap, not sbrk. */
#define HAVE_MORECORE 0
/* We could, in theory, support mremap, but it wouldn't buy us anything. */
#define HAVE_MREMAP 0
/* We have no use for this, so save some code and data. */
#define NO_MALLINFO 1
/* We need all allocations to be in regular segments, otherwise we
lose track of the corresponding code address. */
#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
/* Don't allocate more than a page unless needed. */
#define DEFAULT_GRANULARITY ((size_t)malloc_getpagesize)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#if !defined(X86_WIN32) && !defined(X86_WIN64)
#ifdef HAVE_MNTENT
#include <mntent.h>
#endif
/* HAVE_MNTENT */
#include <sys/param.h>
#include <pthread.h>
/* We don't want sys/mman.h to be included after we redefine mmap and
dlmunmap. */
#include <sys/mman.h>
#define LACKS_SYS_MMAN_H 1
#if FFI_MMAP_EXEC_SELINUX
#include <sys/statfs.h>
#include <stdlib.h>
static
int
selinux_enabled
=
-
1
;
static
int
selinux_enabled_check
(
void
)
{
struct
statfs
sfs
;
FILE
*
f
;
char
*
buf
=
NULL
;
size_t
len
=
0
;
if
(
statfs
(
"/selinux"
,
&
sfs
)
>=
0
&&
(
unsigned
int
)
sfs
.
f_type
==
0xf97cff8cU
)
return
1
;
f
=
fopen
(
"/proc/mounts"
,
"r"
);
if
(
f
==
NULL
)
return
0
;
while
(
getline
(
&
buf
,
&
len
,
f
)
>=
0
)
{
char
*
p
=
strchr
(
buf
,
' '
);
if
(
p
==
NULL
)
break
;
p
=
strchr
(
p
+
1
,
' '
);
if
(
p
==
NULL
)
break
;
if
(
strncmp
(
p
+
1
,
"selinuxfs "
,
10
)
==
0
)
{
free
(
buf
);
fclose
(
f
);
return
1
;
}
}
free
(
buf
);
fclose
(
f
);
return
0
;
}
#define is_selinux_enabled() (selinux_enabled >= 0 ? selinux_enabled \
: (selinux_enabled = selinux_enabled_check ()))
#else
#define is_selinux_enabled() 0
#endif
/* !FFI_MMAP_EXEC_SELINUX */
/* On PaX enable kernels that have MPROTECT enable we can't use PROT_EXEC. */
#ifdef FFI_MMAP_EXEC_EMUTRAMP_PAX
#include <stdlib.h>
static
int
emutramp_enabled
=
-
1
;
static
int
emutramp_enabled_check
(
void
)
{
char
*
buf
=
NULL
;
size_t
len
=
0
;
FILE
*
f
;
int
ret
;
f
=
fopen
(
"/proc/self/status"
,
"r"
);
if
(
f
==
NULL
)
return
0
;
ret
=
0
;
while
(
getline
(
&
buf
,
&
len
,
f
)
!=
-
1
)
if
(
!
strncmp
(
buf
,
"PaX:"
,
4
))
{
char
emutramp
;
if
(
sscanf
(
buf
,
"%*s %*c%c"
,
&
emutramp
)
==
1
)
ret
=
(
emutramp
==
'E'
);
break
;
}
free
(
buf
);
fclose
(
f
);
return
ret
;
}
#define is_emutramp_enabled() (emutramp_enabled >= 0 ? emutramp_enabled \
: (emutramp_enabled = emutramp_enabled_check ()))
#endif
/* FFI_MMAP_EXEC_EMUTRAMP_PAX */
#elif defined (__CYGWIN__) || defined(__INTERIX)
#include <sys/mman.h>
/* Cygwin is Linux-like, but not quite that Linux-like. */
#define is_selinux_enabled() 0
#endif
/* !defined(X86_WIN32) && !defined(X86_WIN64) */
#ifndef FFI_MMAP_EXEC_EMUTRAMP_PAX
#define is_emutramp_enabled() 0
#endif
/* FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Declare all functions defined in dlmalloc.c as static. */
static
void
*
dlmalloc
(
size_t
);
static
void
dlfree
(
void
*
);
static
void
*
dlcalloc
(
size_t
,
size_t
)
MAYBE_UNUSED
;
static
void
*
dlrealloc
(
void
*
,
size_t
)
MAYBE_UNUSED
;
static
void
*
dlmemalign
(
size_t
,
size_t
)
MAYBE_UNUSED
;
static
void
*
dlvalloc
(
size_t
)
MAYBE_UNUSED
;
static
int
dlmallopt
(
int
,
int
)
MAYBE_UNUSED
;
static
size_t
dlmalloc_footprint
(
void
)
MAYBE_UNUSED
;
static
size_t
dlmalloc_max_footprint
(
void
)
MAYBE_UNUSED
;
static
void
**
dlindependent_calloc
(
size_t
,
size_t
,
void
**
)
MAYBE_UNUSED
;
static
void
**
dlindependent_comalloc
(
size_t
,
size_t
*
,
void
**
)
MAYBE_UNUSED
;
static
void
*
dlpvalloc
(
size_t
)
MAYBE_UNUSED
;
static
int
dlmalloc_trim
(
size_t
)
MAYBE_UNUSED
;
static
size_t
dlmalloc_usable_size
(
void
*
)
MAYBE_UNUSED
;
static
void
dlmalloc_stats
(
void
)
MAYBE_UNUSED
;
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* Use these for mmap and munmap within dlmalloc.c. */
static
void
*
dlmmap
(
void
*
,
size_t
,
int
,
int
,
int
,
off_t
);
static
int
dlmunmap
(
void
*
,
size_t
);
#endif
/* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
#define mmap dlmmap
#define munmap dlmunmap
#include "dlmalloc.c"
#undef mmap
#undef munmap
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
/* A mutex used to synchronize access to *exec* variables in this file. */
static
pthread_mutex_t
open_temp_exec_file_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
/* A file descriptor of a temporary file from which we'll map
executable pages. */
static
int
execfd
=
-
1
;
/* The amount of space already allocated from the temporary file. */
static
size_t
execsize
=
0
;
/* Open a temporary file name, and immediately unlink it. */
static
int
open_temp_exec_file_name
(
char
*
name
,
int
flags
)
{
int
fd
;
#ifdef HAVE_MKOSTEMP
fd
=
mkostemp
(
name
,
flags
);
#else
fd
=
mkstemp
(
name
);
#endif
if
(
fd
!=
-
1
)
unlink
(
name
);
return
fd
;
}
/* Open a temporary file in the named directory. */
static
int
open_temp_exec_file_dir
(
const
char
*
dir
)
{
static
const
char
suffix
[]
=
"/ffiXXXXXX"
;
int
lendir
,
flags
;
char
*
tempname
;
#ifdef O_TMPFILE
int
fd
;
#endif
#ifdef O_CLOEXEC
flags
=
O_CLOEXEC
;
#else
flags
=
0
;
#endif
#ifdef O_TMPFILE
fd
=
open
(
dir
,
flags
|
O_RDWR
|
O_EXCL
|
O_TMPFILE
,
0700
);
/* If the running system does not support the O_TMPFILE flag then retry without it. */
if
(
fd
!=
-
1
||
(
errno
!=
EINVAL
&&
errno
!=
EISDIR
&&
errno
!=
EOPNOTSUPP
))
{
return
fd
;
}
else
{
errno
=
0
;
}
#endif
lendir
=
(
int
)
strlen
(
dir
);
tempname
=
__builtin_alloca
(
lendir
+
sizeof
(
suffix
));
if
(
!
tempname
)
return
-
1
;
memcpy
(
tempname
,
dir
,
lendir
);
memcpy
(
tempname
+
lendir
,
suffix
,
sizeof
(
suffix
));
return
open_temp_exec_file_name
(
tempname
,
flags
);
}
/* Open a temporary file in the directory in the named environment
variable. */
static
int
open_temp_exec_file_env
(
const
char
*
envvar
)
{
const
char
*
value
=
getenv
(
envvar
);
if
(
!
value
)
return
-
1
;
return
open_temp_exec_file_dir
(
value
);
}
#ifdef HAVE_MNTENT
/* Open a temporary file in an executable and writable mount point
listed in the mounts file. Subsequent calls with the same mounts
keep searching for mount points in the same file. Providing NULL
as the mounts file closes the file. */
static
int
open_temp_exec_file_mnt
(
const
char
*
mounts
)
{
static
const
char
*
last_mounts
;
static
FILE
*
last_mntent
;
if
(
mounts
!=
last_mounts
)
{
if
(
last_mntent
)
endmntent
(
last_mntent
);
last_mounts
=
mounts
;
if
(
mounts
)
last_mntent
=
setmntent
(
mounts
,
"r"
);
else
last_mntent
=
NULL
;
}
if
(
!
last_mntent
)
return
-
1
;
for
(;;)
{
int
fd
;
struct
mntent
mnt
;
char
buf
[
MAXPATHLEN
*
3
];
if
(
getmntent_r
(
last_mntent
,
&
mnt
,
buf
,
sizeof
(
buf
))
==
NULL
)
return
-
1
;
if
(
hasmntopt
(
&
mnt
,
"ro"
)
||
hasmntopt
(
&
mnt
,
"noexec"
)
||
access
(
mnt
.
mnt_dir
,
W_OK
))
continue
;
fd
=
open_temp_exec_file_dir
(
mnt
.
mnt_dir
);
if
(
fd
!=
-
1
)
return
fd
;
}
}
#endif
/* HAVE_MNTENT */
/* Instructions to look for a location to hold a temporary file that
can be mapped in for execution. */
static
struct
{
int
(
*
func
)(
const
char
*
);
const
char
*
arg
;
int
repeat
;
}
open_temp_exec_file_opts
[]
=
{
{
open_temp_exec_file_env
,
"TMPDIR"
,
0
},
{
open_temp_exec_file_dir
,
"/tmp"
,
0
},
{
open_temp_exec_file_dir
,
"/var/tmp"
,
0
},
{
open_temp_exec_file_dir
,
"/dev/shm"
,
0
},
{
open_temp_exec_file_env
,
"HOME"
,
0
},
#ifdef HAVE_MNTENT
{
open_temp_exec_file_mnt
,
"/etc/mtab"
,
1
},
{
open_temp_exec_file_mnt
,
"/proc/mounts"
,
1
},
#endif
/* HAVE_MNTENT */
};
/* Current index into open_temp_exec_file_opts. */
static
int
open_temp_exec_file_opts_idx
=
0
;
/* Reset a current multi-call func, then advances to the next entry.
If we're at the last, go back to the first and return nonzero,
otherwise return zero. */
static
int
open_temp_exec_file_opts_next
(
void
)
{
if
(
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
repeat
)
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
func
(
NULL
);
open_temp_exec_file_opts_idx
++
;
if
(
open_temp_exec_file_opts_idx
==
(
sizeof
(
open_temp_exec_file_opts
)
/
sizeof
(
*
open_temp_exec_file_opts
)))
{
open_temp_exec_file_opts_idx
=
0
;
return
1
;
}
return
0
;
}
/* Return a file descriptor of a temporary zero-sized file in a
writable and executable filesystem. */
static
int
open_temp_exec_file
(
void
)
{
int
fd
;
do
{
fd
=
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
func
(
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
arg
);
if
(
!
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
repeat
||
fd
==
-
1
)
{
if
(
open_temp_exec_file_opts_next
())
break
;
}
}
while
(
fd
==
-
1
);
return
fd
;
}
/* We need to allocate space in a file that will be backing a writable
mapping. Several problems exist with the usual approaches:
- fallocate() is Linux-only
- posix_fallocate() is not available on all platforms
- ftruncate() does not allocate space on filesystems with sparse files
Failure to allocate the space will cause SIGBUS to be thrown when
the mapping is subsequently written to. */
static
int
allocate_space
(
int
fd
,
off_t
offset
,
off_t
len
)
{
static
size_t
page_size
;
/* Obtain system page size. */
if
(
!
page_size
)
page_size
=
sysconf
(
_SC_PAGESIZE
);
unsigned
char
buf
[
page_size
];
memset
(
buf
,
0
,
page_size
);
while
(
len
>
0
)
{
off_t
to_write
=
(
len
<
page_size
)
?
len
:
page_size
;
if
(
write
(
fd
,
buf
,
to_write
)
<
to_write
)
return
-
1
;
len
-=
to_write
;
}
return
0
;
}
/* Map in a chunk of memory from the temporary exec file into separate
locations in the virtual memory address space, one writable and one
executable. Returns the address of the writable portion, after
storing an offset to the corresponding executable portion at the
last word of the requested chunk. */
static
void
*
dlmmap_locked
(
void
*
start
,
size_t
length
,
int
prot
,
int
flags
,
off_t
offset
)
{
void
*
ptr
;
if
(
execfd
==
-
1
)
{
open_temp_exec_file_opts_idx
=
0
;
retry_open:
execfd
=
open_temp_exec_file
();
if
(
execfd
==
-
1
)
return
MFAIL
;
}
offset
=
execsize
;
if
(
allocate_space
(
execfd
,
offset
,
length
))
return
MFAIL
;
flags
&=
~
(
MAP_PRIVATE
|
MAP_ANONYMOUS
);
flags
|=
MAP_SHARED
;
ptr
=
mmap
(
NULL
,
length
,
(
prot
&
~
PROT_WRITE
)
|
PROT_EXEC
,
flags
,
execfd
,
offset
);
if
(
ptr
==
MFAIL
)
{
if
(
!
offset
)
{
close
(
execfd
);
goto
retry_open
;
}
ftruncate
(
execfd
,
offset
);
return
MFAIL
;
}
else
if
(
!
offset
&&
open_temp_exec_file_opts
[
open_temp_exec_file_opts_idx
].
repeat
)
open_temp_exec_file_opts_next
();
start
=
mmap
(
start
,
length
,
prot
,
flags
,
execfd
,
offset
);
if
(
start
==
MFAIL
)
{
munmap
(
ptr
,
length
);
ftruncate
(
execfd
,
offset
);
return
start
;
}
mmap_exec_offset
((
char
*
)
start
,
length
)
=
(
char
*
)
ptr
-
(
char
*
)
start
;
execsize
+=
length
;
return
start
;
}
/* Map in a writable and executable chunk of memory if possible.
Failing that, fall back to dlmmap_locked. */
static
void
*
dlmmap
(
void
*
start
,
size_t
length
,
int
prot
,
int
flags
,
int
fd
,
off_t
offset
)
{
void
*
ptr
;
assert
(
start
==
NULL
&&
length
%
malloc_getpagesize
==
0
&&
prot
==
(
PROT_READ
|
PROT_WRITE
)
&&
flags
==
(
MAP_PRIVATE
|
MAP_ANONYMOUS
)
&&
fd
==
-
1
&&
offset
==
0
);
if
(
execfd
==
-
1
&&
is_emutramp_enabled
())
{
ptr
=
mmap
(
start
,
length
,
prot
&
~
PROT_EXEC
,
flags
,
fd
,
offset
);
return
ptr
;
}
if
(
execfd
==
-
1
&&
!
is_selinux_enabled
())
{
ptr
=
mmap
(
start
,
length
,
prot
|
PROT_EXEC
,
flags
,
fd
,
offset
);
if
(
ptr
!=
MFAIL
||
(
errno
!=
EPERM
&&
errno
!=
EACCES
))
/* Cool, no need to mess with separate segments. */
return
ptr
;
/* If MREMAP_DUP is ever introduced and implemented, try mmap
with ((prot & ~PROT_WRITE) | PROT_EXEC) and mremap with
MREMAP_DUP and prot at this point. */
}
if
(
execsize
==
0
||
execfd
==
-
1
)
{
pthread_mutex_lock
(
&
open_temp_exec_file_mutex
);
ptr
=
dlmmap_locked
(
start
,
length
,
prot
,
flags
,
offset
);
pthread_mutex_unlock
(
&
open_temp_exec_file_mutex
);
return
ptr
;
}
return
dlmmap_locked
(
start
,
length
,
prot
,
flags
,
offset
);
}
/* Release memory at the given address, as well as the corresponding
executable page if it's separate. */
static
int
dlmunmap
(
void
*
start
,
size_t
length
)
{
/* We don't bother decreasing execsize or truncating the file, since
we can't quite tell whether we're unmapping the end of the file.
We don't expect frequent deallocation anyway. If we did, we
could locate pages in the file by writing to the pages being
deallocated and checking that the file contents change.
Yuck. */
msegmentptr
seg
=
segment_holding
(
gm
,
start
);
void
*
code
;
if
(
seg
&&
(
code
=
add_segment_exec_offset
(
start
,
seg
))
!=
start
)
{
int
ret
=
munmap
(
code
,
length
);
if
(
ret
)
return
ret
;
}
return
munmap
(
start
,
length
);
}
#if FFI_CLOSURE_FREE_CODE
/* Return segment holding given code address. */
static
msegmentptr
segment_holding_code
(
mstate
m
,
char
*
addr
)
{
msegmentptr
sp
=
&
m
->
seg
;
for
(;;)
{
if
(
addr
>=
add_segment_exec_offset
(
sp
->
base
,
sp
)
&&
addr
<
add_segment_exec_offset
(
sp
->
base
,
sp
)
+
sp
->
size
)
return
sp
;
if
((
sp
=
sp
->
next
)
==
0
)
return
0
;
}
}
#endif
#endif
/* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
/* Allocate a chunk of memory with the given size. Returns a pointer
to the writable address, and sets *CODE to the executable
corresponding virtual address. */
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
)
{
void
*
ptr
;
if
(
!
code
)
return
NULL
;
ptr
=
dlmalloc
(
size
);
if
(
ptr
)
{
msegmentptr
seg
=
segment_holding
(
gm
,
ptr
);
*
code
=
add_segment_exec_offset
(
ptr
,
seg
);
}
return
ptr
;
}
/* Release a chunk of memory allocated with ffi_closure_alloc. If
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
writable or the executable address given. Otherwise, only the
writable address can be provided here. */
void
ffi_closure_free
(
void
*
ptr
)
{
#if FFI_CLOSURE_FREE_CODE
msegmentptr
seg
=
segment_holding_code
(
gm
,
ptr
);
if
(
seg
)
ptr
=
sub_segment_exec_offset
(
ptr
,
seg
);
#endif
dlfree
(
ptr
);
}
# else
/* ! FFI_MMAP_EXEC_WRIT */
/* On many systems, memory returned by malloc is writable and
executable, so just use it. */
#include <stdlib.h>
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
)
{
if
(
!
code
)
return
NULL
;
return
*
code
=
malloc
(
size
);
}
void
ffi_closure_free
(
void
*
ptr
)
{
free
(
ptr
);
}
# endif
/* ! FFI_MMAP_EXEC_WRIT */
#endif
/* FFI_CLOSURES */
#endif
/* NetBSD with PROT_MPROTECT */
nativehook/src/main/cpp/libffi/debug.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
debug.c - Copyright (c) 1996 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#include <stdio.h>
/* General debugging routines */
void
ffi_stop_here
(
void
)
{
/* This function is only useful for debugging purposes.
Place a breakpoint on ffi_stop_here to be notified of
significant events. */
}
/* This function should only be called via the FFI_ASSERT() macro */
void
ffi_assert
(
char
*
expr
,
char
*
file
,
int
line
)
{
fprintf
(
stderr
,
"ASSERTION FAILURE: %s at %s:%d
\n
"
,
expr
,
file
,
line
);
ffi_stop_here
();
abort
();
}
/* Perform a sanity check on an ffi_type structure */
void
ffi_type_test
(
ffi_type
*
a
,
char
*
file
,
int
line
)
{
FFI_ASSERT_AT
(
a
!=
NULL
,
file
,
line
);
FFI_ASSERT_AT
(
a
->
type
<=
FFI_TYPE_LAST
,
file
,
line
);
FFI_ASSERT_AT
(
a
->
type
==
FFI_TYPE_VOID
||
a
->
size
>
0
,
file
,
line
);
FFI_ASSERT_AT
(
a
->
type
==
FFI_TYPE_VOID
||
a
->
alignment
>
0
,
file
,
line
);
FFI_ASSERT_AT
((
a
->
type
!=
FFI_TYPE_STRUCT
&&
a
->
type
!=
FFI_TYPE_COMPLEX
)
||
a
->
elements
!=
NULL
,
file
,
line
);
FFI_ASSERT_AT
(
a
->
type
!=
FFI_TYPE_COMPLEX
||
(
a
->
elements
!=
NULL
&&
a
->
elements
[
0
]
!=
NULL
&&
a
->
elements
[
1
]
==
NULL
),
file
,
line
);
}
nativehook/src/main/cpp/libffi/dlmalloc.c
0 → 100755
View file @
10c7897b
This source diff could not be displayed because it is too large. You can
view the blob
instead.
nativehook/src/main/cpp/libffi/ffi.h
0 → 100755
View file @
10c7897b
#ifdef __aarch64__
#include <ffi_arm64.h>
#endif
#ifdef __i386__
#include <ffi_i386.h>
#endif
#ifdef __arm__
#include <ffi_armv7.h>
#endif
#ifdef __x86_64__
#include <ffi_x86_64.h>
#endif
nativehook/src/main/cpp/libffi/ffi_cfi.h
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
ffi_cfi.h - Copyright (c) 2014 Red Hat, Inc.
Conditionally assemble cfi directives. Only necessary for building libffi.
----------------------------------------------------------------------- */
#ifndef FFI_CFI_H
#define FFI_CFI_H
#ifdef HAVE_AS_CFI_PSEUDO_OP
# define cfi_startproc .cfi_startproc
# define cfi_endproc .cfi_endproc
# define cfi_def_cfa(reg, off) .cfi_def_cfa reg, off
# define cfi_def_cfa_register(reg) .cfi_def_cfa_register reg
# define cfi_def_cfa_offset(off) .cfi_def_cfa_offset off
# define cfi_adjust_cfa_offset(off) .cfi_adjust_cfa_offset off
# define cfi_offset(reg, off) .cfi_offset reg, off
# define cfi_rel_offset(reg, off) .cfi_rel_offset reg, off
# define cfi_register(r1, r2) .cfi_register r1, r2
# define cfi_return_column(reg) .cfi_return_column reg
# define cfi_restore(reg) .cfi_restore reg
# define cfi_same_value(reg) .cfi_same_value reg
# define cfi_undefined(reg) .cfi_undefined reg
# define cfi_remember_state .cfi_remember_state
# define cfi_restore_state .cfi_restore_state
# define cfi_window_save .cfi_window_save
# define cfi_personality(enc, exp) .cfi_personality enc, exp
# define cfi_lsda(enc, exp) .cfi_lsda enc, exp
# define cfi_escape(...) .cfi_escape __VA_ARGS__
#else
# define cfi_startproc
# define cfi_endproc
# define cfi_def_cfa(reg, off)
# define cfi_def_cfa_register(reg)
# define cfi_def_cfa_offset(off)
# define cfi_adjust_cfa_offset(off)
# define cfi_offset(reg, off)
# define cfi_rel_offset(reg, off)
# define cfi_register(r1, r2)
# define cfi_return_column(reg)
# define cfi_restore(reg)
# define cfi_same_value(reg)
# define cfi_undefined(reg)
# define cfi_remember_state
# define cfi_restore_state
# define cfi_window_save
# define cfi_personality(enc, exp)
# define cfi_lsda(enc, exp)
# define cfi_escape(...)
#endif
/* HAVE_AS_CFI_PSEUDO_OP */
#endif
/* FFI_CFI_H */
nativehook/src/main/cpp/libffi/ffi_common.h
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
ffi_common.h - Copyright (C) 2011, 2012, 2013 Anthony Green
Copyright (C) 2007 Free Software Foundation, Inc
Copyright (c) 1996 Red Hat, Inc.
Common internal definitions and macros. Only necessary for building
libffi.
----------------------------------------------------------------------- */
#ifndef FFI_COMMON_H
#define FFI_COMMON_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include <fficonfig.h>
/* Do not move this. Some versions of AIX are very picky about where
this is positioned. */
#ifdef __GNUC__
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
/* mingw64 defines this already in malloc.h. */
# ifndef alloca
# define alloca __builtin_alloca
# endif
# endif
# define MAYBE_UNUSED __attribute__((__unused__))
#else
# define MAYBE_UNUSED
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
# pragma alloca
# else
# ifndef alloca
/* predefined by HP cc +Olibcalls */
# ifdef _MSC_VER
# define alloca _alloca
# else
char
*
alloca
();
# endif
# endif
# endif
# endif
#endif
/* Check for the existence of memcpy. */
#if STDC_HEADERS
# include <string.h>
#else
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy ((s), (d), (n))
# endif
#endif
#if defined(FFI_DEBUG)
#include <stdio.h>
#endif
#ifdef FFI_DEBUG
void
ffi_assert
(
char
*
expr
,
char
*
file
,
int
line
);
void
ffi_stop_here
(
void
);
void
ffi_type_test
(
ffi_type
*
a
,
char
*
file
,
int
line
);
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
#define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__)
#else
#define FFI_ASSERT(x)
#define FFI_ASSERT_AT(x, f, l)
#define FFI_ASSERT_VALID_TYPE(x)
#endif
/* v cast to size_t and aligned up to a multiple of a */
#define FFI_ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
/* v cast to size_t and aligned down to a multiple of a */
#define FFI_ALIGN_DOWN(v, a) (((size_t) (v)) & -a)
/* Perform machine dependent cif processing */
ffi_status
ffi_prep_cif_machdep
(
ffi_cif
*
cif
);
ffi_status
ffi_prep_cif_machdep_var
(
ffi_cif
*
cif
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
);
#if HAVE_LONG_DOUBLE_VARIANT
/* Used to adjust size/alignment of ffi types. */
void
ffi_prep_types
(
ffi_abi
abi
);
#endif
/* Used internally, but overridden by some architectures */
ffi_status
ffi_prep_cif_core
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
isvariadic
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
/* Extended cif, used in callback from assembly routine */
typedef
struct
{
ffi_cif
*
cif
;
void
*
rvalue
;
void
**
avalue
;
}
extended_cif
;
/* Terse sized type definitions. */
#if defined(_MSC_VER) || defined(__sgi) || defined(__SUNPRO_C)
typedef
unsigned
char
UINT8
;
typedef
signed
char
SINT8
;
typedef
unsigned
short
UINT16
;
typedef
signed
short
SINT16
;
typedef
unsigned
int
UINT32
;
typedef
signed
int
SINT32
;
# ifdef _MSC_VER
typedef
unsigned
__int64
UINT64
;
typedef
signed
__int64
SINT64
;
# else
# include <inttypes.h>
typedef
uint64_t
UINT64
;
typedef
int64_t
SINT64
;
# endif
#else
typedef
unsigned
int
UINT8
__attribute__
((
__mode__
(
__QI__
)));
typedef
signed
int
SINT8
__attribute__
((
__mode__
(
__QI__
)));
typedef
unsigned
int
UINT16
__attribute__
((
__mode__
(
__HI__
)));
typedef
signed
int
SINT16
__attribute__
((
__mode__
(
__HI__
)));
typedef
unsigned
int
UINT32
__attribute__
((
__mode__
(
__SI__
)));
typedef
signed
int
SINT32
__attribute__
((
__mode__
(
__SI__
)));
typedef
unsigned
int
UINT64
__attribute__
((
__mode__
(
__DI__
)));
typedef
signed
int
SINT64
__attribute__
((
__mode__
(
__DI__
)));
#endif
typedef
float
FLOAT32
;
#ifndef __GNUC__
#define __builtin_expect(x, expected_value) (x)
#endif
#define LIKELY(x) __builtin_expect(!!(x),1)
#define UNLIKELY(x) __builtin_expect((x)!=0,0)
#ifdef __cplusplus
}
#endif
#endif
nativehook/src/main/cpp/libffi/ffi_cxx.cc
0 → 100755
View file @
10c7897b
#include "ffi_cxx.h"
FFICallInterface
::~
FFICallInterface
()
{
for
(
FFIClosure
*
closure
:
closures_
)
{
delete
closure
;
}
delete
cif_
;
delete
types_
;
}
void
FFIDispatcher
(
ffi_cif
*
cif
OPTION
,
void
*
ret
,
void
**
args
,
void
*
userdata
)
{
FFIClosure
*
closure
=
reinterpret_cast
<
FFIClosure
*>
(
userdata
);
FFICallback
callback
=
closure
->
GetCallback
();
callback
(
closure
,
ret
,
args
,
closure
->
GetUserData
());
}
FFIClosure
*
FFICallInterface
::
CreateClosure
(
void
*
userdata
,
FFICallback
callback
)
{
std
::
lock_guard
<
std
::
mutex
>
guard
(
lock_
);
FFIClosure
*
closure
=
new
FFIClosure
(
this
,
userdata
,
callback
);
ffi_prep_closure_loc
(
closure
->
closure_
,
cif_
,
FFIDispatcher
,
closure
,
closure
->
code_
);
closures_
.
push_back
(
closure
);
return
closure
;
}
static
ffi_type
*
FFIGetCType
(
FFIType
type
)
{
switch
(
type
)
{
case
FFIType
:
:
kFFITypeVoid
:
return
&
ffi_type_void
;
case
FFIType
:
:
kFFITypeU1
:
return
&
ffi_type_uint8
;
case
FFIType
:
:
kFFITypeU2
:
return
&
ffi_type_uint16
;
case
FFIType
:
:
kFFITypeU4
:
return
&
ffi_type_uint32
;
case
FFIType
:
:
kFFITypeU8
:
return
&
ffi_type_uint64
;
case
FFIType
:
:
kFFITypeS1
:
return
&
ffi_type_sint8
;
case
FFIType
:
:
kFFITypeS2
:
return
&
ffi_type_sint16
;
case
FFIType
:
:
kFFITypeS4
:
return
&
ffi_type_sint32
;
case
FFIType
:
:
kFFITypeS8
:
return
&
ffi_type_sint64
;
case
FFIType
:
:
kFFITypePointer
:
return
&
ffi_type_pointer
;
case
FFIType
:
:
kFFITypeFloat
:
return
&
ffi_type_float
;
case
FFIType
:
:
kFFITypeDouble
:
return
&
ffi_type_double
;
}
}
FFICallInterface
*
FFICallInterface
::
FinalizeCif
()
{
cif_
=
new
ffi_cif
;
types_
=
new
ffi_type
*
[
parameters_
.
size
()];
int
idx
=
0
;
for
(
FFIType
type
:
parameters_
)
{
types_
[
idx
]
=
FFIGetCType
(
type
);
idx
++
;
}
ffi_prep_cif
(
cif_
,
FFI_DEFAULT_ABI
,
(
unsigned
int
)
parameters_
.
size
(),
FFIGetCType
(
return_type_
),
types_
);
return
this
;
}
nativehook/src/main/cpp/libffi/ffi_cxx.h
0 → 100755
View file @
10c7897b
#ifndef WHALE_FFI_CXX_H_
#define WHALE_FFI_CXX_H_
#include <cstdarg>
#include <list>
#include <mutex>
#include "ffi.h"
#define OPTION __unused
enum
class
FFIType
{
kFFITypeVoid
,
kFFITypeU1
,
kFFITypeU2
,
kFFITypeU4
,
kFFITypeU8
,
kFFITypeS1
,
kFFITypeS2
,
kFFITypeS4
,
kFFITypeS8
,
kFFITypePointer
,
kFFITypeFloat
,
kFFITypeDouble
,
};
class
FFICallInterface
;
class
FFIClosure
;
typedef
void
(
*
FFICallback
)(
FFIClosure
*
closure
,
void
*
ret
,
void
**
args
,
void
*
userdata
);
class
FFIClosure
{
public
:
FFIClosure
(
FFICallInterface
*
cif
,
void
*
userdata
,
FFICallback
callback
)
:
cif_
(
cif
),
userdata_
(
userdata
),
callback_
(
callback
)
{
closure_
=
reinterpret_cast
<
ffi_closure
*>
(
ffi_closure_alloc
(
sizeof
(
ffi_closure
),
&
code_
));
}
~
FFIClosure
()
{
ffi_closure_free
(
closure_
);
}
void
*
GetCode
()
{
return
code_
;
}
void
*
GetUserData
()
{
return
userdata_
;
}
FFICallInterface
*
GetCif
()
{
return
cif_
;
}
FFICallback
GetCallback
()
{
return
callback_
;
}
private
:
friend
class
FFICallInterface
;
FFICallInterface
*
cif_
;
ffi_closure
*
closure_
;
FFICallback
callback_
;
void
*
code_
;
void
*
userdata_
;
};
class
FFICallInterface
{
public
:
FFICallInterface
(
const
FFIType
return_type
)
:
return_type_
(
return_type
)
{}
~
FFICallInterface
();
FFICallInterface
*
Parameter
(
const
FFIType
parameter
)
{
parameters_
.
push_back
(
parameter
);
return
this
;
}
FFICallInterface
*
Parameters
(
unsigned
int
count
,
...)
{
va_list
ap
;
va_start
(
ap
,
count
);
while
(
count
--
>
0
)
{
Parameter
(
va_arg
(
ap
,
FFIType
));
}
va_end
(
ap
);
return
this
;
}
FFICallInterface
*
FinalizeCif
();
size_t
GetParameterCount
()
{
return
parameters_
.
size
();
}
std
::
list
<
FFIType
>
GetParameters
()
{
return
parameters_
;
}
FFIClosure
*
CreateClosure
(
void
*
userdata
,
FFICallback
callback
);
void
RemoveClosure
(
FFIClosure
*
closure
)
{
std
::
lock_guard
<
std
::
mutex
>
guard
(
lock_
);
closures_
.
remove
(
closure
);
}
private
:
std
::
mutex
lock_
;
ffi_cif
*
cif_
;
ffi_type
**
types_
;
std
::
list
<
FFIType
>
parameters_
;
const
FFIType
return_type_
;
std
::
list
<
FFIClosure
*>
closures_
;
};
#endif //WHALE_FFI_CXX_H_
nativehook/src/main/cpp/libffi/fficonfig.h
0 → 100755
View file @
10c7897b
#if defined(__aarch64__) || defined(__arm64__)
#include <fficonfig_arm64.h>
#endif
#ifdef __i386__
#include <fficonfig_i386.h>
#endif
#ifdef __arm__
#include <fficonfig_armv7.h>
#endif
#ifdef __x86_64__
#include <fficonfig_x86_64.h>
#endif
nativehook/src/main/cpp/libffi/ffitarget.h
0 → 100755
View file @
10c7897b
#ifdef __aarch64__
#include <ffitarget_arm64.h>
#endif
#ifdef __i386__
#include <ffitarget_i386.h>
#endif
#ifdef __arm__
#include <ffitarget_armv7.h>
#endif
#ifdef __x86_64__
#include <ffitarget_x86_64.h>
#endif
nativehook/src/main/cpp/libffi/java_raw_api.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
java_raw_api.c - Copyright (c) 1999, 2007, 2008 Red Hat, Inc.
Cloned from raw_api.c
Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
$Id $
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This defines a Java- and 64-bit specific variant of the raw API. */
/* It assumes that "raw" argument blocks look like Java stacks on a */
/* 64-bit machine. Arguments that can be stored in a single stack */
/* stack slots (longs, doubles) occupy 128 bits, but only the first */
/* 64 bits are actually used. */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
#if !defined(NO_JAVA_RAW_API)
size_t
ffi_java_raw_size
(
ffi_cif
*
cif
)
{
size_t
result
=
0
;
int
i
;
ffi_type
**
at
=
cif
->
arg_types
;
for
(
i
=
cif
->
nargs
-
1
;
i
>=
0
;
i
--
,
at
++
)
{
switch
((
*
at
)
->
type
)
{
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_DOUBLE
:
result
+=
2
*
FFI_SIZEOF_JAVA_RAW
;
break
;
case
FFI_TYPE_STRUCT
:
/* No structure parameters in Java. */
abort
();
case
FFI_TYPE_COMPLEX
:
/* Not supported yet. */
abort
();
default:
result
+=
FFI_SIZEOF_JAVA_RAW
;
}
}
return
result
;
}
void
ffi_java_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_java_raw
*
raw
,
void
**
args
)
{
unsigned
i
;
ffi_type
**
tp
=
cif
->
arg_types
;
#if WORDS_BIGENDIAN
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
switch
((
*
tp
)
->
type
)
{
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT8
:
*
args
=
(
void
*
)
((
char
*
)(
raw
++
)
+
3
);
break
;
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT16
:
*
args
=
(
void
*
)
((
char
*
)(
raw
++
)
+
2
);
break
;
#if FFI_SIZEOF_JAVA_RAW == 8
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_DOUBLE
:
*
args
=
(
void
*
)
raw
;
raw
+=
2
;
break
;
#endif
case
FFI_TYPE_POINTER
:
*
args
=
(
void
*
)
&
(
raw
++
)
->
ptr
;
break
;
case
FFI_TYPE_COMPLEX
:
/* Not supported yet. */
abort
();
default:
*
args
=
raw
;
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
sizeof
(
ffi_java_raw
))
/
sizeof
(
ffi_java_raw
);
}
}
#else
/* WORDS_BIGENDIAN */
#if !PDP
/* then assume little endian */
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
#if FFI_SIZEOF_JAVA_RAW == 8
switch
((
*
tp
)
->
type
)
{
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_DOUBLE
:
*
args
=
(
void
*
)
raw
;
raw
+=
2
;
break
;
case
FFI_TYPE_COMPLEX
:
/* Not supported yet. */
abort
();
default:
*
args
=
(
void
*
)
raw
++
;
}
#else
/* FFI_SIZEOF_JAVA_RAW != 8 */
*
args
=
(
void
*
)
raw
;
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
sizeof
(
ffi_java_raw
))
/
sizeof
(
ffi_java_raw
);
#endif
/* FFI_SIZEOF_JAVA_RAW == 8 */
}
#else
#error "pdp endian not supported"
#endif
/* ! PDP */
#endif
/* WORDS_BIGENDIAN */
}
void
ffi_java_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_java_raw
*
raw
)
{
unsigned
i
;
ffi_type
**
tp
=
cif
->
arg_types
;
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
switch
((
*
tp
)
->
type
)
{
case
FFI_TYPE_UINT8
:
#if WORDS_BIGENDIAN
*
(
UINT32
*
)(
raw
++
)
=
*
(
UINT8
*
)
(
*
args
);
#else
(
raw
++
)
->
uint
=
*
(
UINT8
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_SINT8
:
#if WORDS_BIGENDIAN
*
(
SINT32
*
)(
raw
++
)
=
*
(
SINT8
*
)
(
*
args
);
#else
(
raw
++
)
->
sint
=
*
(
SINT8
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_UINT16
:
#if WORDS_BIGENDIAN
*
(
UINT32
*
)(
raw
++
)
=
*
(
UINT16
*
)
(
*
args
);
#else
(
raw
++
)
->
uint
=
*
(
UINT16
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_SINT16
:
#if WORDS_BIGENDIAN
*
(
SINT32
*
)(
raw
++
)
=
*
(
SINT16
*
)
(
*
args
);
#else
(
raw
++
)
->
sint
=
*
(
SINT16
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_UINT32
:
#if WORDS_BIGENDIAN
*
(
UINT32
*
)(
raw
++
)
=
*
(
UINT32
*
)
(
*
args
);
#else
(
raw
++
)
->
uint
=
*
(
UINT32
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_SINT32
:
#if WORDS_BIGENDIAN
*
(
SINT32
*
)(
raw
++
)
=
*
(
SINT32
*
)
(
*
args
);
#else
(
raw
++
)
->
sint
=
*
(
SINT32
*
)
(
*
args
);
#endif
break
;
case
FFI_TYPE_FLOAT
:
(
raw
++
)
->
flt
=
*
(
FLOAT32
*
)
(
*
args
);
break
;
#if FFI_SIZEOF_JAVA_RAW == 8
case
FFI_TYPE_UINT64
:
case
FFI_TYPE_SINT64
:
case
FFI_TYPE_DOUBLE
:
raw
->
uint
=
*
(
UINT64
*
)
(
*
args
);
raw
+=
2
;
break
;
#endif
case
FFI_TYPE_POINTER
:
(
raw
++
)
->
ptr
=
**
(
void
***
)
args
;
break
;
default:
#if FFI_SIZEOF_JAVA_RAW == 8
FFI_ASSERT
(
0
);
/* Should have covered all cases */
#else
memcpy
((
void
*
)
raw
->
data
,
(
void
*
)
*
args
,
(
*
tp
)
->
size
);
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
sizeof
(
ffi_java_raw
))
/
sizeof
(
ffi_java_raw
);
#endif
}
}
}
#if !FFI_NATIVE_RAW_API
static
void
ffi_java_rvalue_to_raw
(
ffi_cif
*
cif
,
void
*
rvalue
)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
switch
(
cif
->
rtype
->
type
)
{
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_UINT32
:
*
(
UINT64
*
)
rvalue
<<=
32
;
break
;
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_INT
:
#if FFI_SIZEOF_JAVA_RAW == 4
case
FFI_TYPE_POINTER
:
#endif
*
(
SINT64
*
)
rvalue
<<=
32
;
break
;
case
FFI_TYPE_COMPLEX
:
/* Not supported yet. */
abort
();
default:
break
;
}
#endif
}
static
void
ffi_java_raw_to_rvalue
(
ffi_cif
*
cif
,
void
*
rvalue
)
{
#if WORDS_BIGENDIAN && FFI_SIZEOF_ARG == 8
switch
(
cif
->
rtype
->
type
)
{
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_UINT32
:
*
(
UINT64
*
)
rvalue
>>=
32
;
break
;
case
FFI_TYPE_SINT8
:
case
FFI_TYPE_SINT16
:
case
FFI_TYPE_SINT32
:
case
FFI_TYPE_INT
:
*
(
SINT64
*
)
rvalue
>>=
32
;
break
;
case
FFI_TYPE_COMPLEX
:
/* Not supported yet. */
abort
();
default:
break
;
}
#endif
}
/* This is a generic definition of ffi_raw_call, to be used if the
* native system does not provide a machine-specific implementation.
* Having this, allows code to be written for the raw API, without
* the need for system-specific code to handle input in that format;
* these following couple of functions will handle the translation forth
* and back automatically. */
void
ffi_java_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_java_raw
*
raw
)
{
void
**
avalue
=
(
void
**
)
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
ffi_java_raw_to_ptrarray
(
cif
,
raw
,
avalue
);
ffi_call
(
cif
,
fn
,
rvalue
,
avalue
);
ffi_java_rvalue_to_raw
(
cif
,
rvalue
);
}
#if FFI_CLOSURES
/* base system provides closures */
static
void
ffi_java_translate_args
(
ffi_cif
*
cif
,
void
*
rvalue
,
void
**
avalue
,
void
*
user_data
)
{
ffi_java_raw
*
raw
=
(
ffi_java_raw
*
)
alloca
(
ffi_java_raw_size
(
cif
));
ffi_raw_closure
*
cl
=
(
ffi_raw_closure
*
)
user_data
;
ffi_java_ptrarray_to_raw
(
cif
,
avalue
,
raw
);
(
*
cl
->
fun
)
(
cif
,
rvalue
,
(
ffi_raw
*
)
raw
,
cl
->
user_data
);
ffi_java_raw_to_rvalue
(
cif
,
rvalue
);
}
ffi_status
ffi_prep_java_raw_closure_loc
(
ffi_java_raw_closure
*
cl
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
)
{
ffi_status
status
;
status
=
ffi_prep_closure_loc
((
ffi_closure
*
)
cl
,
cif
,
&
ffi_java_translate_args
,
codeloc
,
codeloc
);
if
(
status
==
FFI_OK
)
{
cl
->
fun
=
fun
;
cl
->
user_data
=
user_data
;
}
return
status
;
}
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_java_raw_closure
(
ffi_java_raw_closure
*
cl
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
)
{
return
ffi_prep_java_raw_closure_loc
(
cl
,
cif
,
fun
,
user_data
,
cl
);
}
#endif
/* FFI_CLOSURES */
#endif
/* !FFI_NATIVE_RAW_API */
#endif
/* !NO_JAVA_RAW_API */
nativehook/src/main/cpp/libffi/platform_include/ffi_arm64.h
0 → 100755
View file @
10c7897b
#if defined(__aarch64__) || defined(__arm64__)
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern
"C"
{
#endif
/* Specify which architecture libffi is configured for. */
#ifndef AARCH64
#define AARCH64
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52
/* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
/* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX
/* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif
/* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef
struct
_ffi_type
{
size_t
size
;
unsigned
short
alignment
;
unsigned
short
type
;
struct
_ffi_type
**
elements
;
}
ffi_type
;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL
/* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING
/* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else
/* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN
ffi_type
ffi_type_void
;
FFI_EXTERN
ffi_type
ffi_type_uint8
;
FFI_EXTERN
ffi_type
ffi_type_sint8
;
FFI_EXTERN
ffi_type
ffi_type_uint16
;
FFI_EXTERN
ffi_type
ffi_type_sint16
;
FFI_EXTERN
ffi_type
ffi_type_uint32
;
FFI_EXTERN
ffi_type
ffi_type_sint32
;
FFI_EXTERN
ffi_type
ffi_type_uint64
;
FFI_EXTERN
ffi_type
ffi_type_sint64
;
FFI_EXTERN
ffi_type
ffi_type_float
;
FFI_EXTERN
ffi_type
ffi_type_double
;
FFI_EXTERN
ffi_type
ffi_type_pointer
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_longdouble
;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN
ffi_type
ffi_type_complex_float
;
FFI_EXTERN
ffi_type
ffi_type_complex_double
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_complex_longdouble
;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif
/* LIBFFI_HIDE_BASIC_TYPES */
typedef
enum
{
FFI_OK
=
0
,
FFI_BAD_TYPEDEF
,
FFI_BAD_ABI
}
ffi_status
;
typedef
struct
{
ffi_abi
abi
;
unsigned
nargs
;
ffi_type
**
arg_types
;
ffi_type
*
rtype
;
unsigned
bytes
;
unsigned
flags
;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS
;
#endif
}
ffi_cif
;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef
union
{
ffi_sarg
sint
;
ffi_arg
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_ARG
];
void
*
ptr
;
}
ffi_raw
;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef
union
{
signed
int
sint
;
unsigned
int
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_JAVA_RAW
];
void
*
ptr
;
}
ffi_java_raw
;
#else
typedef
ffi_raw
ffi_java_raw
;
#endif
FFI_API
void
ffi_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_raw
*
avalue
);
FFI_API
void
ffi_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_raw
*
raw
);
FFI_API
void
ffi_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_raw_size
(
ffi_cif
*
cif
);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void
ffi_java_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_java_raw
*
avalue
);
FFI_API
void
ffi_java_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_java_raw
*
raw
);
FFI_API
void
ffi_java_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_java_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_java_raw_size
(
ffi_cif
*
cif
);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec
(
align
(
8
))
#endif
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
user_data
;
}
ffi_closure
#ifdef __GNUC__
__attribute__
((
aligned
(
8
)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
);
FFI_API
void
ffi_closure_free
(
void
*
);
FFI_API
ffi_status
ffi_prep_closure
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__
((
deprecated
(
"use ffi_prep_closure_loc instead"
)))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__
((
deprecated
))
#endif
;
FFI_API
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#ifdef __sgi
# pragma pack 8
#endif
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_raw_closure
;
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_java_raw_closure
;
FFI_API
ffi_status
ffi_prep_raw_closure
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_raw_closure_loc
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
FFI_API
ffi_status
ffi_prep_java_raw_closure
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_java_raw_closure_loc
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#endif
/* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef
struct
{
void
*
tramp
;
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
}
ffi_go_closure
;
FFI_API
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
));
FFI_API
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
);
#endif
/* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status
ffi_prep_cif
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
ffi_status
ffi_prep_cif_var
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
);
FFI_API
ffi_status
ffi_get_struct_offsets
(
ffi_abi
abi
,
ffi_type
*
struct_type
,
size_t
*
offsets
);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffi_armv7.h
0 → 100755
View file @
10c7897b
#ifdef __arm__
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern
"C"
{
#endif
/* Specify which architecture libffi is configured for. */
#ifndef ARM
#define ARM
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52
/* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
/* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX
/* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif
/* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef
struct
_ffi_type
{
size_t
size
;
unsigned
short
alignment
;
unsigned
short
type
;
struct
_ffi_type
**
elements
;
}
ffi_type
;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL
/* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING
/* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else
/* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN
ffi_type
ffi_type_void
;
FFI_EXTERN
ffi_type
ffi_type_uint8
;
FFI_EXTERN
ffi_type
ffi_type_sint8
;
FFI_EXTERN
ffi_type
ffi_type_uint16
;
FFI_EXTERN
ffi_type
ffi_type_sint16
;
FFI_EXTERN
ffi_type
ffi_type_uint32
;
FFI_EXTERN
ffi_type
ffi_type_sint32
;
FFI_EXTERN
ffi_type
ffi_type_uint64
;
FFI_EXTERN
ffi_type
ffi_type_sint64
;
FFI_EXTERN
ffi_type
ffi_type_float
;
FFI_EXTERN
ffi_type
ffi_type_double
;
FFI_EXTERN
ffi_type
ffi_type_pointer
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_longdouble
;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN
ffi_type
ffi_type_complex_float
;
FFI_EXTERN
ffi_type
ffi_type_complex_double
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_complex_longdouble
;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif
/* LIBFFI_HIDE_BASIC_TYPES */
typedef
enum
{
FFI_OK
=
0
,
FFI_BAD_TYPEDEF
,
FFI_BAD_ABI
}
ffi_status
;
typedef
struct
{
ffi_abi
abi
;
unsigned
nargs
;
ffi_type
**
arg_types
;
ffi_type
*
rtype
;
unsigned
bytes
;
unsigned
flags
;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS
;
#endif
}
ffi_cif
;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef
union
{
ffi_sarg
sint
;
ffi_arg
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_ARG
];
void
*
ptr
;
}
ffi_raw
;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef
union
{
signed
int
sint
;
unsigned
int
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_JAVA_RAW
];
void
*
ptr
;
}
ffi_java_raw
;
#else
typedef
ffi_raw
ffi_java_raw
;
#endif
FFI_API
void
ffi_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_raw
*
avalue
);
FFI_API
void
ffi_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_raw
*
raw
);
FFI_API
void
ffi_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_raw_size
(
ffi_cif
*
cif
);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void
ffi_java_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_java_raw
*
avalue
);
FFI_API
void
ffi_java_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_java_raw
*
raw
);
FFI_API
void
ffi_java_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_java_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_java_raw_size
(
ffi_cif
*
cif
);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec
(
align
(
8
))
#endif
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
user_data
;
}
ffi_closure
#ifdef __GNUC__
__attribute__
((
aligned
(
8
)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
);
FFI_API
void
ffi_closure_free
(
void
*
);
FFI_API
ffi_status
ffi_prep_closure
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__
((
deprecated
(
"use ffi_prep_closure_loc instead"
)))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__
((
deprecated
))
#endif
;
FFI_API
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#ifdef __sgi
# pragma pack 8
#endif
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_raw_closure
;
typedef
struct
{
#if FFI_EXEC_TRAMPOLINE_TABLE
void
*
trampoline_table
;
void
*
trampoline_table_entry
;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_java_raw_closure
;
FFI_API
ffi_status
ffi_prep_raw_closure
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_raw_closure_loc
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
FFI_API
ffi_status
ffi_prep_java_raw_closure
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_java_raw_closure_loc
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#endif
/* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef
struct
{
void
*
tramp
;
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
}
ffi_go_closure
;
FFI_API
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
));
FFI_API
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
);
#endif
/* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status
ffi_prep_cif
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
ffi_status
ffi_prep_cif_var
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
);
FFI_API
ffi_status
ffi_get_struct_offsets
(
ffi_abi
abi
,
ffi_type
*
struct_type
,
size_t
*
offsets
);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffi_i386.h
0 → 100755
View file @
10c7897b
#ifdef __i386__
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern
"C"
{
#endif
/* Specify which architecture libffi is configured for. */
#ifndef X86_UNIX
#define X86_UNIX
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52
/* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
/* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX
/* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif
/* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef
struct
_ffi_type
{
size_t
size
;
unsigned
short
alignment
;
unsigned
short
type
;
struct
_ffi_type
**
elements
;
}
ffi_type
;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL
/* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING
/* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else
/* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN
ffi_type
ffi_type_void
;
FFI_EXTERN
ffi_type
ffi_type_uint8
;
FFI_EXTERN
ffi_type
ffi_type_sint8
;
FFI_EXTERN
ffi_type
ffi_type_uint16
;
FFI_EXTERN
ffi_type
ffi_type_sint16
;
FFI_EXTERN
ffi_type
ffi_type_uint32
;
FFI_EXTERN
ffi_type
ffi_type_sint32
;
FFI_EXTERN
ffi_type
ffi_type_uint64
;
FFI_EXTERN
ffi_type
ffi_type_sint64
;
FFI_EXTERN
ffi_type
ffi_type_float
;
FFI_EXTERN
ffi_type
ffi_type_double
;
FFI_EXTERN
ffi_type
ffi_type_pointer
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_longdouble
;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN
ffi_type
ffi_type_complex_float
;
FFI_EXTERN
ffi_type
ffi_type_complex_double
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_complex_longdouble
;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif
/* LIBFFI_HIDE_BASIC_TYPES */
typedef
enum
{
FFI_OK
=
0
,
FFI_BAD_TYPEDEF
,
FFI_BAD_ABI
}
ffi_status
;
typedef
struct
{
ffi_abi
abi
;
unsigned
nargs
;
ffi_type
**
arg_types
;
ffi_type
*
rtype
;
unsigned
bytes
;
unsigned
flags
;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS
;
#endif
}
ffi_cif
;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef
union
{
ffi_sarg
sint
;
ffi_arg
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_ARG
];
void
*
ptr
;
}
ffi_raw
;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef
union
{
signed
int
sint
;
unsigned
int
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_JAVA_RAW
];
void
*
ptr
;
}
ffi_java_raw
;
#else
typedef
ffi_raw
ffi_java_raw
;
#endif
FFI_API
void
ffi_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_raw
*
avalue
);
FFI_API
void
ffi_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_raw
*
raw
);
FFI_API
void
ffi_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_raw_size
(
ffi_cif
*
cif
);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void
ffi_java_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_java_raw
*
avalue
);
FFI_API
void
ffi_java_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_java_raw
*
raw
);
FFI_API
void
ffi_java_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_java_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_java_raw_size
(
ffi_cif
*
cif
);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec
(
align
(
8
))
#endif
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
user_data
;
}
ffi_closure
#ifdef __GNUC__
__attribute__
((
aligned
(
8
)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
);
FFI_API
void
ffi_closure_free
(
void
*
);
FFI_API
ffi_status
ffi_prep_closure
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__
((
deprecated
(
"use ffi_prep_closure_loc instead"
)))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__
((
deprecated
))
#endif
;
FFI_API
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#ifdef __sgi
# pragma pack 8
#endif
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_raw_closure
;
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_java_raw_closure
;
FFI_API
ffi_status
ffi_prep_raw_closure
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_raw_closure_loc
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
FFI_API
ffi_status
ffi_prep_java_raw_closure
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_java_raw_closure_loc
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#endif
/* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef
struct
{
void
*
tramp
;
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
}
ffi_go_closure
;
FFI_API
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
));
FFI_API
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
);
#endif
/* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status
ffi_prep_cif
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
ffi_status
ffi_prep_cif_var
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
);
FFI_API
ffi_status
ffi_get_struct_offsets
(
ffi_abi
abi
,
ffi_type
*
struct_type
,
size_t
*
offsets
);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffi_x86_64.h
0 → 100755
View file @
10c7897b
#ifdef __x86_64__
/* -----------------------------------------------------------------*-C-*-
libffi 3.3-rc0 - Copyright (c) 2011, 2014 Anthony Green
- Copyright (c) 1996-2003, 2007, 2008 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the ``Software''), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* -------------------------------------------------------------------
Most of the API is documented in doc/libffi.texi.
The raw API is designed to bypass some of the argument packing and
unpacking on architectures for which it can be avoided. Routines
are provided to emulate the raw API if the underlying platform
doesn't allow faster implementation.
More details on the raw API can be found in:
http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
and
http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
-------------------------------------------------------------------- */
#ifndef LIBFFI_H
#define LIBFFI_H
#ifdef __cplusplus
extern
"C"
{
#endif
/* Specify which architecture libffi is configured for. */
#ifndef X86_64
#define X86_64
#endif
/* ---- System configuration information --------------------------------- */
#include <ffitarget.h>
#ifndef LIBFFI_ASM
#if defined(_MSC_VER) && !defined(__clang__)
#define __attribute__(X)
#endif
#include <stddef.h>
#include <limits.h>
/* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example).
But we can find it either under the correct ANSI name, or under GNU
C's internal name. */
#define FFI_64_BIT_MAX 9223372036854775807
#ifdef LONG_LONG_MAX
# define FFI_LONG_LONG_MAX LONG_LONG_MAX
#else
# ifdef LLONG_MAX
# define FFI_LONG_LONG_MAX LLONG_MAX
# ifdef _AIX52
/* or newer has C99 LLONG_MAX */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
/* _AIX52 or newer */
# else
# ifdef __GNUC__
# define FFI_LONG_LONG_MAX __LONG_LONG_MAX__
# endif
# ifdef _AIX
/* AIX 5.1 and earlier have LONGLONG_MAX */
# ifndef __PPC64__
# if defined (__IBMC__) || defined (__IBMCPP__)
# define FFI_LONG_LONG_MAX LONGLONG_MAX
# endif
# endif
/* __PPC64__ */
# undef FFI_64_BIT_MAX
# define FFI_64_BIT_MAX 9223372036854775807LL
# endif
# endif
#endif
/* The closure code assumes that this works on pointers, i.e. a size_t
can hold a pointer. */
typedef
struct
_ffi_type
{
size_t
size
;
unsigned
short
alignment
;
unsigned
short
type
;
struct
_ffi_type
**
elements
;
}
ffi_type
;
/* Need minimal decorations for DLLs to work on Windows. GCC has
autoimport and autoexport. Always mark externally visible symbols
as dllimport for MSVC clients, even if it means an extra indirection
when using the static version of the library.
Besides, as a workaround, they can define FFI_BUILDING if they
*know* they are going to link with the static library. */
#if defined _MSC_VER
# if defined FFI_BUILDING_DLL
/* Building libffi.DLL with msvcc.sh */
# define FFI_API __declspec(dllexport)
# elif !defined FFI_BUILDING
/* Importing libffi.DLL */
# define FFI_API __declspec(dllimport)
# else
/* Building/linking static library */
# define FFI_API
# endif
#else
# define FFI_API
#endif
/* The externally visible type declarations also need the MSVC DLL
decorations, or they will not be exported from the object file. */
#if defined LIBFFI_HIDE_BASIC_TYPES
# define FFI_EXTERN FFI_API
#else
# define FFI_EXTERN extern FFI_API
#endif
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8
#else
#error "char size not supported"
#endif
#if SHRT_MAX == 32767
# define ffi_type_ushort ffi_type_uint16
# define ffi_type_sshort ffi_type_sint16
#elif SHRT_MAX == 2147483647
# define ffi_type_ushort ffi_type_uint32
# define ffi_type_sshort ffi_type_sint32
#else
#error "short size not supported"
#endif
#if INT_MAX == 32767
# define ffi_type_uint ffi_type_uint16
# define ffi_type_sint ffi_type_sint16
#elif INT_MAX == 2147483647
# define ffi_type_uint ffi_type_uint32
# define ffi_type_sint ffi_type_sint32
#elif INT_MAX == 9223372036854775807
# define ffi_type_uint ffi_type_uint64
# define ffi_type_sint ffi_type_sint64
#else
#error "int size not supported"
#endif
#if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != FFI_64_BIT_MAX
#error "no 64-bit data type supported"
# endif
#elif LONG_MAX != FFI_64_BIT_MAX
#error "long size not supported"
#endif
#if LONG_MAX == 2147483647
# define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == FFI_64_BIT_MAX
# define ffi_type_ulong ffi_type_uint64
# define ffi_type_slong ffi_type_sint64
#else
#error "long size not supported"
#endif
/* These are defined in types.c. */
FFI_EXTERN
ffi_type
ffi_type_void
;
FFI_EXTERN
ffi_type
ffi_type_uint8
;
FFI_EXTERN
ffi_type
ffi_type_sint8
;
FFI_EXTERN
ffi_type
ffi_type_uint16
;
FFI_EXTERN
ffi_type
ffi_type_sint16
;
FFI_EXTERN
ffi_type
ffi_type_uint32
;
FFI_EXTERN
ffi_type
ffi_type_sint32
;
FFI_EXTERN
ffi_type
ffi_type_uint64
;
FFI_EXTERN
ffi_type
ffi_type_sint64
;
FFI_EXTERN
ffi_type
ffi_type_float
;
FFI_EXTERN
ffi_type
ffi_type_double
;
FFI_EXTERN
ffi_type
ffi_type_pointer
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_longdouble
;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_EXTERN
ffi_type
ffi_type_complex_float
;
FFI_EXTERN
ffi_type
ffi_type_complex_double
;
#if 1
FFI_EXTERN
ffi_type
ffi_type_complex_longdouble
;
#else
#define ffi_type_complex_longdouble ffi_type_complex_double
#endif
#endif
#endif
/* LIBFFI_HIDE_BASIC_TYPES */
typedef
enum
{
FFI_OK
=
0
,
FFI_BAD_TYPEDEF
,
FFI_BAD_ABI
}
ffi_status
;
typedef
struct
{
ffi_abi
abi
;
unsigned
nargs
;
ffi_type
**
arg_types
;
ffi_type
*
rtype
;
unsigned
bytes
;
unsigned
flags
;
#ifdef FFI_EXTRA_CIF_FIELDS
FFI_EXTRA_CIF_FIELDS
;
#endif
}
ffi_cif
;
/* ---- Definitions for the raw API -------------------------------------- */
#ifndef FFI_SIZEOF_ARG
# if LONG_MAX == 2147483647
# define FFI_SIZEOF_ARG 4
# elif LONG_MAX == FFI_64_BIT_MAX
# define FFI_SIZEOF_ARG 8
# endif
#endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef
union
{
ffi_sarg
sint
;
ffi_arg
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_ARG
];
void
*
ptr
;
}
ffi_raw
;
#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef
union
{
signed
int
sint
;
unsigned
int
uint
;
float
flt
;
char
data
[
FFI_SIZEOF_JAVA_RAW
];
void
*
ptr
;
}
ffi_java_raw
;
#else
typedef
ffi_raw
ffi_java_raw
;
#endif
FFI_API
void
ffi_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_raw
*
avalue
);
FFI_API
void
ffi_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_raw
*
raw
);
FFI_API
void
ffi_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_raw_size
(
ffi_cif
*
cif
);
/* This is analogous to the raw API, except it uses Java parameter
packing, even on 64-bit machines. I.e. on 64-bit machines longs
and doubles are followed by an empty 64-bit word. */
FFI_API
void
ffi_java_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_java_raw
*
avalue
);
FFI_API
void
ffi_java_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_java_raw
*
raw
);
FFI_API
void
ffi_java_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_java_raw
*
raw
,
void
**
args
);
FFI_API
size_t
ffi_java_raw_size
(
ffi_cif
*
cif
);
/* ---- Definitions for closures ----------------------------------------- */
#if FFI_CLOSURES
#ifdef _MSC_VER
__declspec
(
align
(
8
))
#endif
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
user_data
;
}
ffi_closure
#ifdef __GNUC__
__attribute__
((
aligned
(
8
)))
#endif
;
#ifndef __GNUC__
# ifdef __sgi
# pragma pack 0
# endif
#endif
FFI_API
void
*
ffi_closure_alloc
(
size_t
size
,
void
**
code
);
FFI_API
void
ffi_closure_free
(
void
*
);
FFI_API
ffi_status
ffi_prep_closure
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 405)
__attribute__
((
deprecated
(
"use ffi_prep_closure_loc instead"
)))
#elif defined(__GNUC__) && __GNUC__ >= 3
__attribute__
((
deprecated
))
#endif
;
FFI_API
ffi_status
ffi_prep_closure_loc
(
ffi_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#ifdef __sgi
# pragma pack 8
#endif
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_raw_closure
;
typedef
struct
{
#if 0
void *trampoline_table;
void *trampoline_table_entry;
#else
char
tramp
[
FFI_TRAMPOLINE_SIZE
];
#endif
ffi_cif
*
cif
;
#if !FFI_NATIVE_RAW_API
/* If this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the translation, void** -> ffi_raw*. */
void
(
*
translate_args
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
void
*
this_closure
;
#endif
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
);
void
*
user_data
;
}
ffi_java_raw_closure
;
FFI_API
ffi_status
ffi_prep_raw_closure
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_raw_closure_loc
(
ffi_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
FFI_API
ffi_status
ffi_prep_java_raw_closure
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
);
FFI_API
ffi_status
ffi_prep_java_raw_closure_loc
(
ffi_java_raw_closure
*
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_java_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
);
#endif
/* FFI_CLOSURES */
#if FFI_GO_CLOSURES
typedef
struct
{
void
*
tramp
;
ffi_cif
*
cif
;
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
);
}
ffi_go_closure
;
FFI_API
ffi_status
ffi_prep_go_closure
(
ffi_go_closure
*
,
ffi_cif
*
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
));
FFI_API
void
ffi_call_go
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
,
void
*
closure
);
#endif
/* FFI_GO_CLOSURES */
/* ---- Public interface definition -------------------------------------- */
FFI_API
ffi_status
ffi_prep_cif
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
ffi_status
ffi_prep_cif_var
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
);
FFI_API
void
ffi_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
void
**
avalue
);
FFI_API
ffi_status
ffi_get_struct_offsets
(
ffi_abi
abi
,
ffi_type
*
struct_type
,
size_t
*
offsets
);
/* Useful for eliminating compiler warnings. */
#define FFI_FN(f) ((void (*)(void))f)
/* ---- Definitions shared with assembly code ---------------------------- */
#endif
/* If these change, update src/mips/ffitarget.h. */
#define FFI_TYPE_VOID 0
#define FFI_TYPE_INT 1
#define FFI_TYPE_FLOAT 2
#define FFI_TYPE_DOUBLE 3
#if 1
#define FFI_TYPE_LONGDOUBLE 4
#else
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
#endif
#define FFI_TYPE_UINT8 5
#define FFI_TYPE_SINT8 6
#define FFI_TYPE_UINT16 7
#define FFI_TYPE_SINT16 8
#define FFI_TYPE_UINT32 9
#define FFI_TYPE_SINT32 10
#define FFI_TYPE_UINT64 11
#define FFI_TYPE_SINT64 12
#define FFI_TYPE_STRUCT 13
#define FFI_TYPE_POINTER 14
#define FFI_TYPE_COMPLEX 15
/* This should always refer to the last type code (for sanity checks). */
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
#ifdef __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/fficonfig_arm64.h
0 → 100755
View file @
10c7897b
#if defined(__aarch64__) || defined(__arm64__)
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
#define EH_FRAME_FLAGS "aw"
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
#ifdef __APPLE__
#define FFI_EXEC_TRAMPOLINE_TABLE 1
#endif
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
#ifdef linux
#define FFI_MMAP_EXEC_WRIT 1
#endif
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define if your assembler supports .cfi_* directives. */
#define HAVE_AS_CFI_PSEUDO_OP 1
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
/* #undef HAVE_AS_X86_PCREL */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if __attribute__((visibility("hidden"))) is supported. */
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
/* #undef HAVE_LONG_DOUBLE */
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
#define HAVE_MMAP 1
/* Define if mmap with MAP_ANON(YMOUS) works. */
#define HAVE_MMAP_ANON 1
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
#define HAVE_MMAP_FILE 1
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 8
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 8
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
#define SYMBOL_UNDERSCORE 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/fficonfig_armv7.h
0 → 100755
View file @
10c7897b
#ifdef __arm__
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
#define EH_FRAME_FLAGS "aw"
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
#ifdef __APPLE__
#define FFI_EXEC_TRAMPOLINE_TABLE 1
#endif
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
#ifdef linux
#define FFI_MMAP_EXEC_WRIT 1
#endif
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define if your assembler supports .cfi_* directives. */
#define HAVE_AS_CFI_PSEUDO_OP 1
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
/* #undef HAVE_AS_X86_PCREL */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if __attribute__((visibility("hidden"))) is supported. */
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
/* #undef HAVE_LONG_DOUBLE */
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
#define HAVE_MMAP 1
/* Define if mmap with MAP_ANON(YMOUS) works. */
#define HAVE_MMAP_ANON 1
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
#define HAVE_MMAP_FILE 1
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 8
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
#define SYMBOL_UNDERSCORE 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/fficonfig_i386.h
0 → 100755
View file @
10c7897b
#ifdef __i386__
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
#define EH_FRAME_FLAGS "aw"
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
#define FFI_MMAP_EXEC_WRIT 1
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define if your assembler supports .cfi_* directives. */
#define HAVE_AS_CFI_PSEUDO_OP 1
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
#define HAVE_AS_X86_PCREL 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if __attribute__((visibility("hidden"))) is supported. */
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
#define HAVE_LONG_DOUBLE 1
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
#define HAVE_MMAP 1
/* Define if mmap with MAP_ANON(YMOUS) works. */
#define HAVE_MMAP_ANON 1
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
#define HAVE_MMAP_FILE 1
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 16
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 4
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
#define SYMBOL_UNDERSCORE 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/fficonfig_x86_64.h
0 → 100755
View file @
10c7897b
#ifdef __x86_64__
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
/* #undef CRAY_STACKSEG_END */
/* Define to 1 if using `alloca.c'. */
/* #undef C_ALLOCA */
/* Define to the flags needed for the .section .eh_frame directive. */
#define EH_FRAME_FLAGS "aw"
/* Define this if you want extra debugging. */
/* #undef FFI_DEBUG */
/* Cannot use PROT_EXEC on this target, so, we revert to alternative means */
/* #undef FFI_EXEC_TRAMPOLINE_TABLE */
/* Define this if you want to enable pax emulated trampolines */
/* #undef FFI_MMAP_EXEC_EMUTRAMP_PAX */
/* Cannot use malloc on this target, so, we revert to alternative means */
#define FFI_MMAP_EXEC_WRIT 1
/* Define this if you do not want support for the raw API. */
/* #undef FFI_NO_RAW_API */
/* Define this if you do not want support for aggregate types. */
/* #undef FFI_NO_STRUCTS */
/* Define to 1 if you have `alloca', as a function or macro. */
#define HAVE_ALLOCA 1
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#define HAVE_ALLOCA_H 1
/* Define if your assembler supports .cfi_* directives. */
#define HAVE_AS_CFI_PSEUDO_OP 1
/* Define if your assembler supports .register. */
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
/* Define if the compiler uses zarch features. */
/* #undef HAVE_AS_S390_ZARCH */
/* Define if your assembler and linker support unaligned PC relative relocs.
*/
/* #undef HAVE_AS_SPARC_UA_PCREL */
/* Define if your assembler supports unwind section type. */
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
/* Define if your assembler supports PC relative relocs. */
#define HAVE_AS_X86_PCREL 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define if __attribute__((visibility("hidden"))) is supported. */
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define if you have the long double type and it is bigger than a double */
#define HAVE_LONG_DOUBLE 1
/* Define if you support more than one size of the long double type */
/* #undef HAVE_LONG_DOUBLE_VARIANT */
/* Define to 1 if you have the `memcpy' function. */
#define HAVE_MEMCPY 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `mkostemp' function. */
/* #undef HAVE_MKOSTEMP */
/* Define to 1 if you have the `mmap' function. */
#define HAVE_MMAP 1
/* Define if mmap with MAP_ANON(YMOUS) works. */
#define HAVE_MMAP_ANON 1
/* Define if mmap of /dev/zero works. */
/* #undef HAVE_MMAP_DEV_ZERO */
/* Define if read-only mmap of a plain file works. */
#define HAVE_MMAP_FILE 1
/* Define if .eh_frame sections should be read-only. */
/* #undef HAVE_RO_EH_FRAME */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/mman.h> header file. */
#define HAVE_SYS_MMAN_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if GNU symbol versioning is used for libatomic. */
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
/* Define to the sub-directory where libtool stores uninstalled libraries. */
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libffi"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "http://github.com/libffi/libffi/issues"
/* Define to the full name of this package. */
#define PACKAGE_NAME "libffi"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libffi 3.3-rc0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libffi"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.3-rc0"
/* The size of `double', as computed by sizeof. */
#define SIZEOF_DOUBLE 8
/* The size of `long double', as computed by sizeof. */
#define SIZEOF_LONG_DOUBLE 16
/* The size of `size_t', as computed by sizeof. */
#define SIZEOF_SIZE_T 8
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
/* #undef STACK_DIRECTION */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Define if symbols are underscored. */
#define SYMBOL_UNDERSCORE 1
/* Define this if you are using Purify and want to suppress spurious messages.
*/
/* #undef USING_PURIFY */
/* Version number of package */
#define VERSION "3.3-rc0"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
# define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* # undef WORDS_BIGENDIAN */
# endif
#endif
/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */
#ifdef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE
#ifdef LIBFFI_ASM
#ifdef __APPLE__
#define FFI_HIDDEN(name) .private_extern name
#else
#define FFI_HIDDEN(name) .hidden name
#endif
#else
#define FFI_HIDDEN __attribute__ ((visibility ("hidden")))
#endif
#else
#ifdef LIBFFI_ASM
#define FFI_HIDDEN(name)
#else
#define FFI_HIDDEN
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffitarget_arm64.h
0 → 100755
View file @
10c7897b
#ifdef __aarch64__
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
#ifndef LIBFFI_ASM
#ifdef __ILP32__
#define FFI_SIZEOF_ARG 8
#define FFI_SIZEOF_JAVA_RAW 4
typedef
unsigned
long
long
ffi_arg
;
typedef
signed
long
long
ffi_sarg
;
#else
typedef
unsigned
long
ffi_arg
;
typedef
signed
long
ffi_sarg
;
#endif
typedef
enum
ffi_abi
{
FFI_FIRST_ABI
=
0
,
FFI_SYSV
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_SYSV
}
ffi_abi
;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#define FFI_TRAMPOLINE_SIZE 16
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 16
#else
#error "No trampoline table implementation"
#endif
#else
#define FFI_TRAMPOLINE_SIZE 24
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
#endif
/* ---- Internal ---- */
#if defined (__APPLE__)
#define FFI_TARGET_SPECIFIC_VARIADIC
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
#else
/* iOS reserves x18 for the system. Disable Go closures until
a new static chain is chosen. */
#define FFI_GO_CLOSURES 1
#endif
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffitarget_armv7.h
0 → 100755
View file @
10c7897b
#ifdef __arm__
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2012 Anthony Green
Copyright (c) 2010 CodeSourcery
Copyright (c) 1996-2003 Red Hat, Inc.
Target configuration macros for ARM.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
#ifndef LIBFFI_ASM
typedef
unsigned
long
ffi_arg
;
typedef
signed
long
ffi_sarg
;
typedef
enum
ffi_abi
{
FFI_FIRST_ABI
=
0
,
FFI_SYSV
,
FFI_VFP
,
FFI_LAST_ABI
,
#ifdef __ARM_PCS_VFP
FFI_DEFAULT_ABI
=
FFI_VFP
,
#else
FFI_DEFAULT_ABI
=
FFI_SYSV
,
#endif
}
ffi_abi
;
#endif
#define FFI_EXTRA_CIF_FIELDS \
int vfp_used; \
unsigned short vfp_reg_free, vfp_nargs; \
signed char vfp_args[16] \
#define FFI_TARGET_SPECIFIC_VARIADIC
#define FFI_TARGET_HAS_COMPLEX_TYPE
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_GO_CLOSURES 1
#define FFI_NATIVE_RAW_API 0
#if defined (FFI_EXEC_TRAMPOLINE_TABLE) && FFI_EXEC_TRAMPOLINE_TABLE
#ifdef __MACH__
#define FFI_TRAMPOLINE_SIZE 12
#define FFI_TRAMPOLINE_CLOSURE_OFFSET 8
#else
#error "No trampoline table implementation"
#endif
#else
#define FFI_TRAMPOLINE_SIZE 12
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffitarget_i386.h
0 → 100755
View file @
10c7897b
#ifdef __i386__
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
Copyright (c) 1996-2003, 2010 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
Target configuration macros for x86 and x86-64.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
/* ---- System specific configurations ----------------------------------- */
/* For code common to all platforms on x86 and x86_64. */
#define X86_ANY
#if defined (X86_64) && defined (__i386__)
#undef X86_64
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
#define USE_BUILTIN_FFS 0
/* not yet implemented in mingw-64 */
#endif
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
#ifndef _MSC_VER
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef
unsigned
__int64
ffi_arg
;
typedef
__int64
ffi_sarg
;
#else
typedef
unsigned
long
long
ffi_arg
;
typedef
long
long
ffi_sarg
;
#endif
#else
#if defined __x86_64__ && defined __ILP32__
#define FFI_SIZEOF_ARG 8
#define FFI_SIZEOF_JAVA_RAW 4
typedef
unsigned
long
long
ffi_arg
;
typedef
long
long
ffi_sarg
;
#else
typedef
unsigned
long
ffi_arg
;
typedef
signed
long
ffi_sarg
;
#endif
#endif
typedef
enum
ffi_abi
{
#if defined(X86_WIN64)
FFI_FIRST_ABI
=
0
,
FFI_WIN64
,
/* sizeof(long double) == 8 - microsoft compilers */
FFI_GNUW64
,
/* sizeof(long double) == 16 - GNU compilers */
FFI_LAST_ABI
,
#ifdef __GNUC__
FFI_DEFAULT_ABI
=
FFI_GNUW64
#else
FFI_DEFAULT_ABI
=
FFI_WIN64
#endif
#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
FFI_FIRST_ABI
=
1
,
FFI_UNIX64
,
FFI_WIN64
,
FFI_EFI64
=
FFI_WIN64
,
FFI_GNUW64
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_UNIX64
#elif defined(X86_WIN32)
FFI_FIRST_ABI
=
0
,
FFI_SYSV
=
1
,
FFI_STDCALL
=
2
,
FFI_THISCALL
=
3
,
FFI_FASTCALL
=
4
,
FFI_MS_CDECL
=
5
,
FFI_PASCAL
=
6
,
FFI_REGISTER
=
7
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_MS_CDECL
#else
FFI_FIRST_ABI
=
0
,
FFI_SYSV
=
1
,
FFI_THISCALL
=
3
,
FFI_FASTCALL
=
4
,
FFI_STDCALL
=
5
,
FFI_PASCAL
=
6
,
FFI_REGISTER
=
7
,
FFI_MS_CDECL
=
8
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_SYSV
#endif
}
ffi_abi
;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_GO_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
#if defined (X86_64) || defined(X86_WIN64) \
|| (defined (__x86_64__) && defined (X86_DARWIN))
# define FFI_TRAMPOLINE_SIZE 24
# define FFI_NATIVE_RAW_API 0
#else
# define FFI_TRAMPOLINE_SIZE 12
# define FFI_NATIVE_RAW_API 1
/* x86 has native raw api support */
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/platform_include/ffitarget_x86_64.h
0 → 100755
View file @
10c7897b
#ifdef __x86_64__
/* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green
Copyright (c) 1996-2003, 2010 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
Target configuration macros for x86 and x86-64.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H
#ifndef LIBFFI_H
#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead."
#endif
/* ---- System specific configurations ----------------------------------- */
/* For code common to all platforms on x86 and x86_64. */
#define X86_ANY
#if defined (X86_64) && defined (__i386__)
#undef X86_64
#define X86
#endif
#ifdef X86_WIN64
#define FFI_SIZEOF_ARG 8
#define USE_BUILTIN_FFS 0
/* not yet implemented in mingw-64 */
#endif
#define FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
#ifndef _MSC_VER
#define FFI_TARGET_HAS_COMPLEX_TYPE
#endif
/* ---- Generic type definitions ----------------------------------------- */
#ifndef LIBFFI_ASM
#ifdef X86_WIN64
#ifdef _MSC_VER
typedef
unsigned
__int64
ffi_arg
;
typedef
__int64
ffi_sarg
;
#else
typedef
unsigned
long
long
ffi_arg
;
typedef
long
long
ffi_sarg
;
#endif
#else
#if defined __x86_64__ && defined __ILP32__
#define FFI_SIZEOF_ARG 8
#define FFI_SIZEOF_JAVA_RAW 4
typedef
unsigned
long
long
ffi_arg
;
typedef
long
long
ffi_sarg
;
#else
typedef
unsigned
long
ffi_arg
;
typedef
signed
long
ffi_sarg
;
#endif
#endif
typedef
enum
ffi_abi
{
#if defined(X86_WIN64)
FFI_FIRST_ABI
=
0
,
FFI_WIN64
,
/* sizeof(long double) == 8 - microsoft compilers */
FFI_GNUW64
,
/* sizeof(long double) == 16 - GNU compilers */
FFI_LAST_ABI
,
#ifdef __GNUC__
FFI_DEFAULT_ABI
=
FFI_GNUW64
#else
FFI_DEFAULT_ABI
=
FFI_WIN64
#endif
#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
FFI_FIRST_ABI
=
1
,
FFI_UNIX64
,
FFI_WIN64
,
FFI_EFI64
=
FFI_WIN64
,
FFI_GNUW64
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_UNIX64
#elif defined(X86_WIN32)
FFI_FIRST_ABI
=
0
,
FFI_SYSV
=
1
,
FFI_STDCALL
=
2
,
FFI_THISCALL
=
3
,
FFI_FASTCALL
=
4
,
FFI_MS_CDECL
=
5
,
FFI_PASCAL
=
6
,
FFI_REGISTER
=
7
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_MS_CDECL
#else
FFI_FIRST_ABI
=
0
,
FFI_SYSV
=
1
,
FFI_THISCALL
=
3
,
FFI_FASTCALL
=
4
,
FFI_STDCALL
=
5
,
FFI_PASCAL
=
6
,
FFI_REGISTER
=
7
,
FFI_MS_CDECL
=
8
,
FFI_LAST_ABI
,
FFI_DEFAULT_ABI
=
FFI_SYSV
#endif
}
ffi_abi
;
#endif
/* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1
#define FFI_GO_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
#define FFI_TYPE_SMALL_STRUCT_4B (FFI_TYPE_LAST + 3)
#define FFI_TYPE_MS_STRUCT (FFI_TYPE_LAST + 4)
#if defined (X86_64) || defined(X86_WIN64) \
|| (defined (__x86_64__) && defined (X86_DARWIN))
# define FFI_TRAMPOLINE_SIZE 24
# define FFI_NATIVE_RAW_API 0
#else
# define FFI_TRAMPOLINE_SIZE 12
# define FFI_NATIVE_RAW_API 1
/* x86 has native raw api support */
#endif
#endif
#endif
\ No newline at end of file
nativehook/src/main/cpp/libffi/prep_cif.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
prep_cif.c - Copyright (c) 2011, 2012 Anthony Green
Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#include <ffi.h>
#include <ffi_common.h>
#include <stdlib.h>
/* Round up to FFI_SIZEOF_ARG. */
#define STACK_ARG_SIZE(x) FFI_ALIGN(x, FFI_SIZEOF_ARG)
/* Perform machine independent initialization of aggregate type
specifications. */
static
ffi_status
initialize_aggregate
(
ffi_type
*
arg
,
size_t
*
offsets
)
{
ffi_type
**
ptr
;
if
(
UNLIKELY
(
arg
==
NULL
||
arg
->
elements
==
NULL
))
return
FFI_BAD_TYPEDEF
;
arg
->
size
=
0
;
arg
->
alignment
=
0
;
ptr
=
&
(
arg
->
elements
[
0
]);
if
(
UNLIKELY
(
ptr
==
0
))
return
FFI_BAD_TYPEDEF
;
while
((
*
ptr
)
!=
NULL
)
{
if
(
UNLIKELY
(((
*
ptr
)
->
size
==
0
)
&&
(
initialize_aggregate
((
*
ptr
),
NULL
)
!=
FFI_OK
)))
return
FFI_BAD_TYPEDEF
;
/* Perform a sanity check on the argument type */
FFI_ASSERT_VALID_TYPE
(
*
ptr
);
arg
->
size
=
FFI_ALIGN
(
arg
->
size
,
(
*
ptr
)
->
alignment
);
if
(
offsets
)
*
offsets
++
=
arg
->
size
;
arg
->
size
+=
(
*
ptr
)
->
size
;
arg
->
alignment
=
(
arg
->
alignment
>
(
*
ptr
)
->
alignment
)
?
arg
->
alignment
:
(
*
ptr
)
->
alignment
;
ptr
++
;
}
/* Structure size includes tail padding. This is important for
structures that fit in one register on ABIs like the PowerPC64
Linux ABI that right justify small structs in a register.
It's also needed for nested structure layout, for example
struct A { long a; char b; }; struct B { struct A x; char y; };
should find y at an offset of 2*sizeof(long) and result in a
total size of 3*sizeof(long). */
arg
->
size
=
FFI_ALIGN
(
arg
->
size
,
arg
->
alignment
);
/* On some targets, the ABI defines that structures have an additional
alignment beyond the "natural" one based on their elements. */
#ifdef FFI_AGGREGATE_ALIGNMENT
if
(
FFI_AGGREGATE_ALIGNMENT
>
arg
->
alignment
)
arg
->
alignment
=
FFI_AGGREGATE_ALIGNMENT
;
#endif
if
(
arg
->
size
==
0
)
return
FFI_BAD_TYPEDEF
;
else
return
FFI_OK
;
}
#ifndef __CRIS__
/* The CRIS ABI specifies structure elements to have byte
alignment only, so it completely overrides this functions,
which assumes "natural" alignment and padding. */
/* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */
/* For non variadic functions isvariadic should be 0 and
nfixedargs==ntotalargs.
For variadic calls, isvariadic should be 1 and nfixedargs
and ntotalargs set as appropriate. nfixedargs must always be >=1 */
ffi_status
FFI_HIDDEN
ffi_prep_cif_core
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
isvariadic
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
)
{
unsigned
bytes
=
0
;
unsigned
int
i
;
ffi_type
**
ptr
;
FFI_ASSERT
(
cif
!=
NULL
);
FFI_ASSERT
((
!
isvariadic
)
||
(
nfixedargs
>=
1
));
FFI_ASSERT
(
nfixedargs
<=
ntotalargs
);
if
(
!
(
abi
>
FFI_FIRST_ABI
&&
abi
<
FFI_LAST_ABI
))
return
FFI_BAD_ABI
;
cif
->
abi
=
abi
;
cif
->
arg_types
=
atypes
;
cif
->
nargs
=
ntotalargs
;
cif
->
rtype
=
rtype
;
cif
->
flags
=
0
;
#if HAVE_LONG_DOUBLE_VARIANT
ffi_prep_types
(
abi
);
#endif
/* Initialize the return type if necessary */
if
((
cif
->
rtype
->
size
==
0
)
&&
(
initialize_aggregate
(
cif
->
rtype
,
NULL
)
!=
FFI_OK
))
return
FFI_BAD_TYPEDEF
;
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
if
(
rtype
->
type
==
FFI_TYPE_COMPLEX
)
abort
();
#endif
/* Perform a sanity check on the return type */
FFI_ASSERT_VALID_TYPE
(
cif
->
rtype
);
/* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
/* Make space for the return structure pointer */
if
(
cif
->
rtype
->
type
==
FFI_TYPE_STRUCT
#ifdef TILE
&&
(
cif
->
rtype
->
size
>
10
*
FFI_SIZEOF_ARG
)
#endif
#ifdef XTENSA
&&
(
cif
->
rtype
->
size
>
16
)
#endif
#ifdef NIOS2
&&
(
cif
->
rtype
->
size
>
8
)
#endif
)
bytes
=
STACK_ARG_SIZE
(
sizeof
(
void
*
));
#endif
for
(
ptr
=
cif
->
arg_types
,
i
=
cif
->
nargs
;
i
>
0
;
i
--
,
ptr
++
)
{
/* Initialize any uninitialized aggregate type definitions */
if
(((
*
ptr
)
->
size
==
0
)
&&
(
initialize_aggregate
((
*
ptr
),
NULL
)
!=
FFI_OK
))
return
FFI_BAD_TYPEDEF
;
#ifndef FFI_TARGET_HAS_COMPLEX_TYPE
if
((
*
ptr
)
->
type
==
FFI_TYPE_COMPLEX
)
abort
();
#endif
/* Perform a sanity check on the argument type, do this
check after the initialization. */
FFI_ASSERT_VALID_TYPE
(
*
ptr
);
#if !defined FFI_TARGET_SPECIFIC_STACK_SPACE_ALLOCATION
{
/* Add any padding if necessary */
if
(((
*
ptr
)
->
alignment
-
1
)
&
bytes
)
bytes
=
(
unsigned
)
FFI_ALIGN
(
bytes
,
(
*
ptr
)
->
alignment
);
#ifdef TILE
if
(
bytes
<
10
*
FFI_SIZEOF_ARG
&&
bytes
+
STACK_ARG_SIZE
((
*
ptr
)
->
size
)
>
10
*
FFI_SIZEOF_ARG
)
{
/* An argument is never split between the 10 parameter
registers and the stack. */
bytes
=
10
*
FFI_SIZEOF_ARG
;
}
#endif
#ifdef XTENSA
if
(
bytes
<=
6
*
4
&&
bytes
+
STACK_ARG_SIZE
((
*
ptr
)
->
size
)
>
6
*
4
)
bytes
=
6
*
4
;
#endif
bytes
+=
STACK_ARG_SIZE
((
*
ptr
)
->
size
);
}
#endif
}
cif
->
bytes
=
bytes
;
/* Perform machine dependent cif processing */
#ifdef FFI_TARGET_SPECIFIC_VARIADIC
if
(
isvariadic
)
return
ffi_prep_cif_machdep_var
(
cif
,
nfixedargs
,
ntotalargs
);
#endif
return
ffi_prep_cif_machdep
(
cif
);
}
#endif
/* not __CRIS__ */
ffi_status
ffi_prep_cif
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
)
{
return
ffi_prep_cif_core
(
cif
,
abi
,
0
,
nargs
,
nargs
,
rtype
,
atypes
);
}
ffi_status
ffi_prep_cif_var
(
ffi_cif
*
cif
,
ffi_abi
abi
,
unsigned
int
nfixedargs
,
unsigned
int
ntotalargs
,
ffi_type
*
rtype
,
ffi_type
**
atypes
)
{
return
ffi_prep_cif_core
(
cif
,
abi
,
1
,
nfixedargs
,
ntotalargs
,
rtype
,
atypes
);
}
#if FFI_CLOSURES
ffi_status
ffi_prep_closure
(
ffi_closure
*
closure
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
void
**
,
void
*
),
void
*
user_data
)
{
return
ffi_prep_closure_loc
(
closure
,
cif
,
fun
,
user_data
,
closure
);
}
#endif
ffi_status
ffi_get_struct_offsets
(
ffi_abi
abi
,
ffi_type
*
struct_type
,
size_t
*
offsets
)
{
if
(
!
(
abi
>
FFI_FIRST_ABI
&&
abi
<
FFI_LAST_ABI
))
return
FFI_BAD_ABI
;
if
(
struct_type
->
type
!=
FFI_TYPE_STRUCT
)
return
FFI_BAD_TYPEDEF
;
#if HAVE_LONG_DOUBLE_VARIANT
ffi_prep_types
(
abi
);
#endif
return
initialize_aggregate
(
struct_type
,
offsets
);
}
nativehook/src/main/cpp/libffi/raw_api.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
raw_api.c - Copyright (c) 1999, 2008 Red Hat, Inc.
Author: Kresten Krab Thorup <krab@gnu.org>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* This file defines generic functions for use with the raw api. */
#include <ffi.h>
#include <ffi_common.h>
#if !FFI_NO_RAW_API
size_t
ffi_raw_size
(
ffi_cif
*
cif
)
{
size_t
result
=
0
;
int
i
;
ffi_type
**
at
=
cif
->
arg_types
;
for
(
i
=
cif
->
nargs
-
1
;
i
>=
0
;
i
--
,
at
++
)
{
#if !FFI_NO_STRUCTS
if
((
*
at
)
->
type
==
FFI_TYPE_STRUCT
)
result
+=
FFI_ALIGN
(
sizeof
(
void
*
),
FFI_SIZEOF_ARG
);
else
#endif
result
+=
FFI_ALIGN
((
*
at
)
->
size
,
FFI_SIZEOF_ARG
);
}
return
result
;
}
void
ffi_raw_to_ptrarray
(
ffi_cif
*
cif
,
ffi_raw
*
raw
,
void
**
args
)
{
unsigned
i
;
ffi_type
**
tp
=
cif
->
arg_types
;
#if WORDS_BIGENDIAN
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
switch
((
*
tp
)
->
type
)
{
case
FFI_TYPE_UINT8
:
case
FFI_TYPE_SINT8
:
*
args
=
(
void
*
)
((
char
*
)(
raw
++
)
+
FFI_SIZEOF_ARG
-
1
);
break
;
case
FFI_TYPE_UINT16
:
case
FFI_TYPE_SINT16
:
*
args
=
(
void
*
)
((
char
*
)(
raw
++
)
+
FFI_SIZEOF_ARG
-
2
);
break
;
#if FFI_SIZEOF_ARG >= 4
case
FFI_TYPE_UINT32
:
case
FFI_TYPE_SINT32
:
*
args
=
(
void
*
)
((
char
*
)(
raw
++
)
+
FFI_SIZEOF_ARG
-
4
);
break
;
#endif
#if !FFI_NO_STRUCTS
case
FFI_TYPE_STRUCT
:
*
args
=
(
raw
++
)
->
ptr
;
break
;
#endif
case
FFI_TYPE_COMPLEX
:
*
args
=
(
raw
++
)
->
ptr
;
break
;
case
FFI_TYPE_POINTER
:
*
args
=
(
void
*
)
&
(
raw
++
)
->
ptr
;
break
;
default:
*
args
=
raw
;
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
FFI_SIZEOF_ARG
)
/
FFI_SIZEOF_ARG
;
}
}
#else
/* WORDS_BIGENDIAN */
#if !PDP
/* then assume little endian */
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
#if !FFI_NO_STRUCTS
if
((
*
tp
)
->
type
==
FFI_TYPE_STRUCT
)
{
*
args
=
(
raw
++
)
->
ptr
;
}
else
#endif
if
((
*
tp
)
->
type
==
FFI_TYPE_COMPLEX
)
{
*
args
=
(
raw
++
)
->
ptr
;
}
else
{
*
args
=
(
void
*
)
raw
;
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
sizeof
(
void
*
))
/
sizeof
(
void
*
);
}
}
#else
#error "pdp endian not supported"
#endif
/* ! PDP */
#endif
/* WORDS_BIGENDIAN */
}
void
ffi_ptrarray_to_raw
(
ffi_cif
*
cif
,
void
**
args
,
ffi_raw
*
raw
)
{
unsigned
i
;
ffi_type
**
tp
=
cif
->
arg_types
;
for
(
i
=
0
;
i
<
cif
->
nargs
;
i
++
,
tp
++
,
args
++
)
{
switch
((
*
tp
)
->
type
)
{
case
FFI_TYPE_UINT8
:
(
raw
++
)
->
uint
=
*
(
UINT8
*
)
(
*
args
);
break
;
case
FFI_TYPE_SINT8
:
(
raw
++
)
->
sint
=
*
(
SINT8
*
)
(
*
args
);
break
;
case
FFI_TYPE_UINT16
:
(
raw
++
)
->
uint
=
*
(
UINT16
*
)
(
*
args
);
break
;
case
FFI_TYPE_SINT16
:
(
raw
++
)
->
sint
=
*
(
SINT16
*
)
(
*
args
);
break
;
#if FFI_SIZEOF_ARG >= 4
case
FFI_TYPE_UINT32
:
(
raw
++
)
->
uint
=
*
(
UINT32
*
)
(
*
args
);
break
;
case
FFI_TYPE_SINT32
:
(
raw
++
)
->
sint
=
*
(
SINT32
*
)
(
*
args
);
break
;
#endif
#if !FFI_NO_STRUCTS
case
FFI_TYPE_STRUCT
:
(
raw
++
)
->
ptr
=
*
args
;
break
;
#endif
case
FFI_TYPE_COMPLEX
:
(
raw
++
)
->
ptr
=
*
args
;
break
;
case
FFI_TYPE_POINTER
:
(
raw
++
)
->
ptr
=
**
(
void
***
)
args
;
break
;
default:
memcpy
((
void
*
)
raw
->
data
,
(
void
*
)
*
args
,
(
*
tp
)
->
size
);
raw
+=
FFI_ALIGN
((
*
tp
)
->
size
,
FFI_SIZEOF_ARG
)
/
FFI_SIZEOF_ARG
;
}
}
}
#if !FFI_NATIVE_RAW_API
/* This is a generic definition of ffi_raw_call, to be used if the
* native system does not provide a machine-specific implementation.
* Having this, allows code to be written for the raw API, without
* the need for system-specific code to handle input in that format;
* these following couple of functions will handle the translation forth
* and back automatically. */
void
ffi_raw_call
(
ffi_cif
*
cif
,
void
(
*
fn
)(
void
),
void
*
rvalue
,
ffi_raw
*
raw
)
{
void
**
avalue
=
(
void
**
)
alloca
(
cif
->
nargs
*
sizeof
(
void
*
));
ffi_raw_to_ptrarray
(
cif
,
raw
,
avalue
);
ffi_call
(
cif
,
fn
,
rvalue
,
avalue
);
}
#if FFI_CLOSURES
/* base system provides closures */
static
void
ffi_translate_args
(
ffi_cif
*
cif
,
void
*
rvalue
,
void
**
avalue
,
void
*
user_data
)
{
ffi_raw
*
raw
=
(
ffi_raw
*
)
alloca
(
ffi_raw_size
(
cif
));
ffi_raw_closure
*
cl
=
(
ffi_raw_closure
*
)
user_data
;
ffi_ptrarray_to_raw
(
cif
,
avalue
,
raw
);
(
*
cl
->
fun
)
(
cif
,
rvalue
,
raw
,
cl
->
user_data
);
}
ffi_status
ffi_prep_raw_closure_loc
(
ffi_raw_closure
*
cl
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
,
void
*
codeloc
)
{
ffi_status
status
;
status
=
ffi_prep_closure_loc
((
ffi_closure
*
)
cl
,
cif
,
&
ffi_translate_args
,
codeloc
,
codeloc
);
if
(
status
==
FFI_OK
)
{
cl
->
fun
=
fun
;
cl
->
user_data
=
user_data
;
}
return
status
;
}
#endif
/* FFI_CLOSURES */
#endif
/* !FFI_NATIVE_RAW_API */
#if FFI_CLOSURES
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_raw_closure
(
ffi_raw_closure
*
cl
,
ffi_cif
*
cif
,
void
(
*
fun
)(
ffi_cif
*
,
void
*
,
ffi_raw
*
,
void
*
),
void
*
user_data
)
{
return
ffi_prep_raw_closure_loc
(
cl
,
cif
,
fun
,
user_data
,
cl
);
}
#endif
/* FFI_CLOSURES */
#endif
/* !FFI_NO_RAW_API */
nativehook/src/main/cpp/libffi/types.c
0 → 100755
View file @
10c7897b
/* -----------------------------------------------------------------------
types.c - Copyright (c) 1996, 1998 Red Hat, Inc.
Predefined ffi_types needed by libffi.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
/* Hide the basic type definitions from the header file, so that we
can redefine them here as "const". */
#define LIBFFI_HIDE_BASIC_TYPES
#include <ffi.h>
#include <ffi_common.h>
/* Type definitions */
#define FFI_TYPEDEF(name, type, id, maybe_const)\
struct struct_align_##name { \
char c; \
type x; \
}; \
FFI_EXTERN \
maybe_const ffi_type ffi_type_##name = { \
sizeof(type), \
offsetof(struct struct_align_##name, x), \
id, NULL \
}
#define FFI_COMPLEX_TYPEDEF(name, type, maybe_const) \
static ffi_type *ffi_elements_complex_##name [2] = { \
(ffi_type *)(&ffi_type_##name), NULL \
}; \
struct struct_align_complex_##name { \
char c; \
_Complex type x; \
}; \
FFI_EXTERN \
maybe_const ffi_type ffi_type_complex_##name = { \
sizeof(_Complex type), \
offsetof(struct struct_align_complex_##name, x), \
FFI_TYPE_COMPLEX, \
(ffi_type **)ffi_elements_complex_##name \
}
/* Size and alignment are fake here. They must not be 0. */
FFI_EXTERN
const
ffi_type
ffi_type_void
=
{
1
,
1
,
FFI_TYPE_VOID
,
NULL
};
FFI_TYPEDEF
(
uint8
,
UINT8
,
FFI_TYPE_UINT8
,
const
);
FFI_TYPEDEF
(
sint8
,
SINT8
,
FFI_TYPE_SINT8
,
const
);
FFI_TYPEDEF
(
uint16
,
UINT16
,
FFI_TYPE_UINT16
,
const
);
FFI_TYPEDEF
(
sint16
,
SINT16
,
FFI_TYPE_SINT16
,
const
);
FFI_TYPEDEF
(
uint32
,
UINT32
,
FFI_TYPE_UINT32
,
const
);
FFI_TYPEDEF
(
sint32
,
SINT32
,
FFI_TYPE_SINT32
,
const
);
FFI_TYPEDEF
(
uint64
,
UINT64
,
FFI_TYPE_UINT64
,
const
);
FFI_TYPEDEF
(
sint64
,
SINT64
,
FFI_TYPE_SINT64
,
const
);
FFI_TYPEDEF
(
pointer
,
void
*
,
FFI_TYPE_POINTER
,
const
);
FFI_TYPEDEF
(
float
,
float
,
FFI_TYPE_FLOAT
,
const
);
FFI_TYPEDEF
(
double
,
double
,
FFI_TYPE_DOUBLE
,
const
);
#if !defined HAVE_LONG_DOUBLE_VARIANT || defined __alpha__
#define FFI_LDBL_CONST const
#else
#define FFI_LDBL_CONST
#endif
#ifdef __alpha__
/* Even if we're not configured to default to 128-bit long double,
maintain binary compatibility, as -mlong-double-128 can be used
at any time. */
/* Validate the hard-coded number below. */
# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
const
ffi_type
ffi_type_longdouble
=
{
16
,
16
,
4
,
NULL
};
#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
FFI_TYPEDEF
(
longdouble
,
long
double
,
FFI_TYPE_LONGDOUBLE
,
FFI_LDBL_CONST
);
#endif
#ifdef FFI_TARGET_HAS_COMPLEX_TYPE
FFI_COMPLEX_TYPEDEF
(
float
,
float
,
const
);
FFI_COMPLEX_TYPEDEF
(
double
,
double
,
const
);
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
FFI_COMPLEX_TYPEDEF
(
longdouble
,
long
double
,
FFI_LDBL_CONST
);
#endif
#endif
nativehook/src/main/cpp/sandhook_native.cpp
View file @
10c7897b
...
@@ -3,6 +3,8 @@
...
@@ -3,6 +3,8 @@
//
//
#include <jni.h>
#include <jni.h>
#include <log.h>
#include <unistd.h>
#include "sandhook_native.h"
#include "sandhook_native.h"
#include "hook.h"
#include "hook.h"
#include "elf.h"
#include "elf.h"
...
@@ -10,6 +12,191 @@
...
@@ -10,6 +12,191 @@
using
namespace
SandHook
::
Hook
;
using
namespace
SandHook
::
Hook
;
using
namespace
SandHook
::
Elf
;
using
namespace
SandHook
::
Elf
;
int
m1
=
5
;
int
m3
=
1036
;
int
m2
=
1035
;
int
m4
=
5
;
void
(
*
dosth3Backup
)(
int
,
int
)
=
nullptr
;
void
(
*
dosth4Backup
)()
=
nullptr
;
void
(
*
dosth4Backup2
)()
=
nullptr
;
void
(
*
innerSuspendVM
)()
=
nullptr
;
static
void
(
*
heapPreForkBackup
)(
void
*
)
=
nullptr
;
static
void
myHeapPreFork
(
void
*
heap
)
{
heapPreForkBackup
(
heap
);
}
void
SuspendVMReplace
()
{
LOGE
(
"VM Suspend!"
);
innerSuspendVM
();
}
void
do2
()
{
int
a
=
1
+
1
;
int
b
=
1
+
1
;
int
c
=
1
+
1
;
int
d
=
1
+
1
;
}
void
do3
(
int
x
,
int
y
)
{
do2
();
int
a
=
1
+
1
;
int
b
=
1
+
1
;
int
c
=
1
+
1
;
int
d
=
a
+
b
+
c
;
LOGE
(
"do3 = %d"
,
y
);
}
void
do5
()
{
LOGE
(
"x = %d"
,
5
);
}
void
do4
()
{
int
a
=
1
+
1
;
int
b
=
a
+
1
;
int
d
=
a
+
1
;
int
e
=
a
+
1
;
}
static
std
::
atomic_int
count
;
void
do4replace
()
{
LOGE
(
"do4replace :%d"
,
count
++
);
int
a
=
1
+
1
;
int
b
=
1
+
1
;
int
c
=
1
+
1
;
int
d
=
1
+
1
;
dosth4Backup
();
}
void
do4replace2
()
{
int
a
=
1
+
1
;
int
c
=
1
+
1
;
int
d
=
1
+
1
;
dosth4Backup2
();
}
void
do3replace
(
int
x
,
int
y
)
{
int
a
=
1
+
1
;
int
b
=
1
+
1
;
int
c
=
1
+
1
;
int
d
=
1
+
1
;
dosth3Backup
(
x
,
y
);
}
void
do1
()
{
do2
();
}
void
breakCallback
(
REG
regs
[])
{
LOGE
(
"breakCallback = %d SP = %d"
,
regs
[
0
],
regs
);
}
class
Visitor
:
public
InstVisitor
{
bool
Visit
(
Unit
<
Base
>
*
unit
,
void
*
pc
)
override
{
BaseInst
*
instruction
=
reinterpret_cast
<
BaseInst
*>
(
unit
);
instruction
->
Assemble
();
return
true
;
}
};
static
void
*
ThreadEntry2
(
void
*
arg
)
{
while
(
true
)
{
*
(
int
*
)(
0
)
=
1
;
LOGE
(
"ThreadEntry2"
);
}
LOGE
(
"ThreadEntry2"
);
return
nullptr
;
}
static
void
*
ThreadEntry
(
void
*
arg
)
{
pthread_t
pthread_ptr_
;
pthread_attr_t
attr
;
pthread_attr_init
(
&
attr
);
pthread_attr_setstacksize
(
&
attr
,
1024
*
128
);
pthread_create
(
&
pthread_ptr_
,
&
attr
,
ThreadEntry2
,
nullptr
);
while
(
true
)
{
*
(
int
*
)(
0
)
=
1
;
LOGE
(
"ThreadEntry1"
);
}
return
nullptr
;
}
std
::
atomic_bool
inited
;
static
void
callback
()
{
if
(
inited
)
return
;
inited
=
true
;
pthread_t
pthread_ptr_
;
pthread_attr_t
attr
;
pthread_attr_init
(
&
attr
);
pthread_attr_setstacksize
(
&
attr
,
1024
*
128
);
pthread_create
(
&
pthread_ptr_
,
&
attr
,
ThreadEntry
,
nullptr
);
}
typedef
enum
{
SP_DEFAULT
=
-
1
,
SP_BACKGROUND
=
0
,
SP_FOREGROUND
=
1
,
SP_SYSTEM
=
2
,
// can't be used with set_sched_policy()
SP_AUDIO_APP
=
3
,
SP_AUDIO_SYS
=
4
,
SP_TOP_APP
=
5
,
SP_RT_APP
=
6
,
SP_RESTRICTED
=
7
,
SP_CNT
,
SP_MAX
=
SP_CNT
-
1
,
SP_SYSTEM_DEFAULT
=
SP_FOREGROUND
,
}
SchedPolicy
;
extern
"C"
JNIEXPORT
void
JNICALL
Java_com_swift_sandhook_nativehook_NativeHook_test
(
JNIEnv
*
env
,
jclass
jclass1
)
{
// dosth4Backup = reinterpret_cast<void (*)()>(InlineHook::instance->SingleInstHook(
// reinterpret_cast<void *>(do4),
// reinterpret_cast<void *>(do4replace)));
//
// InlineHook::instance->callback = callback;
//
//
// do4();
//
// if (sizeof(void*) == 8) {
// heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandSingleInstHookSym("/system/lib64/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
// reinterpret_cast<void *>(myHeapPreFork)));
// innerSuspendVM = reinterpret_cast<void (*)()>(SandSingleInstHookSym("/system/lib64/libart.so", "_ZN3art3Dbg9SuspendVMEv",
// reinterpret_cast<void *>(SuspendVMReplace)));
// } else {
// heapPreForkBackup = reinterpret_cast<void (*)(void *)>(SandSingleInstHookSym("/system/lib/libart.so", "_ZN3art2gc4Heap13PreZygoteForkEv",
// reinterpret_cast<void *>(myHeapPreFork)));
// innerSuspendVM = reinterpret_cast<void (*)()>(SandSingleInstHookSym("/system/lib/libart.so", "_ZN3art3Dbg9SuspendVMEv",
// reinterpret_cast<void *>(SuspendVMReplace)));
// }
//
// void* do3P = reinterpret_cast<void *>(do3);
//
// InlineHook::instance->BreakPoint(reinterpret_cast<void *>((Addr)do3), breakCallback);
//
// LOGE("ok");
//
// do3(100, 2);
}
extern
"C"
extern
"C"
EXPORT
void
*
SandGetSym
(
const
char
*
so
,
const
char
*
symb
)
{
EXPORT
void
*
SandGetSym
(
const
char
*
so
,
const
char
*
symb
)
{
ElfImg
elfImg
(
so
);
ElfImg
elfImg
(
so
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment