Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add binary_format to rustc target specs #136637

Merged
merged 1 commit into from
Feb 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
40 changes: 11 additions & 29 deletions compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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>,
Expand All @@ -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);
Expand Down Expand Up @@ -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}")?;
}
Expand All @@ -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 => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added Xcoff here with Elf since it wasn't taken into account before and AsmBinaryFormat defaulted to elf

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I'd expect this to be wrong, but not any more wrong than before, and I don't really know anything about XCoff. Let's leave it like this and open a follow-up issue about this and ping the AIX maintainers there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have created an issue about this at #137219

Copy link
Contributor

@folkertdev folkertdev Feb 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

author of this file here: I just checked, and this is definitely wrong and needs something custom. I don't think we have any tests that would hit this target, so I think this PR can just be merged first, and then we fix naked_asm for AIX later.

I'll have a stab at a fix, and then hopefully the AIX folks can confirm that what I come up with actually works.

also in general: this is a really nice change, thanks!

let section = link_section.unwrap_or(format!(".text.{asm_name}"));

let progbits = match is_arm {
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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();
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_target/src/spec/base/aix.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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(&[
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/base/apple/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_target/src/spec/base/cygwin.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/base/msvc.rs
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/base/wasm.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/base/windows_gnu.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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(),
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_target/src/spec/base/windows_gnullvm.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
52 changes: 52 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,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 {
Expand Down Expand Up @@ -2369,6 +2418,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,
Expand Down Expand Up @@ -2744,6 +2795,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,
Expand Down
Loading