diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-11-19 11:54:43 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-19 11:54:43 +0530 |
| commit | aeeac5dd0c079cbe36ea5ba6eed702e88906eb16 (patch) | |
| tree | 6ecfc7b7f251cbce8e7a83f2c3a77b6d80d462b0 /compiler/rustc_target/src | |
| parent | becc24a23aed2639db3b78acd93ec6d553898583 (diff) | |
| parent | 2436dff7727732a9f55b1c80888be66ada8e288f (diff) | |
| download | rust-aeeac5dd0c079cbe36ea5ba6eed702e88906eb16.tar.gz rust-aeeac5dd0c079cbe36ea5ba6eed702e88906eb16.zip | |
Rollup merge of #104001 - Ayush1325:custom-entry, r=bjorn3
Improve generating Custom entry function This commit is aimed at making compiler-generated entry functions (Basically just C `main` right now) more generic so other targets can do similar things for custom entry. This was initially implemented as part of https://github.com/rust-lang/rust/pull/100316. Currently, this moves the entry function name and Call convention to the target spec. Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
Diffstat (limited to 'compiler/rustc_target/src')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 28 | ||||
| -rw-r--r-- | compiler/rustc_target/src/json.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_target/src/spec/mod.rs | 27 |
3 files changed, 80 insertions, 0 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index c5a6f9893b6..0c559ec04a4 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -3,6 +3,7 @@ use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::{self, HasTargetSpec}; use rustc_span::Symbol; use std::fmt; +use std::str::FromStr; mod aarch64; mod amdgpu; @@ -737,6 +738,33 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } +impl FromStr for Conv { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "C" => Ok(Conv::C), + "Rust" => Ok(Conv::Rust), + "RustCold" => Ok(Conv::Rust), + "ArmAapcs" => Ok(Conv::ArmAapcs), + "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall), + "Msp430Intr" => Ok(Conv::Msp430Intr), + "PtxKernel" => Ok(Conv::PtxKernel), + "X86Fastcall" => Ok(Conv::X86Fastcall), + "X86Intr" => Ok(Conv::X86Intr), + "X86Stdcall" => Ok(Conv::X86Stdcall), + "X86ThisCall" => Ok(Conv::X86ThisCall), + "X86VectorCall" => Ok(Conv::X86VectorCall), + "X86_64SysV" => Ok(Conv::X86_64SysV), + "X86_64Win64" => Ok(Conv::X86_64Win64), + "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), + "AvrInterrupt" => Ok(Conv::AvrInterrupt), + "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), + _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)), + } + } +} + // Some types are used a lot. Make sure they don't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs index b5d92635212..75bb76a9de0 100644 --- a/compiler/rustc_target/src/json.rs +++ b/compiler/rustc_target/src/json.rs @@ -89,3 +89,28 @@ impl<A: ToJson> ToJson for Option<A> { } } } + +impl ToJson for crate::abi::call::Conv { + fn to_json(&self) -> Json { + let s = match self { + Self::C => "C", + Self::Rust => "Rust", + Self::RustCold => "RustCold", + Self::ArmAapcs => "ArmAapcs", + Self::CCmseNonSecureCall => "CCmseNonSecureCall", + Self::Msp430Intr => "Msp430Intr", + Self::PtxKernel => "PtxKernel", + Self::X86Fastcall => "X86Fastcall", + Self::X86Intr => "X86Intr", + Self::X86Stdcall => "X86Stdcall", + Self::X86ThisCall => "X86ThisCall", + Self::X86VectorCall => "X86VectorCall", + Self::X86_64SysV => "X86_64SysV", + Self::X86_64Win64 => "X86_64Win64", + Self::AmdGpuKernel => "AmdGpuKernel", + Self::AvrInterrupt => "AvrInterrupt", + Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt", + }; + Json::String(s.to_owned()) + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 664592b02a1..6d936d2cb9f 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -34,6 +34,7 @@ //! the target's settings, though `target-feature` and `link-args` will *add* //! to the list specified by the target, rather than replace. +use crate::abi::call::Conv; use crate::abi::Endian; use crate::json::{Json, ToJson}; use crate::spec::abi::{lookup as lookup_abi, Abi}; @@ -1668,6 +1669,14 @@ pub struct TargetOptions { /// Whether the target supports stack canary checks. `true` by default, /// since this is most common among tier 1 and tier 2 targets. pub supports_stack_protector: bool, + + // The name of entry function. + // Default value is "main" + pub entry_name: StaticCow<str>, + + // The ABI of entry function. + // Default value is `Conv::C`, i.e. C call convention + pub entry_abi: Conv, } /// Add arguments for the given flavor and also for its "twin" flavors @@ -1884,6 +1893,8 @@ impl Default for TargetOptions { c_enum_min_bits: 32, generate_arange_section: true, supports_stack_protector: true, + entry_name: "main".into(), + entry_abi: Conv::C, } } } @@ -2404,6 +2415,18 @@ impl Target { } } } ); + ($key_name:ident, Conv) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match Conv::from_str(s) { + Ok(c) => { + base.$key_name = c; + Some(Ok(())) + } + Err(e) => Some(Err(e)) + } + })).unwrap_or(Ok(())) + } ); } if let Some(j) = obj.remove("target-endian") { @@ -2523,6 +2546,8 @@ impl Target { key!(c_enum_min_bits, u64); key!(generate_arange_section, bool); key!(supports_stack_protector, bool); + key!(entry_name); + key!(entry_abi, Conv)?; if base.is_builtin { // This can cause unfortunate ICEs later down the line. @@ -2773,6 +2798,8 @@ impl ToJson for Target { target_option_val!(c_enum_min_bits); target_option_val!(generate_arange_section); target_option_val!(supports_stack_protector); + target_option_val!(entry_name); + target_option_val!(entry_abi); if let Some(abi) = self.default_adjusted_cabi { d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json()); |
