Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
std::vector<std::string> Result;
const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
Result.push_back("--target=" + Triple.str());
bool IsARM = false;

switch (Triple.getArch()) {
case llvm::Triple::aarch64:
Expand All @@ -355,6 +356,7 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
getARMMultilibFlags(D, Triple, Args, Result);
IsARM = true; // for ROPI/RWPI below
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
Expand All @@ -376,6 +378,41 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
else
Result.push_back("-fexceptions");

// A difference of relocation model (absolutely addressed data, PIC, Arm
// ROPI/RWPI) is likely to change whether a particular multilib variant is
// compatible with a given link. Determine the relocation model of the
// current link, and add appropriate
{
RegisterEffectiveTriple TripleRAII(
*this, llvm::Triple(ComputeEffectiveClangTriple(Args)));

auto [RelocationModel, PICLevel, IsPIE] = tools::ParsePICArgs(*this, Args);

// ROPI and RWPI are only meaningful on Arm, so for other architectures, we
// expect never to find out they're enabled. But it seems confusing to add
// -fno-ropi and -fno-rwpi unconditionally to every other architecture's
// multilib flags, so instead we leave them out completely.
if (IsARM) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to move this Arm-only segment into getARMMultilibFlags? In theory, that function handles everything that is only relevant to Arm. So it's a more natural place to host this segment here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. In my early drafts I had the whole thing in getARMMultilibFlags, but moved it out once I realised that PIC needed to be handled as well as ROPI/RWPI. I've kept the calculation of the relocation model in the top-level function, and just passed the answer down into getARMMultilibFlags where it can add the Arm-specific options.

if (RelocationModel == llvm::Reloc::ROPI ||
RelocationModel == llvm::Reloc::ROPI_RWPI)
Result.push_back("-fropi");
else
Result.push_back("-fno-ropi");

if (RelocationModel == llvm::Reloc::RWPI ||
RelocationModel == llvm::Reloc::ROPI_RWPI)
Result.push_back("-frwpi");
else
Result.push_back("-fno-rwpi");
}

if (RelocationModel == llvm::Reloc::PIC_)
Result.push_back(IsPIE ? (PICLevel > 1 ? "-fPIE" : "-fpie")
: (PICLevel > 1 ? "-fPIC" : "-fpic"));
else
Result.push_back("-fno-pic");
}

// Sort and remove duplicates.
std::sort(Result.begin(), Result.end());
Result.erase(llvm::unique(Result), Result.end());
Expand Down
19 changes: 19 additions & 0 deletions clang/test/Driver/print-multi-selection-flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,22 @@
// CHECK-AARCH64-MULTILIB-CUSTOM-FLAG: --target=aarch64-unknown-none-eabi
// CHECK-MULTILIB-CUSTOM-FLAG-DAG: -fmultilib-flag=foo
// CHECK-MULTILIB-CUSTOM-FLAG-DAG: -fmultilib-flag=bar

// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fropi | FileCheck --check-prefixes=CHECK-ROPI,CHECK-NO-RWPI,CHECK-NO-PIC %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -frwpi | FileCheck --check-prefixes=CHECK-RWPI,CHECK-NO-ROPI,CHECK-NO-PIC %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fropi -frwpi | FileCheck --check-prefixes=CHECK-ROPI,CHECK-RWPI,CHECK-NO-PIC %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fno-ropi -fno-rwpi | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-NO-PIC %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-NO-PIC %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fpic | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-PIC1 %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fPIC | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-PIC2 %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fpie | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-PIE1 %s
// RUN: %clang -multi-lib-config=%S/Inputs/multilib/empty.yaml -print-multi-flags-experimental --target=arm-none-eabi -march=armv7a -fPIE | FileCheck --check-prefixes=CHECK-NO-ROPI,CHECK-NO-RWPI,CHECK-PIE2 %s
// CHECK-ROPI: -fropi
// CHECK-NO-ROPI: -fno-ropi
// CHECK-RWPI: -frwpi
// CHECK-NO-RWPI: -fno-rwpi
// CHECK-PIC1: -fpic
// CHECK-PIC2: -fPIC
// CHECK-PIE1: -fpie
// CHECK-PIE2: -fPIE
// CHECK-NO-PIC: -fno-pic
Loading