1
Fork 0

Correctly handle the relocation model for LTO

This commit is contained in:
Antoni Boucher 2025-01-10 20:51:23 -05:00
parent 423701a3cf
commit 0d47dc0cf0
4 changed files with 42 additions and 21 deletions

View file

@ -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,
};

View file

@ -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);

View file

@ -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),
}
}

View file

@ -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>,