Auto merge of #145721 - dpaoliello:ar050, r=bjorn3
Update to ar_archive_writer 0.5 This updates `ar_archive_writer` to 0.5, which in turn was updated to match LLVM 20.1.8: <https://github.com/rust-lang/ar_archive_writer/pull/24> As part of this, I refactored part of `SymbolWrapper.cpp` to pull common code that I was about to duplicate again into a new function. NOTE: `ar_archive_writer` does include a breaking change where it no longer supports mangling C++ mangled names for Arm64EC. Since we don't need the mangled name (it's not the "exported name" which we're trying to load from the external dll), I'm setting the `import_name` when building for Arm64EC to prevent error when failing to mangle. r? `@bjorn3`
This commit is contained in:
commit
7aef4bec4b
6 changed files with 84 additions and 58 deletions
|
|
@ -158,11 +158,11 @@ checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
|||
|
||||
[[package]]
|
||||
name = "ar_archive_writer"
|
||||
version = "0.4.2"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "01667f6f40216b9a0b2945e05fed5f1ad0ab6470e69cb9378001e37b1c0668e4"
|
||||
checksum = "7eb93bbb63b9c227414f6eb3a0adfddca591a8ce1e9b60661bb08969b87e340b"
|
||||
dependencies = [
|
||||
"object 0.36.7",
|
||||
"object 0.37.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ static LLVM_OBJECT_READER: ObjectReader = ObjectReader {
|
|||
get_symbols: get_llvm_object_symbols,
|
||||
is_64_bit_object_file: llvm_is_64_bit_object_file,
|
||||
is_ec_object_file: llvm_is_ec_object_file,
|
||||
is_any_arm64_coff: llvm_is_any_arm64_coff,
|
||||
get_xcoff_member_alignment: DEFAULT_OBJECT_READER.get_xcoff_member_alignment,
|
||||
};
|
||||
|
||||
|
|
@ -95,3 +96,7 @@ fn llvm_is_64_bit_object_file(buf: &[u8]) -> bool {
|
|||
fn llvm_is_ec_object_file(buf: &[u8]) -> bool {
|
||||
unsafe { llvm::LLVMRustIsECObject(buf.as_ptr(), buf.len()) }
|
||||
}
|
||||
|
||||
fn llvm_is_any_arm64_coff(buf: &[u8]) -> bool {
|
||||
unsafe { llvm::LLVMRustIsAnyArm64Coff(buf.as_ptr(), buf.len()) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2686,6 +2686,8 @@ unsafe extern "C" {
|
|||
|
||||
pub(crate) fn LLVMRustIsECObject(buf_ptr: *const u8, buf_len: usize) -> bool;
|
||||
|
||||
pub(crate) fn LLVMRustIsAnyArm64Coff(buf_ptr: *const u8, buf_len: usize) -> bool;
|
||||
|
||||
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
|
||||
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ edition = "2024"
|
|||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
ar_archive_writer = "0.4.2"
|
||||
ar_archive_writer = "0.5"
|
||||
bitflags.workspace = true
|
||||
bstr = "1.11.3"
|
||||
# `cc` updates often break things, so we pin it here. Cargo enforces "max 1 semver-compat version
|
||||
|
|
|
|||
|
|
@ -40,16 +40,18 @@ pub struct ImportLibraryItem {
|
|||
pub is_data: bool,
|
||||
}
|
||||
|
||||
impl From<ImportLibraryItem> for COFFShortExport {
|
||||
fn from(item: ImportLibraryItem) -> Self {
|
||||
impl ImportLibraryItem {
|
||||
fn into_coff_short_export(self, sess: &Session) -> COFFShortExport {
|
||||
let import_name = (sess.target.arch == "arm64ec").then(|| self.name.clone());
|
||||
COFFShortExport {
|
||||
name: item.name,
|
||||
name: self.name,
|
||||
ext_name: None,
|
||||
symbol_name: item.symbol_name,
|
||||
alias_target: None,
|
||||
ordinal: item.ordinal.unwrap_or(0),
|
||||
noname: item.ordinal.is_some(),
|
||||
data: item.is_data,
|
||||
symbol_name: self.symbol_name,
|
||||
import_name,
|
||||
export_as: None,
|
||||
ordinal: self.ordinal.unwrap_or(0),
|
||||
noname: self.ordinal.is_some(),
|
||||
data: self.is_data,
|
||||
private: false,
|
||||
constant: false,
|
||||
}
|
||||
|
|
@ -113,7 +115,8 @@ pub trait ArchiveBuilderBuilder {
|
|||
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() }),
|
||||
};
|
||||
|
||||
let exports = items.into_iter().map(Into::into).collect::<Vec<_>>();
|
||||
let exports =
|
||||
items.into_iter().map(|item| item.into_coff_short_export(sess)).collect::<Vec<_>>();
|
||||
let machine = match &*sess.target.arch {
|
||||
"x86_64" => MachineTypes::AMD64,
|
||||
"x86" => MachineTypes::I386,
|
||||
|
|
@ -134,6 +137,7 @@ pub trait ArchiveBuilderBuilder {
|
|||
// when linking a rust staticlib using `/WHOLEARCHIVE`.
|
||||
// See #129020
|
||||
true,
|
||||
&[],
|
||||
) {
|
||||
sess.dcx()
|
||||
.emit_fatal(ErrorCreatingImportLibrary { lib_name, error: error.to_string() });
|
||||
|
|
@ -527,7 +531,7 @@ impl<'a> ArArchiveBuilder<'a> {
|
|||
&entries,
|
||||
archive_kind,
|
||||
false,
|
||||
/* is_ec = */ self.sess.target.arch == "arm64ec",
|
||||
/* is_ec = */ Some(self.sess.target.arch == "arm64ec"),
|
||||
)?;
|
||||
archive_tmpfile.flush()?;
|
||||
drop(archive_tmpfile);
|
||||
|
|
|
|||
|
|
@ -103,28 +103,9 @@ LLVMRustGetSymbols(char *BufPtr, size_t BufLen, void *State,
|
|||
#define TRUE_PTR (void *)1
|
||||
#define FALSE_PTR (void *)0
|
||||
|
||||
extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
|
||||
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
|
||||
SmallString<0> SymNameBuf;
|
||||
auto SymName = raw_svector_ostream(SymNameBuf);
|
||||
|
||||
// Code starting from this line is copied from s64BitSymbolicFile in
|
||||
// ArchiveWriter.cpp.
|
||||
// In the scenario when LLVMContext is populated SymbolicFile will contain a
|
||||
// reference to it, thus SymbolicFile should be destroyed first.
|
||||
LLVMContext Context;
|
||||
Expected<std::unique_ptr<object::SymbolicFile>> ObjOrErr =
|
||||
getSymbolicFile(Buf->getMemBufferRef(), Context);
|
||||
if (!ObjOrErr) {
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
|
||||
|
||||
return Obj != nullptr ? Obj->is64Bit() : false;
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
|
||||
bool withBufferAsSymbolicFile(
|
||||
char *BufPtr, size_t BufLen,
|
||||
std::function<bool(object::SymbolicFile &)> Callback) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(
|
||||
StringRef(BufPtr, BufLen), StringRef("LLVMRustGetSymbolsObject"), false);
|
||||
SmallString<0> SymNameBuf;
|
||||
|
|
@ -139,29 +120,63 @@ extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
|
|||
return false;
|
||||
}
|
||||
std::unique_ptr<object::SymbolicFile> Obj = std::move(*ObjOrErr);
|
||||
|
||||
if (Obj == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Code starting from this line is copied from isECObject in
|
||||
// ArchiveWriter.cpp with an extra #if to work with LLVM 17.
|
||||
if (Obj->isCOFF())
|
||||
return cast<llvm::object::COFFObjectFile>(&*Obj)->getMachine() !=
|
||||
COFF::IMAGE_FILE_MACHINE_ARM64;
|
||||
|
||||
if (Obj->isCOFFImportFile())
|
||||
return cast<llvm::object::COFFImportFile>(&*Obj)->getMachine() !=
|
||||
COFF::IMAGE_FILE_MACHINE_ARM64;
|
||||
|
||||
if (Obj->isIR()) {
|
||||
Expected<std::string> TripleStr =
|
||||
getBitcodeTargetTriple(Obj->getMemoryBufferRef());
|
||||
if (!TripleStr)
|
||||
return false;
|
||||
Triple T(*TripleStr);
|
||||
return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
|
||||
}
|
||||
|
||||
return false;
|
||||
return Callback(*Obj);
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustIs64BitSymbolicFile(char *BufPtr, size_t BufLen) {
|
||||
return withBufferAsSymbolicFile(
|
||||
BufPtr, BufLen, [](object::SymbolicFile &Obj) { return Obj.is64Bit(); });
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
|
||||
return withBufferAsSymbolicFile(
|
||||
BufPtr, BufLen, [](object::SymbolicFile &Obj) {
|
||||
// Code starting from this line is copied from isECObject in
|
||||
// ArchiveWriter.cpp with an extra #if to work with LLVM 17.
|
||||
if (Obj.isCOFF())
|
||||
return cast<llvm::object::COFFObjectFile>(&Obj)->getMachine() !=
|
||||
COFF::IMAGE_FILE_MACHINE_ARM64;
|
||||
|
||||
if (Obj.isCOFFImportFile())
|
||||
return cast<llvm::object::COFFImportFile>(&Obj)->getMachine() !=
|
||||
COFF::IMAGE_FILE_MACHINE_ARM64;
|
||||
|
||||
if (Obj.isIR()) {
|
||||
Expected<std::string> TripleStr =
|
||||
getBitcodeTargetTriple(Obj.getMemoryBufferRef());
|
||||
if (!TripleStr)
|
||||
return false;
|
||||
Triple T(*TripleStr);
|
||||
return T.isWindowsArm64EC() || T.getArch() == Triple::x86_64;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" bool LLVMRustIsAnyArm64Coff(char *BufPtr, size_t BufLen) {
|
||||
return withBufferAsSymbolicFile(
|
||||
BufPtr, BufLen, [](object::SymbolicFile &Obj) {
|
||||
// Code starting from this line is copied from isAnyArm64COFF in
|
||||
// ArchiveWriter.cpp.
|
||||
if (Obj.isCOFF())
|
||||
return COFF::isAnyArm64(cast<COFFObjectFile>(&Obj)->getMachine());
|
||||
|
||||
if (Obj.isCOFFImportFile())
|
||||
return COFF::isAnyArm64(cast<COFFImportFile>(&Obj)->getMachine());
|
||||
|
||||
if (Obj.isIR()) {
|
||||
Expected<std::string> TripleStr =
|
||||
getBitcodeTargetTriple(Obj.getMemoryBufferRef());
|
||||
if (!TripleStr)
|
||||
return false;
|
||||
Triple T(*TripleStr);
|
||||
return T.isOSWindows() && T.getArch() == Triple::aarch64;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue