Rollup merge of #136637 - Pyr0de:binary-format, r=Noratrieb
Add binary_format to rustc target specs Added binary format field to `TargetOptions` Fixes #135724 r? `@Noratrieb`
This commit is contained in:
commit
2c6fa32bdc
11 changed files with 102 additions and 48 deletions
|
@ -252,15 +252,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
|
|||
// Unsupported architecture.
|
||||
_ => return None,
|
||||
};
|
||||
let binary_format = if sess.target.is_like_osx {
|
||||
BinaryFormat::MachO
|
||||
} else if sess.target.is_like_windows {
|
||||
BinaryFormat::Coff
|
||||
} else if sess.target.is_like_aix {
|
||||
BinaryFormat::Xcoff
|
||||
} else {
|
||||
BinaryFormat::Elf
|
||||
};
|
||||
let binary_format = sess.target.binary_format.to_object();
|
||||
|
||||
let mut file = write::Object::new(binary_format, architecture, endianness);
|
||||
file.set_sub_architecture(sub_architecture);
|
||||
|
|
|
@ -8,7 +8,7 @@ use rustc_middle::ty::{Instance, Ty, TyCtxt};
|
|||
use rustc_middle::{bug, span_bug, ty};
|
||||
use rustc_span::sym;
|
||||
use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
|
||||
use rustc_target::spec::WasmCAbi;
|
||||
use rustc_target::spec::{BinaryFormat, WasmCAbi};
|
||||
|
||||
use crate::common;
|
||||
use crate::traits::{AsmCodegenMethods, BuilderMethods, GlobalAsmOperandRef, MiscCodegenMethods};
|
||||
|
@ -104,27 +104,6 @@ fn inline_to_global_operand<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
}
|
||||
}
|
||||
|
||||
enum AsmBinaryFormat {
|
||||
Elf,
|
||||
Macho,
|
||||
Coff,
|
||||
Wasm,
|
||||
}
|
||||
|
||||
impl AsmBinaryFormat {
|
||||
fn from_target(target: &rustc_target::spec::Target) -> Self {
|
||||
if target.is_like_windows {
|
||||
Self::Coff
|
||||
} else if target.is_like_osx {
|
||||
Self::Macho
|
||||
} else if target.is_like_wasm {
|
||||
Self::Wasm
|
||||
} else {
|
||||
Self::Elf
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn prefix_and_suffix<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
|
@ -134,7 +113,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
) -> (String, String) {
|
||||
use std::fmt::Write;
|
||||
|
||||
let asm_binary_format = AsmBinaryFormat::from_target(&tcx.sess.target);
|
||||
let asm_binary_format = &tcx.sess.target.binary_format;
|
||||
|
||||
let is_arm = tcx.sess.target.arch == "arm";
|
||||
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
|
||||
|
@ -178,10 +157,13 @@ fn prefix_and_suffix<'tcx>(
|
|||
}
|
||||
Linkage::LinkOnceAny | Linkage::LinkOnceODR | Linkage::WeakAny | Linkage::WeakODR => {
|
||||
match asm_binary_format {
|
||||
AsmBinaryFormat::Elf | AsmBinaryFormat::Coff | AsmBinaryFormat::Wasm => {
|
||||
BinaryFormat::Elf
|
||||
| BinaryFormat::Coff
|
||||
| BinaryFormat::Wasm
|
||||
| BinaryFormat::Xcoff => {
|
||||
writeln!(w, ".weak {asm_name}")?;
|
||||
}
|
||||
AsmBinaryFormat::Macho => {
|
||||
BinaryFormat::MachO => {
|
||||
writeln!(w, ".globl {asm_name}")?;
|
||||
writeln!(w, ".weak_definition {asm_name}")?;
|
||||
}
|
||||
|
@ -207,7 +189,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
let mut begin = String::new();
|
||||
let mut end = String::new();
|
||||
match asm_binary_format {
|
||||
AsmBinaryFormat::Elf => {
|
||||
BinaryFormat::Elf | BinaryFormat::Xcoff => {
|
||||
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
|
||||
|
||||
let progbits = match is_arm {
|
||||
|
@ -239,7 +221,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
writeln!(end, "{}", arch_suffix).unwrap();
|
||||
}
|
||||
}
|
||||
AsmBinaryFormat::Macho => {
|
||||
BinaryFormat::MachO => {
|
||||
let section = link_section.unwrap_or("__TEXT,__text".to_string());
|
||||
writeln!(begin, ".pushsection {},regular,pure_instructions", section).unwrap();
|
||||
writeln!(begin, ".balign {align}").unwrap();
|
||||
|
@ -255,7 +237,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
writeln!(end, "{}", arch_suffix).unwrap();
|
||||
}
|
||||
}
|
||||
AsmBinaryFormat::Coff => {
|
||||
BinaryFormat::Coff => {
|
||||
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
|
||||
writeln!(begin, ".pushsection {},\"xr\"", section).unwrap();
|
||||
writeln!(begin, ".balign {align}").unwrap();
|
||||
|
@ -272,7 +254,7 @@ fn prefix_and_suffix<'tcx>(
|
|||
writeln!(end, "{}", arch_suffix).unwrap();
|
||||
}
|
||||
}
|
||||
AsmBinaryFormat::Wasm => {
|
||||
BinaryFormat::Wasm => {
|
||||
let section = link_section.unwrap_or(format!(".text.{asm_name}"));
|
||||
|
||||
writeln!(begin, ".section {section},\"\",@").unwrap();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use rustc_abi::Endian;
|
||||
|
||||
use crate::spec::{Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs};
|
||||
use crate::spec::{
|
||||
BinaryFormat, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions, crt_objects, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
TargetOptions {
|
||||
|
@ -21,6 +23,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
linker: Some("ld".into()),
|
||||
eh_frame_header: false,
|
||||
is_like_aix: true,
|
||||
binary_format: BinaryFormat::Xcoff,
|
||||
default_dwarf_version: 3,
|
||||
function_sections: true,
|
||||
pre_link_objects: crt_objects::new(&[
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::borrow::Cow;
|
|||
use std::env;
|
||||
|
||||
use crate::spec::{
|
||||
Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi, SplitDebuginfo,
|
||||
StackProbeType, StaticCow, TargetOptions, cvs,
|
||||
BinaryFormat, Cc, DebuginfoKind, FloatAbi, FramePointer, LinkerFlavor, Lld, RustcAbi,
|
||||
SplitDebuginfo, StackProbeType, StaticCow, TargetOptions, cvs,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -116,6 +116,7 @@ pub(crate) fn base(
|
|||
dynamic_linking: true,
|
||||
families: cvs!["unix"],
|
||||
is_like_osx: true,
|
||||
binary_format: BinaryFormat::MachO,
|
||||
// LLVM notes that macOS 10.11+ and iOS 9+ default
|
||||
// to v4, so we do the same.
|
||||
// https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs};
|
||||
use crate::spec::{
|
||||
BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
let mut pre_link_args = TargetOptions::link_args(
|
||||
|
@ -32,6 +34,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
exe_suffix: ".exe".into(),
|
||||
families: cvs!["unix"],
|
||||
is_like_windows: true,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
allows_weak_linkage: false,
|
||||
pre_link_args,
|
||||
late_link_args,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
|
||||
use crate::spec::{BinaryFormat, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
// Suppress the verbose logo and authorship debugging output, which would needlessly
|
||||
|
@ -12,6 +12,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
dll_tls_export: false,
|
||||
is_like_windows: true,
|
||||
is_like_msvc: true,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
pre_link_args,
|
||||
abi_return_struct_as_int: true,
|
||||
emit_debug_gdb_scripts: false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::spec::{
|
||||
Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel,
|
||||
add_link_args, cvs,
|
||||
BinaryFormat, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel,
|
||||
TargetOptions, TlsModel, add_link_args, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn options() -> TargetOptions {
|
||||
|
@ -53,6 +53,7 @@ pub(crate) fn options() -> TargetOptions {
|
|||
|
||||
TargetOptions {
|
||||
is_like_wasm: true,
|
||||
binary_format: BinaryFormat::Wasm,
|
||||
families: cvs!["wasm"],
|
||||
|
||||
// we allow dynamic linking, but only cdylibs. Basically we allow a
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::spec::{
|
||||
Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions,
|
||||
add_link_args, crt_objects, cvs,
|
||||
BinaryFormat, Cc, DebuginfoKind, LinkSelfContainedDefault, LinkerFlavor, Lld, SplitDebuginfo,
|
||||
TargetOptions, add_link_args, crt_objects, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
|
@ -90,6 +90,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
exe_suffix: ".exe".into(),
|
||||
families: cvs!["windows"],
|
||||
is_like_windows: true,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
allows_weak_linkage: false,
|
||||
pre_link_args,
|
||||
pre_link_objects: crt_objects::pre_mingw(),
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::spec::{Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs};
|
||||
use crate::spec::{
|
||||
BinaryFormat, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions, cvs,
|
||||
};
|
||||
|
||||
pub(crate) fn opts() -> TargetOptions {
|
||||
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed
|
||||
|
@ -30,6 +32,7 @@ pub(crate) fn opts() -> TargetOptions {
|
|||
exe_suffix: ".exe".into(),
|
||||
families: cvs!["windows"],
|
||||
is_like_windows: true,
|
||||
binary_format: BinaryFormat::Coff,
|
||||
allows_weak_linkage: false,
|
||||
pre_link_args,
|
||||
late_link_args,
|
||||
|
|
|
@ -103,6 +103,19 @@ impl Target {
|
|||
base.$key_name = Some(s);
|
||||
}
|
||||
} );
|
||||
($key_name:ident, BinaryFormat) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.remove(&name).and_then(|f| f.as_str().and_then(|s| {
|
||||
match s.parse::<super::BinaryFormat>() {
|
||||
Ok(binary_format) => base.$key_name = binary_format,
|
||||
_ => return Some(Err(format!(
|
||||
"'{s}' is not a valid value for binary_format. \
|
||||
Use 'coff', 'elf', 'mach-o', 'wasm' or 'xcoff' "
|
||||
))),
|
||||
}
|
||||
Some(Ok(()))
|
||||
})).unwrap_or(Ok(()))
|
||||
} );
|
||||
($key_name:ident, MergeFunctions) => ( {
|
||||
let name = (stringify!($key_name)).replace("_", "-");
|
||||
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
|
||||
|
@ -585,6 +598,7 @@ impl Target {
|
|||
key!(is_like_msvc, bool);
|
||||
key!(is_like_wasm, bool);
|
||||
key!(is_like_android, bool);
|
||||
key!(binary_format, BinaryFormat)?;
|
||||
key!(default_dwarf_version, u32);
|
||||
key!(allows_weak_linkage, bool);
|
||||
key!(has_rpath, bool);
|
||||
|
@ -762,6 +776,7 @@ impl ToJson for Target {
|
|||
target_option_val!(is_like_msvc);
|
||||
target_option_val!(is_like_wasm);
|
||||
target_option_val!(is_like_android);
|
||||
target_option_val!(binary_format);
|
||||
target_option_val!(default_dwarf_version);
|
||||
target_option_val!(allows_weak_linkage);
|
||||
target_option_val!(has_rpath);
|
||||
|
|
|
@ -1644,6 +1644,55 @@ impl fmt::Display for StackProtector {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Clone, Debug)]
|
||||
pub enum BinaryFormat {
|
||||
Coff,
|
||||
Elf,
|
||||
MachO,
|
||||
Wasm,
|
||||
Xcoff,
|
||||
}
|
||||
|
||||
impl BinaryFormat {
|
||||
/// Returns [`object::BinaryFormat`] for given `BinaryFormat`
|
||||
pub fn to_object(&self) -> object::BinaryFormat {
|
||||
match self {
|
||||
Self::Coff => object::BinaryFormat::Coff,
|
||||
Self::Elf => object::BinaryFormat::Elf,
|
||||
Self::MachO => object::BinaryFormat::MachO,
|
||||
Self::Wasm => object::BinaryFormat::Wasm,
|
||||
Self::Xcoff => object::BinaryFormat::Xcoff,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for BinaryFormat {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"coff" => Ok(Self::Coff),
|
||||
"elf" => Ok(Self::Elf),
|
||||
"mach-o" => Ok(Self::MachO),
|
||||
"wasm" => Ok(Self::Wasm),
|
||||
"xcoff" => Ok(Self::Xcoff),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for BinaryFormat {
|
||||
fn to_json(&self) -> Json {
|
||||
match self {
|
||||
Self::Coff => "coff",
|
||||
Self::Elf => "elf",
|
||||
Self::MachO => "mach-o",
|
||||
Self::Wasm => "wasm",
|
||||
Self::Xcoff => "xcoff",
|
||||
}
|
||||
.to_json()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! supported_targets {
|
||||
( $(($tuple:literal, $module:ident),)+ ) => {
|
||||
mod targets {
|
||||
|
@ -2381,6 +2430,8 @@ pub struct TargetOptions {
|
|||
pub is_like_wasm: bool,
|
||||
/// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc
|
||||
pub is_like_android: bool,
|
||||
/// Target's binary file format. Defaults to BinaryFormat::Elf
|
||||
pub binary_format: BinaryFormat,
|
||||
/// Default supported version of DWARF on this platform.
|
||||
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
|
||||
pub default_dwarf_version: u32,
|
||||
|
@ -2756,6 +2807,7 @@ impl Default for TargetOptions {
|
|||
is_like_msvc: false,
|
||||
is_like_wasm: false,
|
||||
is_like_android: false,
|
||||
binary_format: BinaryFormat::Elf,
|
||||
default_dwarf_version: 4,
|
||||
allows_weak_linkage: true,
|
||||
has_rpath: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue