Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit e2781f8

Browse files
author
Sarah Jelinek
authored
Merge pull request #44 from GBuella/static_test
Fix static library
2 parents d263de2 + 468f0aa commit e2781f8

File tree

8 files changed

+132
-63
lines changed

8 files changed

+132
-63
lines changed

CMakeLists.txt

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3030
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131

32-
cmake_minimum_required(VERSION 2.8.7)
32+
cmake_minimum_required(VERSION 3.3)
3333
project(syscall_intercept C CXX ASM)
3434

3535
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
@@ -60,7 +60,7 @@ include(GNUInstallDirs)
6060
include(cmake/toolchain_features.cmake)
6161
include(cmake/find_capstone.cmake)
6262

63-
# main source files - intentionally excluding src/entry.c
63+
# main source files - intentionally excluding src/cmdline_filter.c
6464
set(SOURCES_C
6565
src/disasm_wrapper.c
6666
src/intercept.c
@@ -83,8 +83,9 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)
8383
# can use the internal interface of the libraries (linking
8484
# with syscall_intercept_base instead of the actual lib ), without
8585
# the library trying to hotpatch libc every time.
86-
add_library(syscall_intercept_base_c STATIC ${SOURCES_C})
87-
add_library(syscall_intercept_base_asm STATIC ${SOURCES_ASM})
86+
add_library(syscall_intercept_base_c OBJECT ${SOURCES_C})
87+
add_library(syscall_intercept_base_asm OBJECT ${SOURCES_ASM})
88+
add_library(syscall_intercept_base_clf OBJECT src/cmdline_filter.c)
8889

8990
if(HAS_NOUNUSEDARG)
9091
target_compile_options(syscall_intercept_base_asm BEFORE
@@ -94,36 +95,42 @@ endif()
9495
set_property(TARGET syscall_intercept_base_c
9596
APPEND PROPERTY COMPILE_FLAGS ${capstone_CFLAGS})
9697

97-
target_link_libraries(syscall_intercept_base_c
98-
${CMAKE_DL_LIBS} ${capstone_LIBRARIES})
98+
add_library(syscall_intercept_unscoped STATIC
99+
$<TARGET_OBJECTS:syscall_intercept_base_c>
100+
$<TARGET_OBJECTS:syscall_intercept_base_asm>
101+
$<TARGET_OBJECTS:syscall_intercept_base_clf>)
102+
103+
set(syscall_intercept_unscoped_a $<TARGET_FILE:syscall_intercept_unscoped>)
104+
105+
add_custom_command(
106+
OUTPUT syscall_intercept_scoped.o
107+
COMMAND ${CMAKE_LINKER}
108+
-r --whole-archive ${syscall_intercept_unscoped_a}
109+
-o syscall_intercept_scoped.o
110+
COMMAND ${CMAKE_OBJCOPY} --localize-hidden syscall_intercept_scoped.o
111+
COMMENT "Hiding symbols")
112+
113+
add_library(syscall_intercept_shared SHARED syscall_intercept_scoped.o)
114+
add_library(syscall_intercept_static STATIC syscall_intercept_scoped.o)
115+
116+
set_target_properties(syscall_intercept_base_c
117+
PROPERTIES C_VISIBILITY_PRESET hidden)
99118

100-
add_library(syscall_intercept_shared SHARED src/entry.c)
101119
target_link_libraries(syscall_intercept_shared
102-
syscall_intercept_base_c syscall_intercept_base_asm)
103-
add_library(syscall_intercept_static STATIC src/entry.c)
120+
PRIVATE ${CMAKE_DL_LIBS} ${capstone_LIBRARIES})
121+
104122
target_link_libraries(syscall_intercept_static
105-
syscall_intercept_base_c syscall_intercept_base_asm)
123+
INTERFACE ${CMAKE_DL_LIBS} ${capstone_LIBRARIES})
106124

107125
set_target_properties(syscall_intercept_shared
108126
PROPERTIES VERSION ${SYSCALL_INTERCEPT_VERSION}
109127
SOVERSION ${SYSCALL_INTERCEPT_VERSION_MAJOR})
110128

111129
add_executable(cpp_test src/cpp_compile_test.cc src/cpp_compile_mock.c)
112130

113-
if(CMAKE_OBJCOPY)
114-
foreach(target syscall_intercept_shared syscall_intercept_static)
115-
add_custom_command(TARGET ${target}
116-
POST_BUILD COMMAND ${CMAKE_OBJCOPY}
117-
--localize-hidden
118-
-G intercept_hook_point
119-
-G syscall_no_intercept
120-
-G libc_hook_in_process_allowed
121-
$<TARGET_FILE:${target}>)
122-
endforeach()
123-
endif()
124-
125131
set_target_properties(syscall_intercept_shared syscall_intercept_static
126132
PROPERTIES
133+
LINKER_LANGUAGE C
127134
PUBLIC_HEADER "include/libsyscall_intercept_hook_point.h"
128135
OUTPUT_NAME syscall_intercept)
129136

src/entry.c renamed to src/cmdline_filter.c

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3131
*/
3232

33-
/*
34-
* entry.c -- the entry point for libsyscall_intercept
35-
* expected to be executed by the loader while using LD_PRELOAD
36-
*/
37-
3833
#include <stdbool.h>
3934
#include <stdlib.h>
4035
#include <string.h>
@@ -45,28 +40,6 @@
4540
#include "libsyscall_intercept_hook_point.h"
4641
#include "intercept.h"
4742

48-
static const char *cmdline;
49-
50-
/*
51-
* entry_point - the main entry point for syscall_intercept
52-
*
53-
* The loader calls this routine once the library is loaded, except in certain
54-
* cases when testing -- see asm_wrapper.c for more details.
55-
* The actual work of hotpatching libraries is done the routine
56-
* called intercept.
57-
*/
58-
static __attribute__((constructor)) void
59-
entry_point(int argc, char **argv)
60-
{
61-
if (argc < 1)
62-
return;
63-
64-
cmdline = argv[0];
65-
66-
if (syscall_hook_in_process_allowed())
67-
intercept();
68-
}
69-
7043
/*
7144
* cmdline_match - match the last component of the path in cmdline
7245
*/
@@ -112,6 +85,9 @@ syscall_hook_in_process_allowed(void)
11285
if (is_decided)
11386
return result;
11487

88+
if (cmdline == NULL)
89+
return 0;
90+
11591
result = cmdline_match(getenv("INTERCEPT_HOOK_CMDLINE_FILTER"));
11692
is_decided = true;
11793

src/intercept.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,11 @@ int (*intercept_hook_point)(long syscall_number,
6363
long arg0, long arg1,
6464
long arg2, long arg3,
6565
long arg4, long arg5,
66-
long *result);
66+
long *result)
67+
__attribute__((visibility("default")));
6768

68-
void (*intercept_hook_point_clone_child)(void);
69+
void (*intercept_hook_point_clone_child)(void)
70+
__attribute__((visibility("default")));
6971

7072
bool debug_dumps_on;
7173

@@ -306,7 +308,15 @@ is_vdso(uintptr_t addr, const char *path)
306308
static bool
307309
should_patch_object(uintptr_t addr, const char *path)
308310
{
309-
static const char self[] = "libsyscall_intercept";
311+
static uintptr_t self_addr;
312+
if (self_addr == 0) {
313+
extern unsigned char intercept_asm_wrapper_tmpl[];
314+
Dl_info self;
315+
if (!dladdr((void *)&intercept_asm_wrapper_tmpl, &self))
316+
xabort("self dladdr failure");
317+
self_addr = (uintptr_t)self.dli_fbase;
318+
}
319+
310320
static const char libc[] = "libc";
311321
static const char pthr[] = "libpthread";
312322
static const char caps[] = "libcapstone";
@@ -322,7 +332,7 @@ should_patch_object(uintptr_t addr, const char *path)
322332
if (len == 0)
323333
return false;
324334

325-
if (str_match(name, len, self)) {
335+
if (addr == self_addr) {
326336
debug_dump(" - skipping: matches self\n");
327337
return false;
328338
}
@@ -403,15 +413,28 @@ analyze_object(struct dl_phdr_info *info, size_t size, void *data)
403413
return 0;
404414
}
405415

416+
const char *cmdline;
417+
406418
/*
407419
* intercept - This is where the highest level logic of hotpatching
408420
* is described. Upon startup, this routine looks for libc, and libpthread.
409421
* If these libraries are found in the process's address space, they are
410422
* patched.
423+
*
424+
* This is init routine of syscall_intercept. This library constructor
425+
* must be in a TU which also contains public symbols, otherwise linkers
426+
* might just get rid of the whole object file containing it, when linking
427+
* statically with libsyscall_intercept.
411428
*/
412-
void
413-
intercept(void)
429+
static __attribute__((constructor)) void
430+
intercept(int argc, char **argv)
414431
{
432+
(void) argc;
433+
cmdline = argv[0];
434+
435+
if (!syscall_hook_in_process_allowed())
436+
return;
437+
415438
vdso_addr = (void *)(uintptr_t)getauxval(AT_SYSINFO_EHDR);
416439
debug_dumps_on = getenv("INTERCEPT_DEBUG_DUMP") != NULL;
417440
patch_all_objs = (getenv("INTERCEPT_ALL_OBJS") != NULL);

src/intercept.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,6 @@ bool is_overwritable_nop(const struct intercept_disasm_result *ins);
225225

226226
void create_jump(unsigned char opcode, unsigned char *from, void *to);
227227

228-
void intercept(void);
228+
const char *cmdline;
229229

230230
#endif

src/intercept_template.s

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,35 +214,61 @@
214214
*/
215215

216216
.global backtrace_placeholder;
217+
.hidden backtrace_placeholder;
217218
.type backtrace_placeholder, @function
218219

219220
.global backtrace_placeholder_2;
221+
.hidden backtrace_placeholder_2;
220222
.type backtrace_placeholder_2, @function
221223

222224
.global intercept_asm_wrapper_tmpl;
225+
.hidden intercept_asm_wrapper_tmpl;
223226
.global intercept_asm_wrapper_simd_save;
227+
.hidden intercept_asm_wrapper_simd_save;
224228
.global intercept_asm_wrapper_prefix;
229+
.hidden intercept_asm_wrapper_prefix;
225230
.global intercept_asm_wrapper_push_origin_addr;
231+
.hidden intercept_asm_wrapper_push_origin_addr;
226232
.global intercept_asm_wrapper_mov_return_addr_r11_no_syscall;
233+
.hidden intercept_asm_wrapper_mov_return_addr_r11_no_syscall;
227234
.global intercept_asm_wrapper_mov_return_addr_r11_syscall;
235+
.hidden intercept_asm_wrapper_mov_return_addr_r11_syscall;
228236
.global intercept_asm_wrapper_mov_libpath_r11;
237+
.hidden intercept_asm_wrapper_mov_libpath_r11;
229238
.global intercept_asm_wrapper_mov_phaddr_r11;
239+
.hidden intercept_asm_wrapper_mov_phaddr_r11;
230240
.global intercept_asm_wrapper_mov_ph2addr_r11;
241+
.hidden intercept_asm_wrapper_mov_ph2addr_r11;
231242
.global intercept_asm_wrapper_call;
243+
.hidden intercept_asm_wrapper_call;
232244
.global intercept_asm_wrapper_simd_restore;
245+
.hidden intercept_asm_wrapper_simd_restore;
233246
.global intercept_asm_wrapper_postfix;
247+
.hidden intercept_asm_wrapper_postfix;
234248
.global intercept_asm_wrapper_return_jump;
249+
.hidden intercept_asm_wrapper_return_jump;
235250
.global intercept_asm_wrapper_end;
251+
.hidden intercept_asm_wrapper_end;
236252
.global intercept_asm_wrapper_simd_save_YMM;
253+
.hidden intercept_asm_wrapper_simd_save_YMM;
237254
.global intercept_asm_wrapper_simd_save_YMM_end;
255+
.hidden intercept_asm_wrapper_simd_save_YMM_end;
238256
.global intercept_asm_wrapper_simd_restore_YMM;
257+
.hidden intercept_asm_wrapper_simd_restore_YMM;
239258
.global intercept_asm_wrapper_simd_restore_YMM_end;
259+
.hidden intercept_asm_wrapper_simd_restore_YMM_end;
240260
.global intercept_asm_wrapper_return_and_no_syscall;
261+
.hidden intercept_asm_wrapper_return_and_no_syscall;
241262
.global intercept_asm_wrapper_return_and_syscall;
263+
.hidden intercept_asm_wrapper_return_and_syscall;
242264
.global intercept_asm_wrapper_push_stack_first_return_addr;
265+
.hidden intercept_asm_wrapper_push_stack_first_return_addr;
243266
.global intercept_asm_wrapper_mov_r11_stack_first_return_addr;
267+
.hidden intercept_asm_wrapper_mov_r11_stack_first_return_addr;
244268
.global intercept_asm_wrapper_clone_wrapper;
269+
.hidden intercept_asm_wrapper_clone_wrapper;
245270
.global intercept_asm_wrapper_call_clone_child_intercept;
271+
.hidden intercept_asm_wrapper_call_clone_child_intercept;
246272

247273
.text
248274

src/util.s

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
*/
3232

3333
.global xlongjmp;
34+
.hidden xlongjmp;
3435
.type xlongjmp, @function
3536

3637
.global has_ymm_registers;
38+
.hidden has_ymm_registers;
3739
.type has_ymm_registers, @function
3840

3941
.global syscall_no_intercept;

test/CMakeLists.txt

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ include_directories(${PROJECT_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR}/test)
4141

4242
set(CMAKE_ASM_CREATE_SHARED_LIBRARY ${CMAKE_C_CREATE_SHARED_LIBRARY})
4343

44-
add_executable(asm_pattern asm_pattern.c)
44+
add_executable(asm_pattern asm_pattern.c
45+
$<TARGET_OBJECTS:syscall_intercept_base_c>
46+
$<TARGET_OBJECTS:syscall_intercept_base_asm>)
47+
4548
target_link_libraries(asm_pattern
46-
PRIVATE ${CMAKE_DL_LIBS} ${capstone_LDFLAGS}
47-
syscall_intercept_base_c syscall_intercept_base_asm)
49+
PRIVATE ${CMAKE_DL_LIBS} ${capstone_LDFLAGS})
4850

4951
set(asm_patterns
5052
nosyscall
@@ -127,19 +129,37 @@ add_test(NAME "logging"
127129
-DSECOND_MATCH_FILE=${CMAKE_CURRENT_SOURCE_DIR}/libcintercept0_child.log.match
128130
${CHECK_LOG_COMMON_ARGS})
129131

132+
add_library(hook_test_preload_o OBJECT hook_test_preload.c)
133+
130134
add_executable(hook_test hook_test.c)
131-
add_library(hook_test_preload SHARED hook_test_preload.c)
132-
target_link_libraries(hook_test_preload PRIVATE syscall_intercept_shared)
133-
add_test(NAME "hook"
135+
136+
add_library(hook_test_preload_with_shared SHARED
137+
$<TARGET_OBJECTS:hook_test_preload_o>)
138+
target_link_libraries(hook_test_preload_with_shared PRIVATE syscall_intercept_shared)
139+
add_test(NAME "hook_with_shared"
140+
COMMAND ${CMAKE_COMMAND}
141+
-DTEST_EXTRA_PRELOAD=${TEST_EXTRA_PRELOAD}
142+
-DTEST_NAME=hook
143+
-DLIB_FILE=$<TARGET_FILE:hook_test_preload_with_shared>
144+
-DTEST_PROG=$<TARGET_FILE:hook_test>
145+
-DTEST_PROG_ARG=None
146+
-DMATCH_FILE=${CMAKE_CURRENT_SOURCE_DIR}/libcintercept1.log.match
147+
${CHECK_LOG_COMMON_ARGS})
148+
149+
add_library(hook_test_preload_with_static SHARED
150+
$<TARGET_OBJECTS:hook_test_preload_o>)
151+
target_link_libraries(hook_test_preload_with_static PRIVATE syscall_intercept_static)
152+
add_test(NAME "hook_with_static"
134153
COMMAND ${CMAKE_COMMAND}
135154
-DTEST_EXTRA_PRELOAD=${TEST_EXTRA_PRELOAD}
136155
-DTEST_NAME=hook
137-
-DLIB_FILE=$<TARGET_FILE:hook_test_preload>
156+
-DLIB_FILE=$<TARGET_FILE:hook_test_preload_with_static>
138157
-DTEST_PROG=$<TARGET_FILE:hook_test>
139158
-DTEST_PROG_ARG=None
140159
-DMATCH_FILE=${CMAKE_CURRENT_SOURCE_DIR}/libcintercept1.log.match
141160
${CHECK_LOG_COMMON_ARGS})
142161

162+
143163
add_library(hook_test_clone_preload SHARED hook_test_clone_preload.c)
144164
target_link_libraries(hook_test_clone_preload PRIVATE syscall_intercept_shared)
145165
add_test(NAME "hook_clone"

test/asm_pattern.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,3 +234,18 @@ main(int argc, char **argv)
234234

235235
return EXIT_SUCCESS;
236236
}
237+
238+
/*
239+
* syscall_hook_in_process_allowed - this symbol must be provided to
240+
* be able to link with syscall_intercept's objects (other then the one
241+
* created from cmdline_filter.c).
242+
* This symbol is referenced from intercept.c,
243+
* defined once in cmdline_filter.c, and defined here as well.
244+
*
245+
* Note: this function is actually never called in this test.
246+
*/
247+
int
248+
syscall_hook_in_process_allowed(void)
249+
{
250+
return 0;
251+
}

0 commit comments

Comments
 (0)