Skip to content

Commit de84d5a

Browse files
jiaqizhotuhaihe
authored andcommitted
PAX: replace cpp-stub submodule with local sources
During the IPMC release review, bundled .a binary files were found in the cpp-stub git submodule. These violate ASF policy, which prohibits including prebuilt binaries in source releases. To resolve this, we removed the cpp-stub submodule and copied only the required source files into the repository as a subdirectory. This ensures compliance with ASF release requirements. Source upstream commit: coolxv/cpp-stub@2ec4837 See: #1237
1 parent 868c469 commit de84d5a

File tree

14 files changed

+6110
-8
lines changed

14 files changed

+6110
-8
lines changed

.gitmodules

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
[submodule "contrib/pax_storage/src/cpp/contrib/googlebench"]
1212
path = contrib/pax_storage/src/cpp/contrib/googlebench
1313
url = https://github.com/google/benchmark.git
14-
[submodule "contrib/pax_storage/src/cpp/contrib/cpp-stub"]
15-
path = contrib/pax_storage/src/cpp/contrib/cpp-stub
16-
url = https://github.com/coolxv/cpp-stub.git
1714
[submodule "dependency/yyjson"]
1815
path = dependency/yyjson
1916
url = https://github.com/ibireme/yyjson.git
Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.ccls-cache
2+
replit*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 coolxv
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
![building and running workflow](https://github.com/coolxv/cpp-stub/actions/workflows/make-test-multi-platform.yml/badge.svg)
2+
3+
[中文](README_zh.md)|[English](README.md)
4+
5+
# Principle
6+
- How to get the original function address (**addr_pri.h**, **addr_any.h**)
7+
- How to replace the original function with stub function (**stub.h**)
8+
9+
# Supported
10+
- Supported operating systems:
11+
* [x] Windows
12+
* [x] Linux
13+
* [x] MacOS(x86-64, printf '\x07' | dd of=test_function bs=1 seek=160 count=1 conv=notrunc)
14+
- Supported hardware platform:
15+
* [x] x86
16+
* [x] x86-64
17+
* [x] arm32
18+
* [x] arm64
19+
* [x] arm thumb
20+
* [x] riscv32
21+
* [x] riscv64
22+
* [x] loongarch64
23+
* [x] mips64
24+
* [x] ppc64 (Generated by chatgpt and requires verification)
25+
* [x] s390x (Generated by chatgpt and requires verification)
26+
* [x] alpha (Generated by chatgpt and requires verification)
27+
* [x] sparc (Generated by chatgpt and requires verification)
28+
* [x] sw_64 (Generated by chatgpt and requires verification)
29+
- Supported compiler:
30+
* [x] msvc
31+
* [x] gcc
32+
* [x] clang
33+
- Support function type:
34+
* [x] [normal function](test/test_function.cpp)
35+
* [x] [variadic function]((test/test_variadic_function.cpp))
36+
* [x] [template function](test/test_template_function_linux.cpp)
37+
* [x] [overload function](test/test_overload_function_linux.cpp)
38+
* [x] [lambda](test/test_addr_lambda_linux.cpp)
39+
* [x] [static function(use addr_any.h)](test/test_addr_any_linux.cpp)
40+
* [x] inline function(use compiler options)
41+
* [x] [constructor function](test/test_constructor_function_linux.cpp)
42+
* [x] [destructor function](test/test_dtor_function_linux.cpp)
43+
* [x] [member function](test/test_object_member_function_linux.cpp)
44+
* [x] [static member function](test/test_class_member_function.cpp)
45+
* [x] [virtual function(not pure)](test/test_virtual_function_linux.cpp)
46+
* [x] [virtual and overload function](test/test_virtual_overload_function_linux.cpp)
47+
* [x] [functor](test/test_functor_linux.cpp)
48+
* [x] [private member function(use addr_pri.h)](test/test_private_member_function_linux.cpp)
49+
* [x] [private member function(cpp17)](test_cpp17/test_private_member.cpp)
50+
51+
52+
53+
54+
# Description of the unit test
55+
## Cannot stub
56+
- Can't stub the exit function, the compiler has made special optimizations.
57+
- Can't stub pure virtual functions, pure virtual functions not have the address.
58+
- Can't stub lambda functions, lambda functions not get the address.(You can try to use addr_any.h api.)
59+
- Can't stub static functions, static function address is not visible.(You can try to use addr_any.h api.)
60+
61+
62+
## Unit test compilation option for linux g++
63+
- -fno-access-control
64+
- -fno-inline
65+
- -Wno-pmf-conversions
66+
- -Wl,--allow-multiple-definition
67+
- -no-pie -fno-stack-protector
68+
- -fprofile-arcs
69+
- -ftest-coverage
70+
71+
## Code coverage statistics for linux g++
72+
```
73+
lcov -d build/ -z
74+
lcov -d build/ -b ../../src1 --no-external -rc lcov_branch_coverage=1 -t ut -c -o ut_1.info
75+
lcov -d build/ -b ../../src2 --no-external -rc lcov_branch_coverage=1 -t ut -c -o ut_2.info
76+
lcov -a ut_1.info -a ut_2.info -o ut.info
77+
genhtml -o report/ --prefix=`pwd` --branch-coverage --function-coverage ut.info
78+
```
79+
## Code coverage statistics for windows
80+
81+
[OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage)
82+
```
83+
OpenCppCoverage.exe --sources MySourcePath* -- YourProgram.exe arg1 arg2
84+
```
85+
# Interface description
86+
87+
## stub.h
88+
```
89+
Stub stub
90+
stub.set(addr, addr_stub)
91+
stub.reset(addr)
92+
```
93+
94+
## addr_pri.h
95+
```
96+
Declaration:
97+
ACCESS_PRIVATE_FIELD(ClassName, TypeName, FieldName)
98+
ACCESS_PRIVATE_FUN(ClassName, TypeName, FunName)
99+
ACCESS_PRIVATE_STATIC_FIELD(ClassName, TypeName, FieldName)
100+
ACCESS_PRIVATE_STATIC_FUN(ClassName, TypeName, FunName)
101+
102+
Use:
103+
access_private_field::ClassNameFieldName(object);
104+
access_private_static_field::ClassName::ClassNameFieldName();
105+
call_private_fun::ClassNameFunName(object,parameters...);
106+
call_private_static_fun::ClassName::ClassNameFunName(parameters...);
107+
get_private_fun::ClassNameFunName();
108+
get_private_static_fun::ClassName::ClassNameFunName();
109+
```
110+
111+
## addr_any.h(linux)
112+
```
113+
AddrAny any //for exe
114+
AddrAny any(libname) //for lib
115+
116+
int get_local_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
117+
int get_global_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
118+
int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
119+
120+
int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map<std::string,void*>& result)
121+
int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map<std::string,void*>& result)
122+
123+
```
124+
## addr_any.h(windows)
125+
```
126+
AddrAny any //for all
127+
int get_func_addr(std::string func_name, std::map<std::string,void*>& result)
128+
```
129+
## addr_any.h(darwin)
130+
```
131+
not implement
132+
```
133+
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#ifndef __ADDR_PRI_H__
2+
#define __ADDR_PRI_H__
3+
4+
5+
#include <utility>
6+
#include <type_traits>
7+
8+
9+
10+
//base on C++11
11+
12+
/**********************************************************
13+
access private function
14+
**********************************************************/
15+
16+
17+
namespace std {
18+
template <bool B, class T = void>
19+
using enable_if_t = typename enable_if<B, T>::type;
20+
template <class T>
21+
using remove_reference_t = typename remove_reference<T>::type;
22+
} // std
23+
24+
// Unnamed namespace is used to avoid duplicate symbols if the macros are used
25+
namespace {
26+
namespace private_access_detail {
27+
28+
// @tparam TagType, used to declare different "get" funciton overloads for
29+
// different members/statics
30+
template <typename PtrType, PtrType PtrValue, typename TagType>
31+
struct private_access {
32+
// Normal lookup cannot find in-class defined (inline) friend functions.
33+
friend PtrType get(TagType) { return PtrValue; }
34+
};
35+
36+
} // namespace private_access_detail
37+
} // namespace
38+
39+
// Used macro naming conventions:
40+
// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all
41+
// macro here has this prefix.
42+
// All implementation macro, which are not meant to be used directly have the
43+
// PRIVATE_ACCESS_DETAIL prefix.
44+
// Some macros have the ABCD_IMPL form, which means they contain the
45+
// implementation details for the specific ABCD macro.
46+
47+
#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y
48+
#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y) \
49+
PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y)
50+
51+
// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of
52+
// members, or it can be "*" in case of statics.
53+
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, \
54+
PtrTypeKind) \
55+
namespace { \
56+
namespace private_access_detail { \
57+
/* Tag type, used to declare different get funcitons for different \
58+
* members \
59+
*/ \
60+
struct Tag {}; \
61+
/* Explicit instantiation */ \
62+
template struct private_access<decltype(&Class::Name), &Class::Name, \
63+
Tag>; \
64+
/* We can build the PtrType only with two aliases */ \
65+
/* E.g. using PtrType = int(int) *; would be illformed */ \
66+
using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type; \
67+
using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) = \
68+
PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind; \
69+
/* Declare the friend function, now it is visible in namespace scope. \
70+
* Note, \
71+
* we could declare it inside the Tag type too, in that case ADL would \
72+
* find \
73+
* the declaration. By choosing to declare it here, the Tag type remains \
74+
* a \
75+
* simple tag type, it has no other responsibilities. */ \
76+
PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag); \
77+
} \
78+
}
79+
80+
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name) \
81+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \
82+
namespace { \
83+
namespace access_private_field { \
84+
Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); } \
85+
Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); } \
86+
/* The following usings are here to avoid duplicate const qualifier \
87+
* warnings \
88+
*/ \
89+
using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type; \
90+
using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) = \
91+
const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag); \
92+
PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\
93+
return t.*get(private_access_detail::Tag{}); \
94+
} \
95+
} \
96+
}
97+
98+
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name) \
99+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*) \
100+
namespace { \
101+
namespace call_private_fun { \
102+
/* We do perfect forwarding, but we want to restrict the overload set \
103+
* only for objects which have the type Class. */ \
104+
template <typename Obj, \
105+
std::enable_if_t<std::is_same<std::remove_reference_t<Obj>, \
106+
Class>::value> * = nullptr, \
107+
typename... Args> \
108+
auto Class##Name(Obj &&o, Args &&... args) -> decltype( \
109+
(std::forward<Obj>(o).* \
110+
get(private_access_detail::Tag{}))(std::forward<Args>(args)...)) { \
111+
return (std::forward<Obj>(o).*get(private_access_detail::Tag{}))( \
112+
std::forward<Args>(args)...); \
113+
} \
114+
} \
115+
namespace get_private_fun { \
116+
auto Class##Name() -> decltype( \
117+
get(private_access_detail::Tag{})) { \
118+
return (get(private_access_detail::Tag{})); \
119+
} \
120+
} \
121+
}
122+
123+
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type, \
124+
Name) \
125+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \
126+
namespace { \
127+
namespace access_private_static_field { \
128+
namespace Class { \
129+
Type &Class##Name() { return *get(private_access_detail::Tag{}); } \
130+
} \
131+
} \
132+
}
133+
134+
#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type, \
135+
Name) \
136+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *) \
137+
namespace { \
138+
namespace call_private_static_fun { \
139+
namespace Class { \
140+
template <typename... Args> \
141+
auto Class##Name(Args &&... args) -> decltype( \
142+
get(private_access_detail::Tag{})(std::forward<Args>(args)...)) { \
143+
return get(private_access_detail::Tag{})( \
144+
std::forward<Args>(args)...); \
145+
} \
146+
} \
147+
} \
148+
namespace get_private_static_fun { \
149+
namespace Class { \
150+
auto Class##Name() -> decltype(get(private_access_detail::Tag{})) { \
151+
return get(private_access_detail::Tag{}); \
152+
} \
153+
} \
154+
} \
155+
}
156+
157+
#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG \
158+
PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__)
159+
160+
#define ACCESS_PRIVATE_FIELD(Class, Type, Name) \
161+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \
162+
Class, Type, Name)
163+
164+
#define ACCESS_PRIVATE_FUN(Class, Type, Name) \
165+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \
166+
Class, Type, Name)
167+
168+
#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name) \
169+
Type Class::Name; \
170+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD( \
171+
PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
172+
173+
#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name) \
174+
PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN( \
175+
PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
176+
177+
#endif

0 commit comments

Comments
 (0)