From 0d47dc0cf0629bcdedfd689c08e2f074aa7d03f3 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Fri, 10 Jan 2025 20:51:23 -0500 Subject: [PATCH] Correctly handle the relocation model for LTO --- src/back/lto.rs | 9 ++++++++- src/back/write.rs | 10 ++++------ src/base.rs | 39 +++++++++++++++++++++++++-------------- src/lib.rs | 5 +++++ 4 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/back/lto.rs b/src/back/lto.rs index aecb4c424081..8371a025d90b 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 007f30369abd..51c5ba73e32b 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, <o_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 4ac25fd7019d..c9701fb9885c 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 0c209ebc26f2..a93e1df4e4db 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, + /// 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,