Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
40 changes: 35 additions & 5 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,10 @@ static void getAArch64MultilibFlags(const Driver &D,
processMultilibCustomFlags(Result, Args);
}

static void getARMMultilibFlags(const Driver &D,
const llvm::Triple &Triple,
const llvm::opt::ArgList &Args,
Multilib::flags_list &Result) {
static void getARMMultilibFlags(const Driver &D, const llvm::Triple &Triple,
llvm::Reloc::Model RelocationModel,
const llvm::opt::ArgList &Args,
Multilib::flags_list &Result) {
std::vector<StringRef> Features;
llvm::ARM::FPUKind FPUKind = tools::arm::getARMTargetFeatures(
D, Triple, Args, Features, false /*ForAs*/, true /*ForMultilib*/);
Expand Down Expand Up @@ -304,6 +304,18 @@ static void getARMMultilibFlags(const Driver &D,
llvm_unreachable("Invalid float ABI");
}

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

const Arg *BranchProtectionArg =
Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
if (BranchProtectionArg) {
Expand Down Expand Up @@ -344,6 +356,18 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
Result.push_back("--target=" + Triple.str());

// 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, so as to add appropriate multilib flags.
llvm::Reloc::Model RelocationModel;
unsigned PICLevel;
bool IsPIE;
{
RegisterEffectiveTriple TripleRAII(*this, Triple);
std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(*this, Args);
}

switch (Triple.getArch()) {
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_32:
Expand All @@ -354,7 +378,7 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
case llvm::Triple::armeb:
case llvm::Triple::thumb:
case llvm::Triple::thumbeb:
getARMMultilibFlags(D, Triple, Args, Result);
getARMMultilibFlags(D, Triple, RelocationModel, Args, Result);
break;
case llvm::Triple::riscv32:
case llvm::Triple::riscv64:
Expand All @@ -376,6 +400,12 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
else
Result.push_back("-fexceptions");

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-NO-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 -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-PIC2: -fPIC
// CHECK-PIE2: -fPIE
// CHECK-NO-PIC: -fno-pic
// CHECK-NO-ROPI: -fno-ropi
// CHECK-NO-RWPI: -fno-rwpi
// CHECK-PIC1: -fpic
// CHECK-PIE1: -fpie
// CHECK-ROPI: -fropi
// CHECK-RWPI: -frwpi