Skip to content

Commit 8764e73

Browse files
committed
added new test. Adjusted test as we dropped the 'no jump to first instruction' condition
1 parent 13bc998 commit 8764e73

File tree

5 files changed

+52
-33
lines changed

5 files changed

+52
-33
lines changed

tests/run-make/hotpatch-unaffected/rmake.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Check if hotpatch leaves the functions that are already hotpatchable untouched
22

3-
//@ revisions: x32 x64
3+
//@ revisions: x32 x64 aarch64
44
//@[x32] only-x86
55
//@[x64] only-x86_64
6-
// Reason: hotpatch is only implemented for X86
6+
//@[aarch64] only-aarch64
7+
8+
// Reason: hotpatch is only implemented for X86 and aarch64
79

810
use run_make_support::{assertion_helpers, llvm, rustc};
911

tests/run-make/hotpatch/lib.rs

+7-27
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,18 @@
11
// hotpatch has two requirements:
2-
// 1. the first instruction of a functin must be at least two bytes long
3-
// 2. there must not be a jump to the first instruction
2+
// 1) the first instruction of a functin must be at least two bytes long
3+
// 2) there must not be a jump to the first instruction
44

5-
// the hotpatch flag should insert nops as needed to fullfil the requirements,
6-
// but only if the the function does not already fulfill them.
7-
// Over 99% of function in regular codebases already fulfill the conditions,
8-
// so its important to check that those are
9-
// unneccessarily affected
10-
11-
// ----------------------------------------------------------------------------------------------
12-
13-
// regularly this tailcall would jump to the first instruction the function
14-
// CHECK-LABEL: <tailcall_fn>:
15-
// CHECK: jne 0x0 <tailcall_fn>
16-
17-
// hotpatch insert nops so that the tailcall will not jump to the first instruction of the function
18-
// HOTPATCH-LABEL: <tailcall_fn>:
19-
// HOTPATCH-NOT: jne 0x0 <tailcall_fn>
20-
21-
#[no_mangle]
22-
pub fn tailcall_fn() {
23-
use std::sync::atomic::{AtomicUsize, Ordering};
24-
static COUNT: AtomicUsize = AtomicUsize::new(0);
25-
if COUNT.fetch_sub(1, Ordering::Relaxed) != 0 {
26-
tailcall_fn()
27-
}
28-
}
5+
// The LLVM attribute we use '"patchable-function", "prologue-short-redirect"' only ensures 1)
6+
// However in practice 2) rarely matters. Its rare that it occurs and the problems it caused can be
7+
// avoided by the hotpatch tool.
8+
// In this test we check if 1) is ensured by inserted nops as needed
299

3010
// ----------------------------------------------------------------------------------------------
3111

3212
// empty_fn just returns. Note that 'ret' is a single byte instruction, but hotpatch requires
3313
// a two or more byte instructions to be at the start of the functions.
3414
// Preferably we would also tests a different single byte instruction,
35-
// but I was not able to make rustc emit anything but 'ret'.
15+
// but I was not able to find an example with another one byte intstruction.
3616

3717
// check that if the first instruction is just a single byte, so our test is valid
3818
// CHECK-LABEL: <empty_fn>:

tests/run-make/hotpatch/rmake.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
// Check if hotpatch only makes the functions hotpachable that were not,
2-
// but leaving the other functions untouched
1+
// Check if hotpatch makes the functions hotpachable that were not
32
// More details in lib.rs
43

54
//@ revisions: x32 x64
65
//@[x32] only-x86
76
//@[x64] only-x86_64
8-
// Reason: hotpatch is only implemented for X86
7+
8+
// Reason: hotpatch is only implemented for x86 and aarch64, but for aarch64 they
9+
// are always hotpatchable so we don't need to check it
910

1011
use run_make_support::{llvm, rustc};
1112

@@ -18,7 +19,7 @@ fn main() {
1819

1920
fn dump_lib(libname: &str) -> String {
2021
llvm::llvm_objdump()
21-
.arg("--disassemble-symbols=tailcall_fn,empty_fn")
22+
.arg("--disassemble-symbols=empty_fn")
2223
.input(libname)
2324
.run()
2425
.stdout_utf8()

tests/run-make/hotpatch_pdb/main.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// CHECK: S_OBJNAME{{.*}}hotpatch_pdb{{.*}}.o
2+
// CHECK: S_COMPILE3
3+
// CHECK-NOT: S_
4+
// CHECK: flags = {{.*}}hot patchable
5+
6+
pub fn main() {}

tests/run-make/hotpatch_pdb/rmake.rs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Check if hotpatch flag is present in the Codeview.
2+
// This is need so linkers actually pad functions when given the functionpadmin arg.
3+
4+
//@ revisions: x32 x64 aarch64
5+
//@[x32] only-x86
6+
//@[x64] only-x86_64
7+
//@[aarch64] only-aarch64
8+
9+
// Reason: Hotpatch is only implemented for x86 and aarch64
10+
11+
use run_make_support::{llvm, rustc};
12+
13+
fn main() {
14+
let output = rustc()
15+
.input("main.rs")
16+
.arg("-g")
17+
.arg("-Zhotpatch")
18+
.crate_name("hotpatch_pdb")
19+
.crate_type("bin")
20+
.run();
21+
22+
let pdbutil_output = llvm::llvm_pdbutil()
23+
.arg("dump")
24+
.arg("-symbols")
25+
.input("hotpatch_pdb.pdb")
26+
.run()
27+
.stdout_utf8();
28+
29+
llvm::llvm_filecheck().patterns("main.rs").stdin_buf(&pdbutil_output).run();
30+
}

0 commit comments

Comments
 (0)