Sync from rust fd02567705326884ddb94535d2ab230a9595dc2a
This commit is contained in:
commit
b8a3c2dd30
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -19,11 +19,6 @@ version = "1.0.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142"
|
||||
|
||||
[[package]]
|
||||
name = "ar"
|
||||
version = "0.8.0"
|
||||
source = "git+https://github.com/bjorn3/rust-ar.git?branch=do_not_remove_cg_clif_ranlib#de9ab0e56bf3a208381d342aa5b60f9ff2891648"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.2"
|
||||
@ -348,7 +343,6 @@ dependencies = [
|
||||
name = "rustc_codegen_cranelift"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ar",
|
||||
"cranelift-codegen",
|
||||
"cranelift-frontend",
|
||||
"cranelift-jit",
|
||||
|
@ -25,7 +25,6 @@ target-lexicon = "0.12.0"
|
||||
gimli = { version = "0.26.0", default-features = false, features = ["write"]}
|
||||
object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] }
|
||||
|
||||
ar = { git = "https://github.com/bjorn3/rust-ar.git", branch = "do_not_remove_cg_clif_ranlib" }
|
||||
indexmap = "1.9.1"
|
||||
libloading = { version = "0.7.3", optional = true }
|
||||
once_cell = "1.10.0"
|
||||
|
@ -207,5 +207,5 @@ pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
|
||||
}
|
||||
|
||||
pub(crate) fn is_ci() -> bool {
|
||||
env::var("CI").as_ref().map(|val| &**val) == Ok("true")
|
||||
env::var("CI").as_deref() == Ok("true")
|
||||
}
|
||||
|
224
src/archive.rs
224
src/archive.rs
@ -1,35 +1,15 @@
|
||||
//! Creation of ar archives like for the lib and staticlib crate type
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read, Seek};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
|
||||
use rustc_codegen_ssa::back::archive::{
|
||||
get_native_object_symbols, ArArchiveBuilder, ArchiveBuilder, ArchiveBuilderBuilder,
|
||||
};
|
||||
use rustc_session::Session;
|
||||
|
||||
use object::read::archive::ArchiveFile;
|
||||
use object::{Object, ObjectSymbol, ReadCache};
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ArchiveEntry {
|
||||
FromArchive { archive_index: usize, file_range: (u64, u64) },
|
||||
File(PathBuf),
|
||||
}
|
||||
|
||||
pub(crate) struct ArArchiveBuilderBuilder;
|
||||
|
||||
impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
||||
fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box<dyn ArchiveBuilder<'a> + 'a> {
|
||||
Box::new(ArArchiveBuilder {
|
||||
sess,
|
||||
use_gnu_style_archive: sess.target.archive_format == "gnu",
|
||||
// FIXME fix builtin ranlib on macOS
|
||||
no_builtin_ranlib: sess.target.is_like_osx,
|
||||
|
||||
src_archives: vec![],
|
||||
entries: vec![],
|
||||
})
|
||||
Box::new(ArArchiveBuilder::new(sess, get_native_object_symbols))
|
||||
}
|
||||
|
||||
fn create_dll_import_lib(
|
||||
@ -40,200 +20,6 @@ impl ArchiveBuilderBuilder for ArArchiveBuilderBuilder {
|
||||
_tmpdir: &Path,
|
||||
_is_direct_dependency: bool,
|
||||
) -> PathBuf {
|
||||
bug!("creating dll imports is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct ArArchiveBuilder<'a> {
|
||||
sess: &'a Session,
|
||||
use_gnu_style_archive: bool,
|
||||
no_builtin_ranlib: bool,
|
||||
|
||||
src_archives: Vec<File>,
|
||||
// Don't use `HashMap` here, as the order is important. `rust.metadata.bin` must always be at
|
||||
// the end of an archive for linkers to not get confused.
|
||||
entries: Vec<(Vec<u8>, ArchiveEntry)>,
|
||||
}
|
||||
|
||||
impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
|
||||
fn add_file(&mut self, file: &Path) {
|
||||
self.entries.push((
|
||||
file.file_name().unwrap().to_str().unwrap().to_string().into_bytes(),
|
||||
ArchiveEntry::File(file.to_owned()),
|
||||
));
|
||||
}
|
||||
|
||||
fn add_archive(
|
||||
&mut self,
|
||||
archive_path: &Path,
|
||||
mut skip: Box<dyn FnMut(&str) -> bool + 'static>,
|
||||
) -> std::io::Result<()> {
|
||||
let read_cache = ReadCache::new(std::fs::File::open(&archive_path)?);
|
||||
let archive = ArchiveFile::parse(&read_cache).unwrap();
|
||||
let archive_index = self.src_archives.len();
|
||||
|
||||
for entry in archive.members() {
|
||||
let entry = entry.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
|
||||
let file_name = String::from_utf8(entry.name().to_vec())
|
||||
.map_err(|err| io::Error::new(io::ErrorKind::InvalidData, err))?;
|
||||
if !skip(&file_name) {
|
||||
self.entries.push((
|
||||
file_name.into_bytes(),
|
||||
ArchiveEntry::FromArchive { archive_index, file_range: entry.file_range() },
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
self.src_archives.push(read_cache.into_inner());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build(mut self: Box<Self>, output: &Path) -> bool {
|
||||
enum BuilderKind {
|
||||
Bsd(ar::Builder<File>),
|
||||
Gnu(ar::GnuBuilder<File>),
|
||||
}
|
||||
|
||||
let sess = self.sess;
|
||||
|
||||
let mut symbol_table = BTreeMap::new();
|
||||
|
||||
let mut entries = Vec::new();
|
||||
|
||||
for (mut entry_name, entry) in self.entries {
|
||||
// FIXME only read the symbol table of the object files to avoid having to keep all
|
||||
// object files in memory at once, or read them twice.
|
||||
let data = match entry {
|
||||
ArchiveEntry::FromArchive { archive_index, file_range } => {
|
||||
// FIXME read symbols from symtab
|
||||
let src_read_cache = &mut self.src_archives[archive_index];
|
||||
|
||||
src_read_cache.seek(io::SeekFrom::Start(file_range.0)).unwrap();
|
||||
let mut data = std::vec::from_elem(0, usize::try_from(file_range.1).unwrap());
|
||||
src_read_cache.read_exact(&mut data).unwrap();
|
||||
|
||||
data
|
||||
}
|
||||
ArchiveEntry::File(file) => std::fs::read(file).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!(
|
||||
"error while reading object file during archive building: {}",
|
||||
err
|
||||
));
|
||||
}),
|
||||
};
|
||||
|
||||
if !self.no_builtin_ranlib {
|
||||
if symbol_table.contains_key(&entry_name) {
|
||||
// The ar crate can't handle creating a symbol table in case of multiple archive
|
||||
// members with the same name. Work around this by prepending a number until we
|
||||
// get a unique name.
|
||||
for i in 1.. {
|
||||
let new_name = format!("{}_", i)
|
||||
.into_bytes()
|
||||
.into_iter()
|
||||
.chain(entry_name.iter().copied())
|
||||
.collect::<Vec<_>>();
|
||||
if !symbol_table.contains_key(&new_name) {
|
||||
entry_name = new_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match object::File::parse(&*data) {
|
||||
Ok(object) => {
|
||||
symbol_table.insert(
|
||||
entry_name.to_vec(),
|
||||
object
|
||||
.symbols()
|
||||
.filter_map(|symbol| {
|
||||
if symbol.is_undefined() || symbol.is_local() {
|
||||
None
|
||||
} else {
|
||||
symbol.name().map(|name| name.as_bytes().to_vec()).ok()
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
let err = err.to_string();
|
||||
if err == "Unknown file magic" {
|
||||
// Not an object file; skip it.
|
||||
} else if object::read::archive::ArchiveFile::parse(&*data).is_ok() {
|
||||
// Nested archive file; skip it.
|
||||
} else {
|
||||
sess.fatal(&format!(
|
||||
"error parsing `{}` during archive creation: {}",
|
||||
String::from_utf8_lossy(&entry_name),
|
||||
err
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entries.push((entry_name, data));
|
||||
}
|
||||
|
||||
let mut builder = if self.use_gnu_style_archive {
|
||||
BuilderKind::Gnu(
|
||||
ar::GnuBuilder::new(
|
||||
File::create(output).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!(
|
||||
"error opening destination during archive building: {}",
|
||||
err
|
||||
));
|
||||
}),
|
||||
entries.iter().map(|(name, _)| name.clone()).collect(),
|
||||
ar::GnuSymbolTableFormat::Size32,
|
||||
symbol_table,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
BuilderKind::Bsd(
|
||||
ar::Builder::new(
|
||||
File::create(output).unwrap_or_else(|err| {
|
||||
sess.fatal(&format!(
|
||||
"error opening destination during archive building: {}",
|
||||
err
|
||||
));
|
||||
}),
|
||||
symbol_table,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
};
|
||||
|
||||
let any_members = !entries.is_empty();
|
||||
|
||||
// Add all files
|
||||
for (entry_name, data) in entries.into_iter() {
|
||||
let header = ar::Header::new(entry_name, data.len() as u64);
|
||||
match builder {
|
||||
BuilderKind::Bsd(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
|
||||
BuilderKind::Gnu(ref mut builder) => builder.append(&header, &mut &*data).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize archive
|
||||
std::mem::drop(builder);
|
||||
|
||||
if self.no_builtin_ranlib {
|
||||
let ranlib = crate::toolchain::get_toolchain_binary(self.sess, "ranlib");
|
||||
|
||||
// Run ranlib to be able to link the archive
|
||||
let status = std::process::Command::new(ranlib)
|
||||
.arg(output)
|
||||
.status()
|
||||
.expect("Couldn't run ranlib");
|
||||
|
||||
if !status.success() {
|
||||
self.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
|
||||
}
|
||||
}
|
||||
|
||||
any_members
|
||||
unimplemented!("creating dll imports is not yet supported");
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use std::env;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn bool_env_var(key: &str) -> bool {
|
||||
env::var(key).as_ref().map(|val| &**val) == Ok("1")
|
||||
env::var(key).as_deref() == Ok("1")
|
||||
}
|
||||
|
||||
/// The mode to use for compilation.
|
||||
|
@ -255,9 +255,9 @@ pub(crate) fn data_id_for_alloc_id(
|
||||
mutability: rustc_hir::Mutability,
|
||||
) -> DataId {
|
||||
cx.todo.push(TodoItem::Alloc(alloc_id));
|
||||
*cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
|
||||
module.declare_anonymous_data(mutability == rustc_hir::Mutability::Mut, false).unwrap()
|
||||
})
|
||||
*cx.anon_allocs
|
||||
.entry(alloc_id)
|
||||
.or_insert_with(|| module.declare_anonymous_data(mutability.is_mut(), false).unwrap())
|
||||
}
|
||||
|
||||
fn data_id_for_static(
|
||||
@ -341,12 +341,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
|
||||
}
|
||||
};
|
||||
let data_id = *cx.anon_allocs.entry(alloc_id).or_insert_with(|| {
|
||||
module
|
||||
.declare_anonymous_data(
|
||||
alloc.inner().mutability == rustc_hir::Mutability::Mut,
|
||||
false,
|
||||
)
|
||||
.unwrap()
|
||||
module.declare_anonymous_data(alloc.inner().mutability.is_mut(), false).unwrap()
|
||||
});
|
||||
(data_id, alloc, None)
|
||||
}
|
||||
|
@ -108,8 +108,8 @@ impl<'tcx> CValue<'tcx> {
|
||||
}
|
||||
|
||||
// FIXME remove
|
||||
// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the
|
||||
// vtable pointer.
|
||||
/// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the
|
||||
/// vtable pointer.
|
||||
pub(crate) fn dyn_star_force_data_on_stack(
|
||||
self,
|
||||
fx: &mut FunctionCx<'_, '_, 'tcx>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user