diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index c03b2188824..b0354376210 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -46,6 +46,7 @@ use rustc_span::symbol::Symbol; use std::any::Any; use std::ffi::CStr; +use std::io::Write; mod back { pub mod archive; @@ -177,32 +178,30 @@ impl WriteBackendMethods for LlvmCodegenBackend { type ThinData = back::lto::ThinData; type ThinBuffer = back::lto::ThinBuffer; fn print_pass_timings(&self) { - let msg = unsafe { - let cstr = llvm::LLVMRustPrintPassTimings(); + unsafe { + let mut size = 0; + let cstr = llvm::LLVMRustPrintPassTimings(&mut size as *mut usize); if cstr.is_null() { - "failed to get pass timings".into() + println!("failed to get pass timings"); } else { - let timings = CStr::from_ptr(cstr).to_bytes(); - let timings = String::from_utf8_lossy(timings).to_string(); + let timings = std::slice::from_raw_parts(cstr as *const u8, size); + std::io::stdout().write_all(timings).unwrap(); libc::free(cstr as *mut _); - timings } - }; - println!("{}", msg); + } } fn print_statistics(&self) { - let msg = unsafe { - let cstr = llvm::LLVMRustPrintStatistics(); + unsafe { + let mut size = 0; + let cstr = llvm::LLVMRustPrintStatistics(&mut size as *mut usize); if cstr.is_null() { - "failed to get stats".into() + println!("failed to get pass stats"); } else { - let stats = CStr::from_ptr(cstr).to_bytes(); - let stats = String::from_utf8_lossy(stats).to_string(); + let stats = std::slice::from_raw_parts(cstr as *const u8, size); + std::io::stdout().write_all(stats).unwrap(); libc::free(cstr as *mut _); - stats } - }; - println!("{}", msg); + } } fn run_link( cgcx: &CodegenContext, diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 7cc79d859a3..fd88994c31c 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1868,10 +1868,10 @@ extern "C" { pub fn LLVMRustGetLastError() -> *const c_char; /// Print the pass timings since static dtors aren't picking them up. - pub fn LLVMRustPrintPassTimings() -> *const c_char; + pub fn LLVMRustPrintPassTimings(size: *const size_t) -> *const c_char; /// Print the statistics since static dtors aren't picking them up. - pub fn LLVMRustPrintStatistics() -> *const c_char; + pub fn LLVMRustPrintStatistics(size: *const size_t) -> *const c_char; pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 695b8847a97..870a2e02cba 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -112,23 +112,25 @@ extern "C" void LLVMRustSetNormalizedTarget(LLVMModuleRef M, unwrap(M)->setTargetTriple(Triple::normalize(Triple)); } -extern "C" const char *LLVMRustPrintPassTimings(void) { +extern "C" const char *LLVMRustPrintPassTimings(size_t *Len) { std::string buf; raw_string_ostream SS(buf); TimerGroup::printAll(SS); SS.flush(); - char* CStr = (char*) malloc((buf.length() + 1) * sizeof(char)); - strcpy(CStr, buf.c_str()); + *Len = buf.length(); + char *CStr = (char *)malloc(*Len); + memcpy(CStr, buf.c_str(), *Len); return CStr; } -extern "C" const char *LLVMRustPrintStatistics(void) { +extern "C" const char *LLVMRustPrintStatistics(size_t *Len) { std::string buf; raw_string_ostream SS(buf); llvm::PrintStatistics(SS); SS.flush(); - char* CStr = (char*) malloc((buf.length() + 1) * sizeof(char)); - strcpy(CStr, buf.c_str()); + *Len = buf.length(); + char *CStr = (char *)malloc(*Len); + memcpy(CStr, buf.c_str(), *Len); return CStr; }