bytes: &'a [u8],
section: &str,
) -> Result<&'a [u8], String> {
- let file = match object::File::parse(bytes) {
- Ok(f) => f,
+ let Ok(file) = object::File::parse(bytes) else {
// The parse above could fail for odd reasons like corruption, but for
// now we just interpret it as this target doesn't support metadata
// emission in object files so the entire byte slice itself is probably
// a metadata file. Ideally though if necessary we could at least check
// the prefix of bytes to see if it's an actual metadata object and if
// not forward the error along here.
- Err(_) => return Ok(bytes),
+ return Ok(bytes);
};
file.section_by_name(section)
.ok_or_else(|| format!("no `{}` section in '{}'", section, path.display()))?
Some(file)
}
+pub enum MetadataPosition {
+ First,
+ Last,
+}
+
// For rlibs we "pack" rustc metadata into a dummy object file. When rustc
// creates a dylib crate type it will pass `--whole-archive` (or the
// platform equivalent) to include all object files from an rlib into the
// * ELF - All other targets are similar to Windows in that there's a
// `SHF_EXCLUDE` flag we can set on sections in an object file to get
// automatically removed from the final output.
-pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> Vec<u8> {
+pub fn create_rmeta_file(sess: &Session, metadata: &[u8]) -> (Vec<u8>, MetadataPosition) {
let Some(mut file) = create_object_file(sess) else {
// This is used to handle all "other" targets. This includes targets
// in two categories:
// WebAssembly and for targets not supported by the `object` crate
// yet it means that work will need to be done in the `object` crate
// to add a case above.
- return metadata.to_vec();
+ return (metadata.to_vec(), MetadataPosition::Last);
};
let section = file.add_section(
file.segment_name(StandardSegment::Debug).to_vec(),
_ => {}
};
file.append_section_data(section, metadata, 1);
- file.write().unwrap()
+ (file.write().unwrap(), MetadataPosition::First)
}
// Historical note: