Skip to content

Commit c79419a

Browse files
committed
Auto merge of #84449 - alexcrichton:metadata-in-object, r=nagisa
rustc: Store metadata-in-rlibs in object files This commit updates how rustc compiler metadata is stored in rlibs. Previously metadata was stored as a raw file that has the same format as `--emit metadata`. After this commit, however, the metadata is encoded into a small object file which has one section which is the contents of the metadata. The motivation for this commit is to fix a common case where #83730 arises. The problem is that when rustc crates a `dylib` crate type it needs to include entire rlib files into the dylib, so it passes `--whole-archive` (or the equivalent) to the linker. The problem with this, though, is that the linker will attempt to read all files in the archive. If the metadata file were left as-is (today) then the linker would generate an error saying it can't read the file. The previous solution was to alter the rlib just before linking, creating a new archive in a temporary directory which has the metadata file removed. This problem from before this commit is now removed if the metadata file is stored in an object file that the linker can read. The only caveat we have to take care of is to ensure that the linker never actually includes the contents of the object file into the final output. We apply similar tricks as the `.llvmbc` bytecode sections to do this. This involved changing the metadata loading code a bit, namely updating some of the LLVM C APIs used to use non-deprecated ones and fiddling with the lifetimes a bit to get everything to work out. Otherwise though this isn't intended to be a functional change really, only that metadata is stored differently in archives now. This should end up fixing #83730 because by default dylibs will no longer have their rlib dependencies "altered" meaning that split-debuginfo will continue to have valid paths pointing at the original rlibs. (note that we still "alter" rlibs if LTO is enabled to remove Rust object files and we also "alter" for the #[link(cfg)] feature, but that's rarely used). Closes #83730
2 parents efc4e37 + 0e03387 commit c79419a

File tree

8 files changed

+212
-182
lines changed

8 files changed

+212
-182
lines changed

Cargo.lock

+15-4
Original file line numberDiff line numberDiff line change
@@ -2154,9 +2154,9 @@ dependencies = [
21542154

21552155
[[package]]
21562156
name = "memchr"
2157-
version = "2.3.3"
2157+
version = "2.4.0"
21582158
source = "registry+https://github.com/rust-lang/crates.io-index"
2159-
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
2159+
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
21602160

21612161
[[package]]
21622162
name = "memmap2"
@@ -2359,6 +2359,17 @@ dependencies = [
23592359
"rustc-std-workspace-core",
23602360
]
23612361

2362+
[[package]]
2363+
name = "object"
2364+
version = "0.25.2"
2365+
source = "registry+https://github.com/rust-lang/crates.io-index"
2366+
checksum = "f8bc1d42047cf336f0f939c99e97183cf31551bf0f2865a2ec9c8d91fd4ffb5e"
2367+
dependencies = [
2368+
"crc32fast",
2369+
"indexmap",
2370+
"memchr",
2371+
]
2372+
23622373
[[package]]
23632374
name = "once_cell"
23642375
version = "1.7.2"
@@ -3701,7 +3712,7 @@ dependencies = [
37013712
"itertools 0.9.0",
37023713
"jobserver",
37033714
"libc",
3704-
"object",
3715+
"object 0.25.2",
37053716
"pathdiff",
37063717
"rustc_apfloat",
37073718
"rustc_ast",
@@ -4912,7 +4923,7 @@ dependencies = [
49124923
"hermit-abi",
49134924
"libc",
49144925
"miniz_oxide",
4915-
"object",
4926+
"object 0.22.0",
49164927
"panic_abort",
49174928
"panic_unwind",
49184929
"profiler_builtins",

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

-40
Original file line numberDiff line numberDiff line change
@@ -582,11 +582,6 @@ pub struct PassManager<'a>(InvariantOpaque<'a>);
582582
extern "C" {
583583
pub type PassManagerBuilder;
584584
}
585-
extern "C" {
586-
pub type ObjectFile;
587-
}
588-
#[repr(C)]
589-
pub struct SectionIterator<'a>(InvariantOpaque<'a>);
590585
extern "C" {
591586
pub type Pass;
592587
}
@@ -1703,35 +1698,6 @@ extern "C" {
17031698

17041699
pub fn LLVMDisposeMessage(message: *mut c_char);
17051700

1706-
// Stuff that's in llvm-wrapper/ because it's not upstream yet.
1707-
1708-
/// Opens an object file.
1709-
pub fn LLVMCreateObjectFile(
1710-
MemBuf: &'static mut MemoryBuffer,
1711-
) -> Option<&'static mut ObjectFile>;
1712-
/// Closes an object file.
1713-
pub fn LLVMDisposeObjectFile(ObjFile: &'static mut ObjectFile);
1714-
1715-
/// Enumerates the sections in an object file.
1716-
pub fn LLVMGetSections(ObjFile: &'a ObjectFile) -> &'a mut SectionIterator<'a>;
1717-
/// Destroys a section iterator.
1718-
pub fn LLVMDisposeSectionIterator(SI: &'a mut SectionIterator<'a>);
1719-
/// Returns `true` if the section iterator is at the end of the section
1720-
/// list:
1721-
pub fn LLVMIsSectionIteratorAtEnd(ObjFile: &'a ObjectFile, SI: &SectionIterator<'a>) -> Bool;
1722-
/// Moves the section iterator to point to the next section.
1723-
pub fn LLVMMoveToNextSection(SI: &SectionIterator<'_>);
1724-
/// Returns the current section size.
1725-
pub fn LLVMGetSectionSize(SI: &SectionIterator<'_>) -> c_ulonglong;
1726-
/// Returns the current section contents as a string buffer.
1727-
pub fn LLVMGetSectionContents(SI: &SectionIterator<'_>) -> *const c_char;
1728-
1729-
/// Reads the given file and returns it as a memory buffer. Use
1730-
/// LLVMDisposeMemoryBuffer() to get rid of it.
1731-
pub fn LLVMRustCreateMemoryBufferWithContentsOfFile(
1732-
Path: *const c_char,
1733-
) -> Option<&'static mut MemoryBuffer>;
1734-
17351701
pub fn LLVMStartMultithreaded() -> Bool;
17361702

17371703
/// Returns a string describing the last error caused by an LLVMRust* call.
@@ -2236,12 +2202,6 @@ extern "C" {
22362202
pub fn LLVMRustArchiveIteratorFree(AIR: &'a mut ArchiveIterator<'a>);
22372203
pub fn LLVMRustDestroyArchive(AR: &'static mut Archive);
22382204

2239-
#[allow(improper_ctypes)]
2240-
pub fn LLVMRustGetSectionName(
2241-
SI: &SectionIterator<'_>,
2242-
data: &mut Option<std::ptr::NonNull<c_char>>,
2243-
) -> size_t;
2244-
22452205
#[allow(improper_ctypes)]
22462206
pub fn LLVMRustWriteTwineToString(T: &Twine, s: &RustString);
22472207

compiler/rustc_codegen_llvm/src/llvm/mod.rs

-44
Original file line numberDiff line numberDiff line change
@@ -150,50 +150,6 @@ impl Attribute {
150150
}
151151
}
152152

153-
// Memory-managed interface to object files.
154-
155-
pub struct ObjectFile {
156-
pub llof: &'static mut ffi::ObjectFile,
157-
}
158-
159-
unsafe impl Send for ObjectFile {}
160-
161-
impl ObjectFile {
162-
// This will take ownership of llmb
163-
pub fn new(llmb: &'static mut MemoryBuffer) -> Option<ObjectFile> {
164-
unsafe {
165-
let llof = LLVMCreateObjectFile(llmb)?;
166-
Some(ObjectFile { llof })
167-
}
168-
}
169-
}
170-
171-
impl Drop for ObjectFile {
172-
fn drop(&mut self) {
173-
unsafe {
174-
LLVMDisposeObjectFile(&mut *(self.llof as *mut _));
175-
}
176-
}
177-
}
178-
179-
// Memory-managed interface to section iterators.
180-
181-
pub struct SectionIter<'a> {
182-
pub llsi: &'a mut SectionIterator<'a>,
183-
}
184-
185-
impl Drop for SectionIter<'a> {
186-
fn drop(&mut self) {
187-
unsafe {
188-
LLVMDisposeSectionIterator(&mut *(self.llsi as *mut _));
189-
}
190-
}
191-
}
192-
193-
pub fn mk_section_iter(llof: &ffi::ObjectFile) -> SectionIter<'_> {
194-
unsafe { SectionIter { llsi: LLVMGetSections(llof) } }
195-
}
196-
197153
pub fn set_section(llglobal: &Value, section_name: &str) {
198154
let section_name_cstr = CString::new(section_name).expect("unexpected CString error");
199155
unsafe {

compiler/rustc_codegen_ssa/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ rustc_target = { path = "../rustc_target" }
3535
rustc_session = { path = "../rustc_session" }
3636

3737
[dependencies.object]
38-
version = "0.22.0"
38+
version = "0.25.2"
3939
default-features = false
40-
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive"]
40+
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]

0 commit comments

Comments
 (0)