Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking error when new external variable is introduced in intercept_wrapper.S #130

Open
hurryman2212 opened this issue Apr 25, 2023 · 2 comments
Labels

Comments

@hurryman2212
Copy link

hurryman2212 commented Apr 25, 2023

This is more like a question other than a issue since this issue is related to the added feature that I'm currently working on, but I don't have any other place to get help on this.

I'm currently working on the version where intercept_hook_point is a static TLS variable that allows each thread to turn on and off the syscall interception dynamically (and a front-end library providing AS-safety against signal as well). You can check it here (except the AS-safe front-end library yet). This solution is for the users who wants to use glibc C/C++ function for some reasons (e.g. don't want to use syscall_no_intercept or additional dlopen() to link original object, want to use complex standard functions or STL things, etc.) during the interception with the cost of inefficiency (as it still goes through the intercepting routines).

In order to relax the overhead when intercept_hook_point is set to NULL (i.e. disable the interception by the thread), I insert the procedure into intercept_wrapper.S in the above fork repository (starting from the line 55):


.global intercept_hook_point
.hidden intercept_hook_point
.type intercept_hook_point, @tls_object

.text

/*
 * Local stack layout:
 *
 * 0x448(%rsp)  -- return address, to the generated asm wrapper
 * Arguments recieved on stack:
 * 0x450(%rsp)  -- original value of rsp
 * 0x458(%rsp)  -- pointer to a struct patch_desc instance
 * Locals on stack:
 * 0xe8(%rsp) - 0x168(%rsp) -- saved GPRs
 * 0x200(%rsp) - 0x400(%rsp) -- saved SIMD registers
 *
 * A pointer to these saved register is passed to intercept_routine, so the
 * layout of `struct context` must match this part of the stack layout.
 *
 * Other arguments:
 * %rcx  -- which C function to call
 */
intercept_wrapper:
	.cfi_startproc

	/*
	 * Stack size used locally: 0x448 bytes.
	 *
	 * This size assumes the stack pointer was correctly aligned before
	 * executing the call instruction calling this function. The return
	 * address pushed to the stack uses 8 bytes. This gives the equation:
	 *
	 * new_rsp = original_rsp - 8 - 0x448 == original_rsp - 0x450
	 * The number 0x450 is a multiple of 16, so the stack is still correctly
	 * aligned. It is very easy to forget about this when making changes to this
	 * code.
	 */
	subq        $0x448, %rsp
	.cfi_def_cfa_offset 0x0

	cmp         $0x1, %rcx
	je          4f

	/* SYS_vfork */
	cmp         $58, %eax
	je          0f
	/* SYS_rt_sigreturn */
	cmp         $15, %eax
	je          0f
	/* SYS_clone */
	cmp         $56, %eax
	je          1f
	/* SYS_clone3 */
	cmp         $435, %eax
	je          1f

	movq        %rcx, 0x160 (%rsp)
	movq        intercept_hook_point (%rip), %rcx
	cmp         $0x0, %rcx
	jne         3f

	movq        0x160 (%rsp), %rcx
0:
	/* SYS_vfork & SYS_rt_sigreturn */
	movq        0x00, %r11
	jmp         2f
1:
	/* SYS_clone & SYS_clone3 */
	movq        0x02, %r11
2:
	addq        $0x448, %rsp
	retq

3:
	movq        0x160 (%rsp), %rcx

4:
	/* Save all GPRs on the stack */

This modification will make intercept_wrapper() to decide on whether the interception will be done or not (or handle differently depending on the syscall number) before intercept_routine() and the stack saving & restoration, in order to lower the false interception overhead for the current implementation (before intercept_wrapper(), intercept_asm_wrapper_tmpl() locates in many addresses for each syscall instruction address so putting the code there is risking the I-cache/I-TLB pollution).

However, this introduces a link error:

/usr/bin/ld: CMakeFiles/filter_test.dir/filter_test.c.o: in function `main':
filter_test.c:(.text+0xb): undefined reference to `intercept_hook_point'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

While the main library file, libsyscall_intercept.so is built successfully, undefined reference to `intercept_hook_point' is still there when trying to preloading it.

@en4bz en4bz added the question label May 1, 2023
@en4bz en4bz changed the title [question] Linking error when new external variable is introduced in intercept_wrapper.S Linking error when new external variable is introduced in intercept_wrapper.S May 1, 2023
@en4bz
Copy link
Collaborator

en4bz commented May 1, 2023

You'll have to post the link command and symbol table for the objects involved in the link with readelf -s. There's not enough info here.

@en4bz
Copy link
Collaborator

en4bz commented May 3, 2023

Also for movq intercept_hook_point (%rip), %rcx the address of intercept_hook_point will be relative to %fs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants