Blame SOURCES/0001-Improve-generating-Custom-entry-function.patch

3824bc
From 9f0a8620bd7d325e6d42417b08daff3e55cb88f6 Mon Sep 17 00:00:00 2001
3824bc
From: Ayush Singh <ayushsingh1325@gmail.com>
3824bc
Date: Sat, 5 Nov 2022 14:36:38 +0530
3824bc
Subject: [PATCH] Improve generating Custom entry function
3824bc
3824bc
This commit is aimed at making compiler generated entry functions
3824bc
(Basically just C `main` right now) more generic so other targets can do
3824bc
similar things for custom entry. This was initially implemented as part
3824bc
of https://github.com/rust-lang/rust/pull/100316.
3824bc
3824bc
Currently, this moves the entry function name and Call convention to the
3824bc
target spec.
3824bc
3824bc
Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
3824bc
---
3824bc
 compiler/rustc_codegen_llvm/src/abi.rs        | 40 +++++++++++--------
3824bc
 compiler/rustc_codegen_llvm/src/context.rs    | 10 ++++-
3824bc
 compiler/rustc_codegen_llvm/src/declare.rs    | 22 ++++++++++
3824bc
 .../src/back/symbol_export.rs                 |  3 +-
3824bc
 compiler/rustc_target/src/abi/call/mod.rs     | 28 +++++++++++++
3824bc
 compiler/rustc_target/src/json.rs             | 25 ++++++++++++
3824bc
 compiler/rustc_target/src/spec/mod.rs         | 27 +++++++++++++
3824bc
 7 files changed, 135 insertions(+), 20 deletions(-)
3824bc
3824bc
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
3824bc
index d478efc863a9..a6fd2a7de6bd 100644
3824bc
--- a/compiler/rustc_codegen_llvm/src/abi.rs
3824bc
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
3824bc
@@ -398,23 +398,7 @@ fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
3824bc
     }
3824bc
 
3824bc
     fn llvm_cconv(&self) -> llvm::CallConv {
3824bc
-        match self.conv {
3824bc
-            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
3824bc
-            Conv::RustCold => llvm::ColdCallConv,
3824bc
-            Conv::AmdGpuKernel => llvm::AmdGpuKernel,
3824bc
-            Conv::AvrInterrupt => llvm::AvrInterrupt,
3824bc
-            Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
3824bc
-            Conv::ArmAapcs => llvm::ArmAapcsCallConv,
3824bc
-            Conv::Msp430Intr => llvm::Msp430Intr,
3824bc
-            Conv::PtxKernel => llvm::PtxKernel,
3824bc
-            Conv::X86Fastcall => llvm::X86FastcallCallConv,
3824bc
-            Conv::X86Intr => llvm::X86_Intr,
3824bc
-            Conv::X86Stdcall => llvm::X86StdcallCallConv,
3824bc
-            Conv::X86ThisCall => llvm::X86_ThisCall,
3824bc
-            Conv::X86VectorCall => llvm::X86_VectorCall,
3824bc
-            Conv::X86_64SysV => llvm::X86_64_SysV,
3824bc
-            Conv::X86_64Win64 => llvm::X86_64_Win64,
3824bc
-        }
3824bc
+        self.conv.into()
3824bc
     }
3824bc
 
3824bc
     fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
3824bc
@@ -596,3 +580,25 @@ fn get_param(&mut self, index: usize) -> Self::Value {
3824bc
         llvm::get_param(self.llfn(), index as c_uint)
3824bc
     }
3824bc
 }
3824bc
+
3824bc
+impl From<Conv> for llvm::CallConv {
3824bc
+    fn from(conv: Conv) -> Self {
3824bc
+        match conv {
3824bc
+            Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
3824bc
+            Conv::RustCold => llvm::ColdCallConv,
3824bc
+            Conv::AmdGpuKernel => llvm::AmdGpuKernel,
3824bc
+            Conv::AvrInterrupt => llvm::AvrInterrupt,
3824bc
+            Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
3824bc
+            Conv::ArmAapcs => llvm::ArmAapcsCallConv,
3824bc
+            Conv::Msp430Intr => llvm::Msp430Intr,
3824bc
+            Conv::PtxKernel => llvm::PtxKernel,
3824bc
+            Conv::X86Fastcall => llvm::X86FastcallCallConv,
3824bc
+            Conv::X86Intr => llvm::X86_Intr,
3824bc
+            Conv::X86Stdcall => llvm::X86StdcallCallConv,
3824bc
+            Conv::X86ThisCall => llvm::X86_ThisCall,
3824bc
+            Conv::X86VectorCall => llvm::X86_VectorCall,
3824bc
+            Conv::X86_64SysV => llvm::X86_64_SysV,
3824bc
+            Conv::X86_64Win64 => llvm::X86_64_Win64,
3824bc
+        }
3824bc
+    }
3824bc
+}
3824bc
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
3824bc
index 79ddfd884dfa..f3ef618fff54 100644
3824bc
--- a/compiler/rustc_codegen_llvm/src/context.rs
3824bc
+++ b/compiler/rustc_codegen_llvm/src/context.rs
3824bc
@@ -570,8 +570,14 @@ fn apply_target_cpu_attr(&self, llfn: &'ll Value) {
3824bc
     }
3824bc
 
3824bc
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
3824bc
-        if self.get_declared_value("main").is_none() {
3824bc
-            Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
3824bc
+        let entry_name = self.sess().target.entry_name.as_ref();
3824bc
+        if self.get_declared_value(entry_name).is_none() {
3824bc
+            Some(self.declare_entry_fn(
3824bc
+                entry_name,
3824bc
+                self.sess().target.entry_abi.into(),
3824bc
+                llvm::UnnamedAddr::Global,
3824bc
+                fn_type,
3824bc
+            ))
3824bc
         } else {
3824bc
             // If the symbol already exists, it is an error: for example, the user wrote
3824bc
             // #[no_mangle] extern "C" fn main(..) {..}
3824bc
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
3824bc
index f79ef11720df..dc21a02cec44 100644
3824bc
--- a/compiler/rustc_codegen_llvm/src/declare.rs
3824bc
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
3824bc
@@ -90,6 +90,28 @@ pub fn declare_cfn(
3824bc
         declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
3824bc
     }
3824bc
 
3824bc
+    /// Declare an entry Function
3824bc
+    ///
3824bc
+    /// The ABI of this function can change depending on the target (although for now the same as
3824bc
+    /// `declare_cfn`)
3824bc
+    ///
3824bc
+    /// If there’s a value with the same name already declared, the function will
3824bc
+    /// update the declaration and return existing Value instead.
3824bc
+    pub fn declare_entry_fn(
3824bc
+        &self,
3824bc
+        name: &str,
3824bc
+        callconv: llvm::CallConv,
3824bc
+        unnamed: llvm::UnnamedAddr,
3824bc
+        fn_type: &'ll Type,
3824bc
+    ) -> &'ll Value {
3824bc
+        let visibility = if self.tcx.sess.target.default_hidden_visibility {
3824bc
+            llvm::Visibility::Hidden
3824bc
+        } else {
3824bc
+            llvm::Visibility::Default
3824bc
+        };
3824bc
+        declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
3824bc
+    }
3824bc
+
3824bc
     /// Declare a Rust function.
3824bc
     ///
3824bc
     /// If there’s a value with the same name already declared, the function will
3824bc
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
3824bc
index 752f6b1ef40c..22f534d909ab 100644
3824bc
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
3824bc
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
3824bc
@@ -180,7 +180,8 @@ fn exported_symbols_provider_local<'tcx>(
3824bc
         .collect();
3824bc
 
3824bc
     if tcx.entry_fn(()).is_some() {
3824bc
-        let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main"));
3824bc
+        let exported_symbol =
3824bc
+            ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref()));
3824bc
 
3824bc
         symbols.push((
3824bc
             exported_symbol,
3824bc
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
3824bc
index 9e5f0e4d158b..c622bd36b00c 100644
3824bc
--- a/compiler/rustc_target/src/abi/call/mod.rs
3824bc
+++ b/compiler/rustc_target/src/abi/call/mod.rs
3824bc
@@ -3,6 +3,7 @@
3824bc
 use crate::spec::{self, HasTargetSpec};
3824bc
 use rustc_span::Symbol;
3824bc
 use std::fmt;
3824bc
+use std::str::FromStr;
3824bc
 
3824bc
 mod aarch64;
3824bc
 mod amdgpu;
3824bc
@@ -735,6 +736,33 @@ pub fn adjust_for_foreign_abi<C>(
3824bc
     }
3824bc
 }
3824bc
 
3824bc
+impl FromStr for Conv {
3824bc
+    type Err = String;
3824bc
+
3824bc
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
3824bc
+        match s {
3824bc
+            "C" => Ok(Conv::C),
3824bc
+            "Rust" => Ok(Conv::Rust),
3824bc
+            "RustCold" => Ok(Conv::Rust),
3824bc
+            "ArmAapcs" => Ok(Conv::ArmAapcs),
3824bc
+            "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall),
3824bc
+            "Msp430Intr" => Ok(Conv::Msp430Intr),
3824bc
+            "PtxKernel" => Ok(Conv::PtxKernel),
3824bc
+            "X86Fastcall" => Ok(Conv::X86Fastcall),
3824bc
+            "X86Intr" => Ok(Conv::X86Intr),
3824bc
+            "X86Stdcall" => Ok(Conv::X86Stdcall),
3824bc
+            "X86ThisCall" => Ok(Conv::X86ThisCall),
3824bc
+            "X86VectorCall" => Ok(Conv::X86VectorCall),
3824bc
+            "X86_64SysV" => Ok(Conv::X86_64SysV),
3824bc
+            "X86_64Win64" => Ok(Conv::X86_64Win64),
3824bc
+            "AmdGpuKernel" => Ok(Conv::AmdGpuKernel),
3824bc
+            "AvrInterrupt" => Ok(Conv::AvrInterrupt),
3824bc
+            "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt),
3824bc
+            _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)),
3824bc
+        }
3824bc
+    }
3824bc
+}
3824bc
+
3824bc
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
3824bc
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
3824bc
 mod size_asserts {
3824bc
diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs
3824bc
index b5d926352122..75bb76a9de08 100644
3824bc
--- a/compiler/rustc_target/src/json.rs
3824bc
+++ b/compiler/rustc_target/src/json.rs
3824bc
@@ -89,3 +89,28 @@ fn to_json(&self) -> Json {
3824bc
         }
3824bc
     }
3824bc
 }
3824bc
+
3824bc
+impl ToJson for crate::abi::call::Conv {
3824bc
+    fn to_json(&self) -> Json {
3824bc
+        let s = match self {
3824bc
+            Self::C => "C",
3824bc
+            Self::Rust => "Rust",
3824bc
+            Self::RustCold => "RustCold",
3824bc
+            Self::ArmAapcs => "ArmAapcs",
3824bc
+            Self::CCmseNonSecureCall => "CCmseNonSecureCall",
3824bc
+            Self::Msp430Intr => "Msp430Intr",
3824bc
+            Self::PtxKernel => "PtxKernel",
3824bc
+            Self::X86Fastcall => "X86Fastcall",
3824bc
+            Self::X86Intr => "X86Intr",
3824bc
+            Self::X86Stdcall => "X86Stdcall",
3824bc
+            Self::X86ThisCall => "X86ThisCall",
3824bc
+            Self::X86VectorCall => "X86VectorCall",
3824bc
+            Self::X86_64SysV => "X86_64SysV",
3824bc
+            Self::X86_64Win64 => "X86_64Win64",
3824bc
+            Self::AmdGpuKernel => "AmdGpuKernel",
3824bc
+            Self::AvrInterrupt => "AvrInterrupt",
3824bc
+            Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt",
3824bc
+        };
3824bc
+        Json::String(s.to_owned())
3824bc
+    }
3824bc
+}
3824bc
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
3824bc
index 72b088d663b1..617de46a55aa 100644
3824bc
--- a/compiler/rustc_target/src/spec/mod.rs
3824bc
+++ b/compiler/rustc_target/src/spec/mod.rs
3824bc
@@ -34,6 +34,7 @@
3824bc
 //! the target's settings, though `target-feature` and `link-args` will *add*
3824bc
 //! to the list specified by the target, rather than replace.
3824bc
 
3824bc
+use crate::abi::call::Conv;
3824bc
 use crate::abi::Endian;
3824bc
 use crate::json::{Json, ToJson};
3824bc
 use crate::spec::abi::{lookup as lookup_abi, Abi};
3824bc
@@ -1668,6 +1669,14 @@ pub struct TargetOptions {
3824bc
     /// Whether the target supports stack canary checks. `true` by default,
3824bc
     /// since this is most common among tier 1 and tier 2 targets.
3824bc
     pub supports_stack_protector: bool,
3824bc
+
3824bc
+    // The name of entry function.
3824bc
+    // Default value is "main"
3824bc
+    pub entry_name: StaticCow<str>,
3824bc
+
3824bc
+    // The ABI of entry function.
3824bc
+    // Default value is `Conv::C`, i.e. C call convention
3824bc
+    pub entry_abi: Conv,
3824bc
 }
3824bc
 
3824bc
 /// Add arguments for the given flavor and also for its "twin" flavors
3824bc
@@ -1884,6 +1893,8 @@ fn default() -> TargetOptions {
3824bc
             c_enum_min_bits: 32,
3824bc
             generate_arange_section: true,
3824bc
             supports_stack_protector: true,
3824bc
+            entry_name: "main".into(),
3824bc
+            entry_abi: Conv::C,
3824bc
         }
3824bc
     }
3824bc
 }
3824bc
@@ -2401,6 +2412,18 @@ macro_rules! key {
3824bc
                     }
3824bc
                 }
3824bc
             } );
3824bc
+            ($key_name:ident, Conv) => ( {
3824bc
+                let name = (stringify!($key_name)).replace("_", "-");
3824bc
+                obj.remove(&name).and_then(|o| o.as_str().and_then(|s| {
3824bc
+                    match Conv::from_str(s) {
3824bc
+                        Ok(c) => {
3824bc
+                            base.$key_name = c;
3824bc
+                            Some(Ok(()))
3824bc
+                        }
3824bc
+                        Err(e) => Some(Err(e))
3824bc
+                    }
3824bc
+                })).unwrap_or(Ok(()))
3824bc
+            } );
3824bc
         }
3824bc
 
3824bc
         if let Some(j) = obj.remove("target-endian") {
3824bc
@@ -2520,6 +2543,8 @@ macro_rules! key {
3824bc
         key!(c_enum_min_bits, u64);
3824bc
         key!(generate_arange_section, bool);
3824bc
         key!(supports_stack_protector, bool);
3824bc
+        key!(entry_name);
3824bc
+        key!(entry_abi, Conv)?;
3824bc
 
3824bc
         if base.is_builtin {
3824bc
             // This can cause unfortunate ICEs later down the line.
3824bc
@@ -2770,6 +2795,8 @@ macro_rules! target_option_val {
3824bc
         target_option_val!(c_enum_min_bits);
3824bc
         target_option_val!(generate_arange_section);
3824bc
         target_option_val!(supports_stack_protector);
3824bc
+        target_option_val!(entry_name);
3824bc
+        target_option_val!(entry_abi);
3824bc
 
3824bc
         if let Some(abi) = self.default_adjusted_cabi {
3824bc
             d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json());
3824bc
-- 
3824bc
2.38.1
3824bc