Issue |
132393
|
Summary |
R_X86_64_REX_GOTPCRELX emitted in a kernel module when compiling with -fsanitize-coverage=trace-pc-guard
|
Labels |
new issue
|
Assignees |
|
Reporter |
ramosian-glider
|
I am trying to bring support for -fsanitize-coverage=trace-pc-guard to the Linux kernel (draft patchset at https://github.com/ramosian-glider/linux/pull/7)
The module looks as follows:
```
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init testmod_init(void) {
return 0;
}
module_init(testmod_init);
```
In the IR, the compiler declares two variables to reference the beginning and the end of the `__sancov_guards` section, `@__start___sancov_guards` and `@__stop___sancov_guards`:
```
...
$sancov.module_ctor_trace_pc_guard = comdat any
...
@__sancov_gen_ = private global [1 x i32] zeroinitializer, section "__sancov_guards", comdat($init_module), align 4
@__start___sancov_guards = extern_weak hidden global i32
@__stop___sancov_guards = extern_weak hidden global i32
@llvm.used = appending global [2 x ptr] [ptr @sancov.module_ctor_trace_pc_guard, ptr @asan.module_ctor], section "llvm.metadata"
@llvm.compiler.used = appending global [3 x ptr] [ptr @__UNIQUE_ID___addressable_init_module564, ptr @__UNIQUE_ID_license563, ptr @__sancov_gen_], section "llvm.metadata"
@___asan_gen_module = private constant [17 x i8] c"kernel/testmod.c\00", align 1
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 2, ptr @sancov.module_ctor_trace_pc_guard, ptr @sancov.module_ctor_trace_pc_guard }]
...
declare void @__sanitizer_cov_trace_pc_guard_init(ptr, ptr)
; Function Attrs: fn_ret_thunk_extern nounwind
define internal void @sancov.module_ctor_trace_pc_guard() #1 comdat {
call void @__asan_before_dynamic_init(i64 ptrtoint (ptr @___asan_gen_module to i64))
call void @__sanitizer_cov_trace_pc_guard_init(ptr @__start___sancov_guards, ptr @__stop___sancov_guards)
call void @__asan_after_dynamic_init()
ret void
}
```
(full IR: [testmod.txt](https://github.com/user-attachments/files/19389425/testmod.txt))
For the parameters of `__sanitizer_cov_trace_pc_guard_init()` the backend generates two R_X86_64_REX_GOTPCRELX in the object file:
```
0000000000000000 <sancov.module_ctor_trace_pc_guard>:
0: f3 0f 1e fa endbr64
4: 48 c7 c7 00 00 00 00 mov $0x0,%rdi
7: R_X86_64_32S .rodata
b: e8 00 00 00 00 call 10 <sancov.module_ctor_trace_pc_guard+0x10>
c: R_X86_64_PLT32 __asan_before_dynamic_init-0x4
10: 48 8b 3d 00 00 00 00 mov 0x0(%rip),%rdi # 17 <sancov.module_ctor_trace_pc_guard+0x17>
13: R_X86_64_REX_GOTPCRELX __start___sancov_guards-0x4
17: 48 8b 35 00 00 00 00 mov 0x0(%rip),%rsi # 1e <sancov.module_ctor_trace_pc_guard+0x1e>
1a: R_X86_64_REX_GOTPCRELX __stop___sancov_guards-0x4
1e: e8 00 00 00 00 call 23 <sancov.module_ctor_trace_pc_guard+0x23>
1f: R_X86_64_PLT32 __sanitizer_cov_trace_pc_guard_init-0x4
23: e8 00 00 00 00 call 28 <sancov.module_ctor_trace_pc_guard+0x28>
24: R_X86_64_PLT32 __asan_after_dynamic_init-0x4
28: 2e e9 00 00 00 00 cs jmp 2e <init_module+0x1e>
2a: R_X86_64_PLT32 __x86_return_thunk-0x4
```
, which remain in the resulting kernel module, making it unusable, as the kernel cannot process this relocation type:
```
$ objdump -r kernel/testmod.ko | grep PCREL
0000000000000013 R_X86_64_REX_GOTPCRELX __start___sancov_guards-0x0000000000000004
000000000000001a R_X86_64_REX_GOTPCRELX __stop___sancov_guards-0x0000000000000004
```
I am wondering if it is correct to declare the `__start` and `__stop` variables as `extern_weak hidden global` for the modules. Given that we want `__sanitizer_cov_trace_pc_guard_init()` in a module to be called for the contents of the `__sancov_guards` section of that module, not the vmlinux binary, shouldn't these variables be `dso_local`, or something alike?
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs