Skip to content

Commit b473e9c

Browse files
committed
Add hotpatch flag. Proof of concept only working on x86/x64.
1 parent 8f8bee4 commit b473e9c

File tree

9 files changed

+39
-1
lines changed

9 files changed

+39
-1
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,15 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
378378
to_add.push(llvm::CreateAttrString(cx.llcx, "use-sample-profile"));
379379
}
380380

381+
// patchable-function is only implemented on x86 on LLVM
382+
if cx.sess().opts.unstable_opts.hotpatch && cx.sess().target.is_x86() {
383+
to_add.push(llvm::CreateAttrStringValue(
384+
cx.llcx,
385+
"patchable-function",
386+
"prologue-short-redirect",
387+
));
388+
}
389+
381390
// FIXME: none of these functions interact with source level attributes.
382391
to_add.extend(frame_pointer_type_attr(cx));
383392
to_add.extend(function_return_attr(cx));

compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ impl OwnedTargetMachine {
3535
emit_stack_size_section: bool,
3636
relax_elf_relocations: bool,
3737
use_init_array: bool,
38+
use_hotpatch: bool,
3839
split_dwarf_file: &CStr,
3940
output_obj_file: &CStr,
4041
debug_info_compression: &CStr,
@@ -67,6 +68,7 @@ impl OwnedTargetMachine {
6768
emit_stack_size_section,
6869
relax_elf_relocations,
6970
use_init_array,
71+
use_hotpatch,
7072
split_dwarf_file.as_ptr(),
7173
output_obj_file.as_ptr(),
7274
debug_info_compression.as_ptr(),

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ pub(crate) fn target_machine_factory(
225225
let use_init_array =
226226
!sess.opts.unstable_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section);
227227

228+
// this annotes in the debug file that code is hotpatchable. In addtion without it -functionpadmin will be ignored.
229+
// See: https://github.com/llvm/llvm-project/blob/d703b922961e0d02a5effdd4bfbb23ad50a3cc9f/lld/COFF/Writer.cpp#L1298
230+
let use_hotpatch = sess.opts.unstable_opts.hotpatch && sess.target.is_x86();
231+
228232
let path_mapping = sess.source_map().path_mapping().clone();
229233

230234
let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated);
@@ -297,6 +301,7 @@ pub(crate) fn target_machine_factory(
297301
emit_stack_size_section,
298302
relax_elf_relocations,
299303
use_init_array,
304+
use_hotpatch,
300305
&split_dwarf_file,
301306
&output_obj_file,
302307
&debuginfo_compression,

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ unsafe extern "C" {
21702170
EmitStackSizeSection: bool,
21712171
RelaxELFRelocations: bool,
21722172
UseInitArray: bool,
2173+
UseHotpatch: bool,
21732174
SplitDwarfFile: *const c_char,
21742175
OutputObjFile: *const c_char,
21752176
DebugInfoCompression: *const c_char,

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ fn test_unstable_options_tracking_hash() {
788788
tracked!(fuel, Some(("abc".to_string(), 99)));
789789
tracked!(function_return, FunctionReturn::ThunkExtern);
790790
tracked!(function_sections, Some(false));
791+
tracked!(hotpatch, true);
791792
tracked!(human_readable_cgu_names, true);
792793
tracked!(incremental_ignore_spans, true);
793794
tracked!(inline_in_all_cgus, Some(true));

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
395395
LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
396396
bool FunctionSections, bool DataSections, bool UniqueSectionNames,
397397
bool TrapUnreachable, bool Singlethread, bool VerboseAsm,
398-
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray,
398+
bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, bool UseHotpatch,
399399
const char *SplitDwarfFile, const char *OutputObjFile,
400400
const char *DebugInfoCompression, bool UseEmulatedTls,
401401
const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
@@ -426,6 +426,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
426426
// Always preserve comments that were written by the user
427427
Options.MCOptions.PreserveAsmComments = true;
428428
Options.MCOptions.ABIName = ABIStr;
429+
Options.Hotpatch = UseHotpatch;
429430
if (SplitDwarfFile) {
430431
Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
431432
}

compiler/rustc_session/src/options.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1810,6 +1810,10 @@ options! {
18101810
"explicitly enable the `cfg(target_thread_local)` directive"),
18111811
hir_stats: bool = (false, parse_bool, [UNTRACKED],
18121812
"print some statistics about AST and HIR (default: no)"),
1813+
hotpatch: bool = (false, parse_bool, [TRACKED],
1814+
"ensures hotpatching is always possible by ensuring that the first instruction of \
1815+
each function is at least two bytes, and no jump within the function goes to the first instruction. \
1816+
Should be combined with link-arg passing -functionpadmin to the linker. Currently only supported for x86 (default: false)"),
18131817
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
18141818
"generate human-readable, predictable names for codegen units (default: no)"),
18151819
identify_regions: bool = (false, parse_bool, [UNTRACKED],

compiler/rustc_target/src/spec/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,9 @@ impl Target {
20702070

20712071
Ok(dl)
20722072
}
2073+
pub fn is_x86(&self) -> bool {
2074+
["x86", "x86_64"].contains(&&self.arch[..])
2075+
}
20732076
}
20742077

20752078
pub trait HasTargetSpec {

tests/codegen/hotpatch.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ revisions: x32 x64
2+
//@[x32] only-x86
3+
//@[x64] only-x86_64
4+
//@ compile-flags: -Z hotpatch
5+
6+
#![crate_type = "lib"]
7+
8+
#[no_mangle]
9+
pub fn foo() {}
10+
11+
// CHECK: @foo() unnamed_addr #0
12+
// CHECK: attributes #0 = { {{.*}} "patchable-function"="prologue-short-redirect" {{.*}}}

0 commit comments

Comments
 (0)