about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAntoni Boucher <bouanto@zoho.com>2025-01-10 20:51:23 -0500
committerAntoni Boucher <bouanto@zoho.com>2025-01-11 21:04:38 -0500
commit0d47dc0cf0629bcdedfd689c08e2f074aa7d03f3 (patch)
treeb8058d4c59f703f4d67ae1166bbb18a0bfdcddcd
parent423701a3cf76dc96904878832c28709b36d8e778 (diff)
downloadrust-0d47dc0cf0629bcdedfd689c08e2f074aa7d03f3.tar.gz
rust-0d47dc0cf0629bcdedfd689c08e2f074aa7d03f3.zip
Correctly handle the relocation model for LTO
-rw-r--r--src/back/lto.rs9
-rw-r--r--src/back/write.rs10
-rw-r--r--src/base.rs39
-rw-r--r--src/lib.rs5
4 files changed, 42 insertions, 21 deletions
diff --git a/src/back/lto.rs b/src/back/lto.rs
index aecb4c42408..8371a025d90 100644
--- a/src/back/lto.rs
+++ b/src/back/lto.rs
@@ -35,6 +35,7 @@ use rustc_middle::bug;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
 use rustc_session::config::{CrateType, Lto};
+use rustc_target::spec::RelocModel;
 use tempfile::{TempDir, tempdir};
 
 use crate::back::write::save_temp_bitcode;
@@ -632,7 +633,13 @@ pub unsafe fn optimize_thin_module(
         }
     };
     let module = ModuleCodegen {
-        module_llvm: GccContext { context, should_combine_object_files, temp_dir: None },
+        module_llvm: GccContext {
+            context,
+            should_combine_object_files,
+            // TODO(antoyo): use the correct relocation model here.
+            relocation_model: RelocModel::Pic,
+            temp_dir: None,
+        },
         name: thin_module.name().to_string(),
         kind: ModuleKind::Regular,
     };
diff --git a/src/back/write.rs b/src/back/write.rs
index 007f30369ab..51c5ba73e32 100644
--- a/src/back/write.rs
+++ b/src/back/write.rs
@@ -10,6 +10,7 @@ use rustc_session::config::OutputType;
 use rustc_span::fatal_error::FatalError;
 use rustc_target::spec::SplitDebuginfo;
 
+use crate::base::add_pic_option;
 use crate::errors::CopyBitcode;
 use crate::{GccCodegenBackend, GccContext};
 
@@ -159,7 +160,7 @@ pub(crate) unsafe fn codegen(
 
                         // NOTE: without -fuse-linker-plugin, we get the following error:
                         // lto1: internal compiler error: decompressed stream: Destination buffer is too small
-                        // TODO: since we do not do LTO when the linker is invoked anymore, perhaps
+                        // TODO(antoyo): since we do not do LTO when the linker is invoked anymore, perhaps
                         // the following flag is not necessary anymore.
                         context.add_driver_option("-fuse-linker-plugin");
                     }
@@ -185,7 +186,7 @@ pub(crate) unsafe fn codegen(
                         // flags, it combines the .o files together in another .o.
                         context.compile_to_file(OutputKind::Executable, &lto_path);
 
-                        let context = Context::default(); // TODO: might need to set some other flags from new_context.
+                        let context = Context::default();
                         if cgcx.target_arch == "x86" || cgcx.target_arch == "x86_64" {
                             // NOTE: it seems we need to use add_driver_option instead of
                             // add_command_line_option here because we use the LTO frontend via gcc.
@@ -195,12 +196,9 @@ pub(crate) unsafe fn codegen(
                         // NOTE: these two options are needed to invoke LTO to produce an object file.
                         // We need to initiate a second compilation because the arguments "-x lto"
                         // needs to be at the very beginning.
-                        // TODO TODO: check that LTO still does the optimizations across different
-                        // object files with this change.
-                        // TODO: this should probably be in a condition `if fat_lto`.
                         context.add_driver_option("-x");
                         context.add_driver_option("lto");
-                        context.add_driver_option("-fPIC"); // TODO TODO: only add this flag when necessary.
+                        add_pic_option(&context, module.module_llvm.relocation_model);
                         context.add_driver_option(lto_path);
 
                         context.compile_to_file(OutputKind::ObjectFile, path);
diff --git a/src/base.rs b/src/base.rs
index 4ac25fd7019..c9701fb9885 100644
--- a/src/base.rs
+++ b/src/base.rs
@@ -3,7 +3,7 @@ use std::env;
 use std::sync::Arc;
 use std::time::Instant;
 
-use gccjit::{CType, FunctionType, GlobalKind};
+use gccjit::{CType, Context, FunctionType, GlobalKind};
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
 use rustc_codegen_ssa::traits::DebugInfoCodegenMethods;
@@ -15,9 +15,9 @@ use rustc_middle::mir::mono::Visibility;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::config::DebugInfo;
 use rustc_span::Symbol;
-use rustc_target::spec::PanicStrategy;
 #[cfg(feature = "master")]
 use rustc_target::spec::SymbolVisibility;
+use rustc_target::spec::{PanicStrategy, RelocModel};
 
 use crate::builder::Builder;
 use crate::context::CodegenCx;
@@ -151,18 +151,7 @@ pub fn compile_codegen_unit(
             });
         }
 
-        match tcx.sess.relocation_model() {
-            rustc_target::spec::RelocModel::Static => {
-                context.add_command_line_option("-fno-pie");
-            }
-            rustc_target::spec::RelocModel::Pic => {
-                context.add_command_line_option("-fPIC");
-            }
-            rustc_target::spec::RelocModel::Pie => {
-                context.add_command_line_option("-fPIE");
-            }
-            model => eprintln!("Unsupported relocation model: {:?}", model),
-        }
+        add_pic_option(&context, tcx.sess.relocation_model());
 
         let target_cpu = gcc_util::target_cpu(tcx.sess);
         if target_cpu != "generic" {
@@ -256,6 +245,7 @@ pub fn compile_codegen_unit(
             name: cgu_name.to_string(),
             module_llvm: GccContext {
                 context: Arc::new(SyncContext::new(context)),
+                relocation_model: tcx.sess.relocation_model(),
                 should_combine_object_files: false,
                 temp_dir: None,
             },
@@ -265,3 +255,24 @@ pub fn compile_codegen_unit(
 
     (module, cost)
 }
+
+pub fn add_pic_option<'gcc>(context: &Context<'gcc>, relocation_model: RelocModel) {
+    match relocation_model {
+        rustc_target::spec::RelocModel::Static => {
+            context.add_command_line_option("-fno-pie");
+            context.add_driver_option("-fno-pie");
+        }
+        rustc_target::spec::RelocModel::Pic => {
+            context.add_command_line_option("-fPIC");
+            // NOTE: we use both add_command_line_option and add_driver_option because the usage in
+            // this module (compile_codegen_unit) requires add_command_line_option while the usage
+            // in the back::write module (codegen) requires add_driver_option.
+            context.add_driver_option("-fPIC");
+        }
+        rustc_target::spec::RelocModel::Pie => {
+            context.add_command_line_option("-fPIE");
+            context.add_driver_option("-fPIE");
+        }
+        model => eprintln!("Unsupported relocation model: {:?}", model),
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 0c209ebc26f..a93e1df4e4d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -113,6 +113,7 @@ use rustc_session::Session;
 use rustc_session::config::{Lto, OptLevel, OutputFilenames};
 use rustc_span::Symbol;
 use rustc_span::fatal_error::FatalError;
+use rustc_target::spec::RelocModel;
 use tempfile::TempDir;
 
 use crate::back::lto::ModuleBuffer;
@@ -298,6 +299,7 @@ impl ExtraBackendMethods for GccCodegenBackend {
     ) -> Self::Module {
         let mut mods = GccContext {
             context: Arc::new(SyncContext::new(new_context(tcx))),
+            relocation_model: tcx.sess.relocation_model(),
             should_combine_object_files: false,
             temp_dir: None,
         };
@@ -329,6 +331,9 @@ impl ExtraBackendMethods for GccCodegenBackend {
 
 pub struct GccContext {
     context: Arc<SyncContext>,
+    /// This field is needed in order to be able to set the flag -fPIC when necessary when doing
+    /// LTO.
+    relocation_model: RelocModel,
     should_combine_object_files: bool,
     // Temporary directory used by LTO. We keep it here so that it's not removed before linking.
     temp_dir: Option<TempDir>,