Files
rust/tests/codegen-llvm/patchable-function-entry/patchable-function-entry-both-flags.rs
T
Paul Murphy c340e8a2ba Allow section override when using patchable-function-entries
Sometimes it is necessary to group patchable function entrypoint
records in distinct linker sections. This is the case for some bpf
functions within the linux kernel which shouldn't be visible to
ftrace.

Extend `-Zpatchable-function-entry` to accept an argument of the form
`prefix_nops,total_nops,record_section`, which places all entry
record into a user specified section.

Likewise, extend the `patchable_function_entry` attribute to accept an
optional `section="name"` option to place a function into a specific
section.

This is made possible by llvm attribute `patchable-function-entry-section`
added in llvm 21.
2026-06-29 08:52:28 -05:00

97 lines
3.7 KiB
Rust

//@ compile-flags: -Z patchable-function-entry=15,10
#![feature(patchable_function_entry)]
#![crate_type = "lib"]
// This should have the default, as set by the compile flags
#[no_mangle]
pub fn fun0() {}
// The attribute should override the compile flags
#[no_mangle]
#[patchable_function_entry(prefix_nops = 1, entry_nops = 2)]
pub fn fun1() {}
// If we override an attribute to 0 or unset, the attribute should go away
#[no_mangle]
#[patchable_function_entry(entry_nops = 0)]
pub fn fun2() {}
// The attribute should override the compile flags
#[no_mangle]
#[patchable_function_entry(prefix_nops = 20, entry_nops = 1)]
pub fn fun3() {}
// The attribute should override the compile flags
#[no_mangle]
#[patchable_function_entry(prefix_nops = 2, entry_nops = 19)]
pub fn fun4() {}
// The attribute should override patchable-function-entry to 3 and
// patchable-function-prefix to the default of 0, clearing it entirely
#[no_mangle]
#[patchable_function_entry(entry_nops = 3)]
pub fn fun5() {}
// The attribute should override patchable-function-prefix to 4
// and patchable-function-entry to the default of 0, clearing it entirely
#[no_mangle]
#[patchable_function_entry(prefix_nops = 4)]
pub fn fun6() {}
// The attribute should override patchable-function-prefix to 4
// and patchable-function-entry to the default of 0, clearing it entirely,
// while setting patchable-function-entry-section.
#[no_mangle]
#[patchable_function_entry(prefix_nops = 4, section = "foo")]
pub fn fun7() {}
// The attribute should override patchable-function-entry-section,
// while passing through the commandline options.
#[no_mangle]
#[patchable_function_entry(section = "bar")]
pub fn fun8() {}
// The attribute should override patchable-function-entry to 5
// and patchable-function-prefix to the default of 0, clearing it entirely,
// while setting patchable-function-entry-section.
#[no_mangle]
#[patchable_function_entry(entry_nops = 5, section = "baz")]
pub fn fun9() {}
// CHECK: @fun0() unnamed_addr #0
// CHECK: @fun1() unnamed_addr #1
// CHECK: @fun2() unnamed_addr #2
// CHECK: @fun3() unnamed_addr #3
// CHECK: @fun4() unnamed_addr #4
// CHECK: @fun5() unnamed_addr #5
// CHECK: @fun6() unnamed_addr #6
// CHECK: @fun7() unnamed_addr #7
// CHECK: @fun8() unnamed_addr #8
// CHECK: @fun9() unnamed_addr #9
// CHECK: attributes #0 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-prefix"="10" {{.*}} }
// CHECK: attributes #1 = { {{.*}}"patchable-function-entry"="2"{{.*}}"patchable-function-prefix"="1" {{.*}} }
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-entry{{.*}} }
// CHECK-NOT: attributes #2 = { {{.*}}patchable-function-prefix{{.*}} }
// CHECK: attributes #2 = { {{.*}} }
// CHECK: attributes #3 = { {{.*}}"patchable-function-entry"="1"{{.*}}"patchable-function-prefix"="20" {{.*}} }
// CHECK: attributes #4 = { {{.*}}"patchable-function-entry"="19"{{.*}}"patchable-function-prefix"="2" {{.*}} }
// CHECK: attributes #5 = { {{.*}}"patchable-function-entry"="3"{{.*}} }
// CHECK-NOT: attributes #5 = { {{.*}}patchable-function-prefix{{.*}} }
// CHECK: attributes #6 = { {{.*}}"patchable-function-prefix"="4"{{.*}} }
// CHECK-NOT: attributes #6 = { {{.*}}patchable-function-entry{{.*}} }
//
// CHECK: attributes #7 = { {{.*}}"patchable-function-entry-section"="foo"{{.*}}"patchable-function-prefix"="4" {{.*}} }
// CHECK-NOT: attributes #7 = { {{.*}}"patchable-function-entry"{{.*}} }
//
// CHECK: attributes #8 = { {{.*}}"patchable-function-entry-section"="bar"{{.*}} }
// CHECK-NOT: attributes #8 = { {{.*}}"patchable-function-entry"{{.*}} }
//
// CHECK: attributes #9 = { {{.*}}"patchable-function-entry"="5"{{.*}}"patchable-function-entry-section"="baz" {{.*}} }
// CHECK-NOT: attributes #9 = { {{.*}}"patchable-function-prefix{{.*}} }