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

Reply via email to