Skip to content

Commit 3ce06b8

Browse files
authored
[Clang][Driver] Expose relocation model as multilib flags (#149132)
If a multilib collection contains libraries built for different methods of accessing global data (via absolute address, or via a GOT in -fPIC style, or as an offset from a fixed register in Arm -frwpi style), then `multilib.yaml` will need to know which relocation model an application is using in order to select the right library. Even if a multilib collection only supports one relocation model, it's still useful for `multilib.yaml` to be able to tell if the user has selected the right one, so as to give a useful error message if they haven't, instead of silently selecting a library that won't work. In this commit we determine the PIC / ROPI / RWPI status using the existing logic in `ParsePICArgs`, and translate it back into a canonical set of multilib selection flags.
1 parent 88721d6 commit 3ce06b8

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

clang/lib/Driver/ToolChain.cpp

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ static void getAArch64MultilibFlags(const Driver &D,
258258
processMultilibCustomFlags(Result, Args);
259259
}
260260

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

307+
if (RelocationModel == llvm::Reloc::ROPI ||
308+
RelocationModel == llvm::Reloc::ROPI_RWPI)
309+
Result.push_back("-fropi");
310+
else
311+
Result.push_back("-fno-ropi");
312+
313+
if (RelocationModel == llvm::Reloc::RWPI ||
314+
RelocationModel == llvm::Reloc::ROPI_RWPI)
315+
Result.push_back("-frwpi");
316+
else
317+
Result.push_back("-fno-rwpi");
318+
307319
const Arg *BranchProtectionArg =
308320
Args.getLastArgNoClaim(options::OPT_mbranch_protection_EQ);
309321
if (BranchProtectionArg) {
@@ -344,6 +356,18 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
344356
const llvm::Triple Triple(ComputeEffectiveClangTriple(Args));
345357
Result.push_back("--target=" + Triple.str());
346358

359+
// A difference of relocation model (absolutely addressed data, PIC, Arm
360+
// ROPI/RWPI) is likely to change whether a particular multilib variant is
361+
// compatible with a given link. Determine the relocation model of the
362+
// current link, so as to add appropriate multilib flags.
363+
llvm::Reloc::Model RelocationModel;
364+
unsigned PICLevel;
365+
bool IsPIE;
366+
{
367+
RegisterEffectiveTriple TripleRAII(*this, Triple);
368+
std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(*this, Args);
369+
}
370+
347371
switch (Triple.getArch()) {
348372
case llvm::Triple::aarch64:
349373
case llvm::Triple::aarch64_32:
@@ -354,7 +378,7 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
354378
case llvm::Triple::armeb:
355379
case llvm::Triple::thumb:
356380
case llvm::Triple::thumbeb:
357-
getARMMultilibFlags(D, Triple, Args, Result);
381+
getARMMultilibFlags(D, Triple, RelocationModel, Args, Result);
358382
break;
359383
case llvm::Triple::riscv32:
360384
case llvm::Triple::riscv64:
@@ -376,6 +400,12 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
376400
else
377401
Result.push_back("-fexceptions");
378402

403+
if (RelocationModel == llvm::Reloc::PIC_)
404+
Result.push_back(IsPIE ? (PICLevel > 1 ? "-fPIE" : "-fpie")
405+
: (PICLevel > 1 ? "-fPIC" : "-fpic"));
406+
else
407+
Result.push_back("-fno-pic");
408+
379409
// Sort and remove duplicates.
380410
std::sort(Result.begin(), Result.end());
381411
Result.erase(llvm::unique(Result), Result.end());

clang/test/Driver/print-multi-selection-flags.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,22 @@
107107
// CHECK-AARCH64-MULTILIB-CUSTOM-FLAG: --target=aarch64-unknown-none-eabi
108108
// CHECK-MULTILIB-CUSTOM-FLAG-DAG: -fmultilib-flag=foo
109109
// CHECK-MULTILIB-CUSTOM-FLAG-DAG: -fmultilib-flag=bar
110+
111+
// 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
112+
// 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
113+
// 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
114+
// 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
115+
// 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
116+
// 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
117+
// 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
118+
// 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
119+
// 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
120+
// CHECK-PIC2: -fPIC
121+
// CHECK-PIE2: -fPIE
122+
// CHECK-NO-PIC: -fno-pic
123+
// CHECK-NO-ROPI: -fno-ropi
124+
// CHECK-NO-RWPI: -fno-rwpi
125+
// CHECK-PIC1: -fpic
126+
// CHECK-PIE1: -fpie
127+
// CHECK-ROPI: -fropi
128+
// CHECK-RWPI: -frwpi

0 commit comments

Comments
 (0)