Skip to content

Commit 1caa875

Browse files
committed
Apply LLVM sanitize attributes to generated entry wrapper
1 parent b846b42 commit 1caa875

File tree

3 files changed

+43
-32
lines changed

3 files changed

+43
-32
lines changed

src/librustc_codegen_llvm/attributes.rs

+26-20
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,31 @@ fn inline(cx: &CodegenCx<'ll, '_>, val: &'ll Value, inline: InlineAttr) {
4646
};
4747
}
4848

49+
/// Apply LLVM sanitize attributes.
50+
#[inline]
51+
pub fn sanitize(cx: &CodegenCx<'ll, '_>, codegen_fn_flags: CodegenFnAttrFlags, llfn: &'ll Value) {
52+
if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer {
53+
match *sanitizer {
54+
Sanitizer::Address => {
55+
if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) {
56+
llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn);
57+
}
58+
}
59+
Sanitizer::Memory => {
60+
if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) {
61+
llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn);
62+
}
63+
}
64+
Sanitizer::Thread => {
65+
if !codegen_fn_flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) {
66+
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
67+
}
68+
}
69+
Sanitizer::Leak => {}
70+
}
71+
}
72+
}
73+
4974
/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
5075
#[inline]
5176
pub fn emit_uwtable(val: &'ll Value, emit: bool) {
@@ -288,26 +313,7 @@ pub fn from_fn_attrs(
288313
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::ALLOCATOR) {
289314
Attribute::NoAlias.apply_llfn(llvm::AttributePlace::ReturnValue, llfn);
290315
}
291-
if let Some(ref sanitizer) = cx.tcx.sess.opts.debugging_opts.sanitizer {
292-
match *sanitizer {
293-
Sanitizer::Address => {
294-
if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_ADDRESS) {
295-
llvm::Attribute::SanitizeAddress.apply_llfn(Function, llfn);
296-
}
297-
}
298-
Sanitizer::Memory => {
299-
if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_MEMORY) {
300-
llvm::Attribute::SanitizeMemory.apply_llfn(Function, llfn);
301-
}
302-
}
303-
Sanitizer::Thread => {
304-
if !codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_SANITIZE_THREAD) {
305-
llvm::Attribute::SanitizeThread.apply_llfn(Function, llfn);
306-
}
307-
}
308-
Sanitizer::Leak => {}
309-
}
310-
}
316+
sanitize(cx, codegen_fn_attrs.flags, llfn);
311317

312318
unwind(
313319
llfn,

src/librustc_codegen_llvm/base.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
1616
use super::ModuleLlvm;
1717

18+
use crate::attributes;
1819
use crate::builder::Builder;
1920
use crate::common;
2021
use crate::context::CodegenCx;
@@ -23,7 +24,7 @@ use crate::metadata;
2324
use crate::value::Value;
2425

2526
use rustc::dep_graph;
26-
use rustc::middle::codegen_fn_attrs::CodegenFnAttrs;
27+
use rustc::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
2728
use rustc::middle::cstore::EncodedMetadata;
2829
use rustc::middle::exported_symbols;
2930
use rustc::mir::mono::{Linkage, Visibility};
@@ -131,7 +132,9 @@ pub fn compile_codegen_unit(
131132

132133
// If this codegen unit contains the main function, also create the
133134
// wrapper here
134-
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx);
135+
if let Some(entry) = maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx) {
136+
attributes::sanitize(&cx, CodegenFnAttrFlags::empty(), entry);
137+
}
135138

136139
// Run replace-all-uses-with for statics that need it
137140
for &(old_g, new_g) in cx.statics_to_rauw().borrow().iter() {

src/librustc_codegen_ssa/base.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -391,36 +391,36 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
391391

392392
/// Creates the `main` function which will initialize the rust runtime and call
393393
/// users main function.
394-
pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'a Bx::CodegenCx) {
394+
pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
395+
cx: &'a Bx::CodegenCx,
396+
) -> Option<Bx::Function> {
395397
let (main_def_id, span) = match cx.tcx().entry_fn(LOCAL_CRATE) {
396398
Some((def_id, _)) => (def_id, cx.tcx().def_span(def_id)),
397-
None => return,
399+
None => return None,
398400
};
399401

400402
let instance = Instance::mono(cx.tcx(), main_def_id);
401403

402404
if !cx.codegen_unit().contains_item(&MonoItem::Fn(instance)) {
403405
// We want to create the wrapper in the same codegen unit as Rust's main
404406
// function.
405-
return;
407+
return None;
406408
}
407409

408410
let main_llfn = cx.get_fn_addr(instance);
409411

410-
let et = cx.tcx().entry_fn(LOCAL_CRATE).map(|e| e.1);
411-
match et {
412-
Some(EntryFnType::Main) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, true),
413-
Some(EntryFnType::Start) => create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, false),
414-
None => {} // Do nothing.
415-
}
412+
return cx.tcx().entry_fn(LOCAL_CRATE).map(|(_, et)| {
413+
let use_start_lang_item = EntryFnType::Start != et;
414+
create_entry_fn::<Bx>(cx, span, main_llfn, main_def_id, use_start_lang_item)
415+
});
416416

417417
fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
418418
cx: &'a Bx::CodegenCx,
419419
sp: Span,
420420
rust_main: Bx::Value,
421421
rust_main_def_id: DefId,
422422
use_start_lang_item: bool,
423-
) {
423+
) -> Bx::Function {
424424
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
425425
// depending on whether the target needs `argc` and `argv` to be passed in.
426426
let llfty = if cx.sess().target.target.options.main_needs_argc_argv {
@@ -481,6 +481,8 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(cx: &'
481481
let result = bx.call(start_fn, &args, None);
482482
let cast = bx.intcast(result, cx.type_int(), true);
483483
bx.ret(cast);
484+
485+
llfn
484486
}
485487
}
486488

0 commit comments

Comments
 (0)