summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_codegen_llvm/src/back
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/back')
-rw-r--r--compiler/rustc_codegen_llvm/src/back/archive.rs49
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs22
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs26
3 files changed, 46 insertions, 51 deletions
diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs
index 27039cda2..ed96355a0 100644
--- a/compiler/rustc_codegen_llvm/src/back/archive.rs
+++ b/compiler/rustc_codegen_llvm/src/back/archive.rs
@@ -8,10 +8,11 @@ use std::path::{Path, PathBuf};
use std::ptr;
use std::str;
+use crate::common;
use crate::llvm::archive_ro::{ArchiveRO, Child};
use crate::llvm::{self, ArchiveKind, LLVMMachineType, LLVMRustCOFFShortExport};
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
-use rustc_session::cstore::{DllCallingConvention, DllImport};
+use rustc_session::cstore::DllImport;
use rustc_session::Session;
/// Helper for adding many files to an archive.
@@ -103,29 +104,28 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
lib_name: &str,
dll_imports: &[DllImport],
tmpdir: &Path,
+ is_direct_dependency: bool,
) -> PathBuf {
+ let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
let output_path = {
let mut output_path: PathBuf = tmpdir.to_path_buf();
- output_path.push(format!("{}_imports", lib_name));
+ output_path.push(format!("{}{}", lib_name, name_suffix));
output_path.with_extension("lib")
};
let target = &sess.target;
- let mingw_gnu_toolchain = target.vendor == "pc"
- && target.os == "windows"
- && target.env == "gnu"
- && target.abi.is_empty();
+ let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(target);
let import_name_and_ordinal_vector: Vec<(String, Option<u16>)> = dll_imports
.iter()
.map(|import: &DllImport| {
if sess.target.arch == "x86" {
(
- LlvmArchiveBuilder::i686_decorated_name(import, mingw_gnu_toolchain),
- import.ordinal,
+ common::i686_decorated_name(import, mingw_gnu_toolchain, false),
+ import.ordinal(),
)
} else {
- (import.name.to_string(), import.ordinal)
+ (import.name.to_string(), import.ordinal())
}
})
.collect();
@@ -136,7 +136,8 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
// that loaded but crashed with an AV upon calling one of the imported
// functions. Therefore, use binutils to create the import library instead,
// by writing a .DEF file to the temp dir and calling binutils's dlltool.
- let def_file_path = tmpdir.join(format!("{}_imports", lib_name)).with_extension("def");
+ let def_file_path =
+ tmpdir.join(format!("{}{}", lib_name, name_suffix)).with_extension("def");
let def_file_content = format!(
"EXPORTS\n{}",
@@ -159,6 +160,9 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
}
};
+ // --no-leading-underscore: For the `import_name_type` feature to work, we need to be
+ // able to control the *exact* spelling of each of the symbols that are being imported:
+ // hence we don't want `dlltool` adding leading underscores automatically.
let dlltool = find_binutils_dlltool(sess);
let result = std::process::Command::new(dlltool)
.args([
@@ -168,6 +172,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
lib_name,
"-l",
output_path.to_str().unwrap(),
+ "--no-leading-underscore",
])
.output();
@@ -188,10 +193,10 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder {
let output_path_z = rustc_fs_util::path_to_c_string(&output_path);
- tracing::trace!("invoking LLVMRustWriteImportLibrary");
- tracing::trace!(" dll_name {:#?}", dll_name_z);
- tracing::trace!(" output_path {}", output_path.display());
- tracing::trace!(
+ trace!("invoking LLVMRustWriteImportLibrary");
+ trace!(" dll_name {:#?}", dll_name_z);
+ trace!(" output_path {}", output_path.display());
+ trace!(
" import names: {}",
dll_imports
.iter()
@@ -322,22 +327,6 @@ impl<'a> LlvmArchiveBuilder<'a> {
ret
}
}
-
- fn i686_decorated_name(import: &DllImport, mingw: bool) -> String {
- let name = import.name;
- let prefix = if mingw { "" } else { "_" };
-
- match import.calling_convention {
- DllCallingConvention::C => format!("{}{}", prefix, name),
- DllCallingConvention::Stdcall(arg_list_size) => {
- format!("{}{}@{}", prefix, name, arg_list_size)
- }
- DllCallingConvention::Fastcall(arg_list_size) => format!("@{}@{}", name, arg_list_size),
- DllCallingConvention::Vectorcall(arg_list_size) => {
- format!("{}@@{}", name, arg_list_size)
- }
- }
- }
}
fn string_to_io_error(s: String) -> io::Error {
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 3731c6bcf..a89df00e2 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -1,15 +1,16 @@
use crate::back::write::{
self, save_temp_bitcode, to_llvm_opt_settings, with_llvm_pmb, DiagnosticHandlers,
};
-use crate::llvm::archive_ro::ArchiveRO;
use crate::llvm::{self, build_string, False, True};
use crate::{llvm_util, LlvmCodegenBackend, ModuleLlvm};
+use object::read::archive::ArchiveFile;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule, ThinShared};
use rustc_codegen_ssa::back::symbol_export;
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, TargetMachineFactoryConfig};
use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::{looks_like_rust_object_file, ModuleCodegen, ModuleKind};
use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::memmap::Mmap;
use rustc_errors::{FatalError, Handler};
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::bug;
@@ -17,7 +18,6 @@ use rustc_middle::dep_graph::WorkProduct;
use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
use rustc_session::cgu_reuse_tracker::CguReuse;
use rustc_session::config::{self, CrateType, Lto};
-use tracing::{debug, info};
use std::ffi::{CStr, CString};
use std::fs::File;
@@ -107,14 +107,24 @@ fn prepare_lto(
.extend(exported_symbols[&cnum].iter().filter_map(symbol_filter));
}
- let archive = ArchiveRO::open(path).expect("wanted an rlib");
+ let archive_data = unsafe {
+ Mmap::map(std::fs::File::open(&path).expect("couldn't open rlib"))
+ .expect("couldn't map rlib")
+ };
+ let archive = ArchiveFile::parse(&*archive_data).expect("wanted an rlib");
let obj_files = archive
- .iter()
- .filter_map(|child| child.ok().and_then(|c| c.name().map(|name| (name, c))))
+ .members()
+ .filter_map(|child| {
+ child.ok().and_then(|c| {
+ std::str::from_utf8(c.name()).ok().map(|name| (name.trim(), c))
+ })
+ })
.filter(|&(name, _)| looks_like_rust_object_file(name));
for (name, child) in obj_files {
info!("adding bitcode from {}", name);
- match get_bitcode_slice_from_object_data(child.data()) {
+ match get_bitcode_slice_from_object_data(
+ child.data(&*archive_data).expect("corrupt rlib"),
+ ) {
Ok(data) => {
let module = SerializedModule::FromRlib(data.to_vec());
upstream_modules.push((module, CString::new(name).unwrap()));
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 534d32e8a..a695df840 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -5,7 +5,7 @@ use crate::back::profiling::{
use crate::base;
use crate::common;
use crate::consts;
-use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
+use crate::llvm::{self, DiagnosticInfo, PassManager};
use crate::llvm_util;
use crate::type_::Type;
use crate::LlvmCodegenBackend;
@@ -28,7 +28,6 @@ use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::InnerSpan;
use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo};
-use tracing::debug;
use libc::{c_char, c_int, c_uint, c_void, size_t};
use std::ffi::CString;
@@ -304,7 +303,6 @@ impl<'a> DiagnosticHandlers<'a> {
remark_passes.as_ptr(),
remark_passes.len(),
);
- llvm::LLVMRustSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, data.cast());
DiagnosticHandlers { data, llcx, old_handler }
}
}
@@ -312,9 +310,7 @@ impl<'a> DiagnosticHandlers<'a> {
impl<'a> Drop for DiagnosticHandlers<'a> {
fn drop(&mut self) {
- use std::ptr::null_mut;
unsafe {
- llvm::LLVMRustSetInlineAsmDiagnosticHandler(self.llcx, inline_asm_handler, null_mut());
llvm::LLVMRustContextSetDiagnosticHandler(self.llcx, self.old_handler);
drop(Box::from_raw(self.data));
}
@@ -342,16 +338,6 @@ fn report_inline_asm(
cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
}
-unsafe extern "C" fn inline_asm_handler(diag: &SMDiagnostic, user: *const c_void, cookie: c_uint) {
- if user.is_null() {
- return;
- }
- let (cgcx, _) = *(user as *const (&CodegenContext<LlvmCodegenBackend>, &Handler));
-
- let smdiag = llvm::diagnostic::SrcMgrDiagnostic::unpack(diag);
- report_inline_asm(cgcx, smdiag.message, smdiag.level, cookie, smdiag.source);
-}
-
unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
if user.is_null() {
return;
@@ -423,6 +409,14 @@ fn get_pgo_sample_use_path(config: &ModuleConfig) -> Option<CString> {
.map(|path_buf| CString::new(path_buf.to_string_lossy().as_bytes()).unwrap())
}
+fn get_instr_profile_output_path(config: &ModuleConfig) -> Option<CString> {
+ if config.instrument_coverage {
+ Some(CString::new("default_%m_%p.profraw").unwrap())
+ } else {
+ None
+ }
+}
+
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
cgcx: &CodegenContext<LlvmCodegenBackend>,
diag_handler: &Handler,
@@ -438,6 +432,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
let pgo_use_path = get_pgo_use_path(config);
let pgo_sample_use_path = get_pgo_sample_use_path(config);
let is_lto = opt_stage == llvm::OptStage::ThinLTO || opt_stage == llvm::OptStage::FatLTO;
+ let instr_profile_output_path = get_instr_profile_output_path(config);
// Sanitizer instrumentation is only inserted during the pre-link optimization stage.
let sanitizer_options = if !is_lto {
Some(llvm::SanitizerOptions {
@@ -488,6 +483,7 @@ pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.instrument_coverage,
+ instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.instrument_gcov,
pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
config.debug_info_for_profiling,