From ef5ede52efbff6ffa9f8c40dc3c6276146e6ff45 Mon Sep 17 00:00:00 2001 From: Usman Nadeem Date: Mon, 22 Aug 2022 10:24:49 -0700 Subject: [PATCH] [Flang][Driver] Add support for PIC This patch does the following: - Consumes the PIC flags (fPIC/fPIE/fropi/frwpi etc) in flang-new. tools::ParsePICArgs() in ToolChains/CommonArgs.cpp is used for this. - Adds FC1Option to "-mrelocation-model", "-pic-level", and "-pic-is-pie" command line options. - Adds the above options to flang/Frontend/CodeGenOptions' data structure. - Sets the relocation model in the target machine, and - Sets module flags for the respective PIC/PIE type in LLVM IR. I have tried my best to replicate how clang does things. Differential Revision: https://reviews.llvm.org/D131533 Change-Id: I68fe64910be28147dc5617826641cea71b92d94d --- clang/include/clang/Driver/Options.td | 32 ++++--- clang/lib/Driver/ToolChains/Clang.cpp | 17 ---- clang/lib/Driver/ToolChains/CommonArgs.cpp | 18 ++++ clang/lib/Driver/ToolChains/CommonArgs.h | 2 + clang/lib/Driver/ToolChains/Flang.cpp | 24 ++++++ clang/lib/Driver/ToolChains/Flang.h | 9 ++ clang/lib/Driver/ToolChains/Linux.cpp | 7 +- .../include/flang/Frontend/CodeGenOptions.def | 11 +++ flang/include/flang/Frontend/CodeGenOptions.h | 9 ++ flang/lib/Frontend/CodeGenOptions.cpp | 1 + flang/lib/Frontend/CompilerInvocation.cpp | 33 +++++++ flang/lib/Frontend/FrontendActions.cpp | 15 +++- flang/test/Driver/driver-help.f90 | 4 + flang/test/Driver/pic-flags.f90 | 85 ++++++++++++++++--- 14 files changed, 217 insertions(+), 50 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c8178c13e82e9..1939312ffd685 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5240,6 +5240,16 @@ def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, // CodeGen Options //===----------------------------------------------------------------------===// +let Flags = [CC1Option, CC1AsOption, FC1Option, NoDriverOption] in { + +def mrelocation_model : Separate<["-"], "mrelocation-model">, + HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">, + NormalizedValuesScope<"llvm::Reloc">, + NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, + MarshallingInfoEnum, "PIC_">; + +} // let Flags = [CC1Option, CC1AsOption, FC1Option, NoDriverOption] + let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; @@ -5284,11 +5294,6 @@ def msave_temp_labels : Flag<["-"], "msave-temp-labels">, "Note this may change .s semantics and shouldn't generally be used " "on compiler-generated code.">, MarshallingInfoFlag>; -def mrelocation_model : Separate<["-"], "mrelocation-model">, - HelpText<"The relocation model to use">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">, - NormalizedValuesScope<"llvm::Reloc">, - NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, - MarshallingInfoEnum, "PIC_">; def fno_math_builtin : Flag<["-"], "fno-math-builtin">, HelpText<"Disable implicit builtin knowledge of math functions">, MarshallingInfoFlag>; @@ -5973,6 +5978,17 @@ def split_dwarf_output : Separate<["-"], "split-dwarf-output">, Flags<[CC1Option, CC1AsOption, NoDriverOption]>, MarshallingInfoString>; +let Flags = [CC1Option, FC1Option, NoDriverOption] in { + +def pic_level : Separate<["-"], "pic-level">, + HelpText<"Value for __PIC__">, + MarshallingInfoInt>; +def pic_is_pie : Flag<["-"], "pic-is-pie">, + HelpText<"File is for a position independent executable">, + MarshallingInfoFlag>; + +} // let Flags = [CC1Option, FC1Option, NoDriverOption] + let Flags = [CC1Option, NoDriverOption] in { def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, @@ -6013,12 +6029,6 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa def function_alignment : Separate<["-"], "function-alignment">, HelpText<"default alignment for functions">, MarshallingInfoInt>; -def pic_level : Separate<["-"], "pic-level">, - HelpText<"Value for __PIC__">, - MarshallingInfoInt>; -def pic_is_pie : Flag<["-"], "pic-is-pie">, - HelpText<"File is for a position independent executable">, - MarshallingInfoFlag>; def fhalf_no_semantic_interposition : Flag<["-"], "fhalf-no-semantic-interposition">, HelpText<"Like -fno-semantic-interposition but don't use local aliases">, MarshallingInfoFlag>; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8c38e934d8aa6..ee23621a3233a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1152,23 +1152,6 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, } } -static const char *RelocationModelName(llvm::Reloc::Model Model) { - switch (Model) { - case llvm::Reloc::Static: - return "static"; - case llvm::Reloc::PIC_: - return "pic"; - case llvm::Reloc::DynamicNoPIC: - return "dynamic-no-pic"; - case llvm::Reloc::ROPI: - return "ropi"; - case llvm::Reloc::RWPI: - return "rwpi"; - case llvm::Reloc::ROPI_RWPI: - return "ropi-rwpi"; - } - llvm_unreachable("Unknown Reloc::Model kind"); -} static void handleAMDGPUCodeObjectVersionOptions(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index c0aec33b082a5..d5b437ceed63c 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1201,6 +1201,24 @@ Arg *tools::getLastProfileSampleUseArg(const ArgList &Args) { options::OPT_fauto_profile_EQ); } +const char *tools::RelocationModelName(llvm::Reloc::Model Model) { + switch (Model) { + case llvm::Reloc::Static: + return "static"; + case llvm::Reloc::PIC_: + return "pic"; + case llvm::Reloc::DynamicNoPIC: + return "dynamic-no-pic"; + case llvm::Reloc::ROPI: + return "ropi"; + case llvm::Reloc::RWPI: + return "rwpi"; + case llvm::Reloc::ROPI_RWPI: + return "ropi-rwpi"; + } + llvm_unreachable("Unknown Reloc::Model kind"); +} + /// Parses the various -fpic/-fPIC/-fpie/-fPIE arguments. Then, /// smooshes them together with platform defaults, to decide whether /// this compile should be using PIC mode or not. Returns a tuple of diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h index 8e62af70ff7f7..326141c3f926e 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -93,6 +93,8 @@ void addLTOOptions(const ToolChain &ToolChain, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const InputInfo &Output, const InputInfo &Input, bool IsThinLTO); +const char *RelocationModelName(llvm::Reloc::Model Model); + std::tuple ParsePICArgs(const ToolChain &ToolChain, const llvm::opt::ArgList &Args); diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 3368f67857180..b279529a33184 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -58,6 +58,27 @@ void Flang::AddOtherOptions(const ArgList &Args, ArgStringList &CmdArgs) const { options::OPT_std_EQ, options::OPT_W_Joined}); } +void Flang::AddPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const { + // ParsePICArgs parses -fPIC/-fPIE and their variants and returns a tuple of + // (RelocationModel, PICLevel, IsPIE). + llvm::Reloc::Model RelocationModel; + unsigned PICLevel; + bool IsPIE; + std::tie(RelocationModel, PICLevel, IsPIE) = + ParsePICArgs(getToolChain(), Args); + + if (auto *RMName = RelocationModelName(RelocationModel)) { + CmdArgs.push_back("-mrelocation-model"); + CmdArgs.push_back(RMName); + } + if (PICLevel > 0) { + CmdArgs.push_back("-pic-level"); + CmdArgs.push_back(PICLevel == 1 ? "1" : "2"); + if (IsPIE) + CmdArgs.push_back("-pic-is-pie"); + } +} + void Flang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { @@ -117,6 +138,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, if (D.getDiags().getDiagnosticOptions().ShowColors) CmdArgs.push_back("-fcolor-diagnostics"); + // -fPIC and related options. + AddPicOptions(Args, CmdArgs); + // Add other compile options AddOtherOptions(Args, CmdArgs); diff --git a/clang/lib/Driver/ToolChains/Flang.h b/clang/lib/Driver/ToolChains/Flang.h index efbdbe854e24f..c5ac147da768c 100644 --- a/clang/lib/Driver/ToolChains/Flang.h +++ b/clang/lib/Driver/ToolChains/Flang.h @@ -39,6 +39,15 @@ class LLVM_LIBRARY_VISIBILITY Flang : public Tool { /// \param [out] CmdArgs The list of output command arguments void AddPreprocessingOptions(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + + /// Extract PIC options from the driver arguments and add them to + /// the command arguments. + /// + /// \param [in] Args The list of input driver arguments + /// \param [out] CmdArgs The list of output command arguments + void AddPicOptions(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + /// Extract other compilation options from the driver arguments and add them /// to the command arguments. /// diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index eedbb12d0dd53..f23797215c236 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -692,11 +692,8 @@ void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs, } bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const { - // TODO: Remove the special treatment for Flang once its frontend driver can - // generate position independent code. - return !getDriver().IsFlangMode() && - (CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() || - getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE()); + return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() || + getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE(); } bool Linux::IsAArch64OutlineAtomicsDefault(const ArgList &Args) const {