Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[Clang][Driver] Expose relocation model as multilib flags#149132

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
statham-arm merged 4 commits intollvm:mainfromstatham-arm:multilib-relocation-model
Jul 18, 2025

Conversation

statham-arm
Copy link
Collaborator

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), thenmultilib.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 formultilib.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 inParsePICArgs, and translate it back into a canonical set of multilib selection flags.

If a multilib collection contains libraries built for differentmethods of accessing global data (via absolute address, or via a GOTin -fPIC style, or as an offset from a fixed register in Arm -frwpistyle), then `multilib.yaml` will need to know which relocation modelan application is using in order to select the right library.Even if a multilib collection only supports one relocation model, it'sstill useful for `multilib.yaml` to be able to tell if the user hasselected the right one, so as to give a useful error message if theyhaven't, instead of silently selecting a library that won't work.In this commit we determine the PIC / ROPI / RWPI status using theexisting logic in `ParsePICArgs`, and translate it back into acanonical set of multilib selection flags.
@llvmbotllvmbot added clangClang issues not falling into any other category clang:driver'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labelsJul 16, 2025
@llvmbot
Copy link
Member

@llvm/pr-subscribers-clang

Author: Simon Tatham (statham-arm)

Changes

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), thenmultilib.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 formultilib.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 inParsePICArgs, and translate it back into a canonical set of multilib selection flags.


Full diff:https://github.com/llvm/llvm-project/pull/149132.diff

2 Files Affected:

  • (modified) clang/lib/Driver/ToolChain.cpp (+37)
  • (modified) clang/test/Driver/print-multi-selection-flags.c (+19)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cppindex 3f9b808b2722e..5738c0aa9b1d2 100644--- a/clang/lib/Driver/ToolChain.cpp+++ b/clang/lib/Driver/ToolChain.cpp@@ -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:@@ -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:@@ -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) {+      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());diff --git a/clang/test/Driver/print-multi-selection-flags.c b/clang/test/Driver/print-multi-selection-flags.cindex 5f9383fbed8f4..1d794091970d3 100644--- a/clang/test/Driver/print-multi-selection-flags.c+++ b/clang/test/Driver/print-multi-selection-flags.c@@ -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

@llvmbot
Copy link
Member

@llvm/pr-subscribers-clang-driver

Author: Simon Tatham (statham-arm)

Changes

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), thenmultilib.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 formultilib.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 inParsePICArgs, and translate it back into a canonical set of multilib selection flags.


Full diff:https://github.com/llvm/llvm-project/pull/149132.diff

2 Files Affected:

  • (modified) clang/lib/Driver/ToolChain.cpp (+37)
  • (modified) clang/test/Driver/print-multi-selection-flags.c (+19)
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cppindex 3f9b808b2722e..5738c0aa9b1d2 100644--- a/clang/lib/Driver/ToolChain.cpp+++ b/clang/lib/Driver/ToolChain.cpp@@ -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:@@ -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:@@ -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) {+      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());diff --git a/clang/test/Driver/print-multi-selection-flags.c b/clang/test/Driver/print-multi-selection-flags.cindex 5f9383fbed8f4..1d794091970d3 100644--- a/clang/test/Driver/print-multi-selection-flags.c+++ b/clang/test/Driver/print-multi-selection-flags.c@@ -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

@github-actionsGitHub Actions
Copy link

github-actionsbot commentedJul 16, 2025
edited
Loading

✅ With the latest revision this PR passed the C/C++ code formatter.

@statham-arm
Copy link
CollaboratorAuthor

Note to reviewers: the thing I'm most uncertain of in this patch is whether I'm using the right strategy for finding out the information about relocation model.

ParsePICArgs looked sensible, but then failed an assertion if there was no "effective triple" set, so I dug out whatlooked like the obvious way to figure one out, and did that.

But I'm notvery confident of what an "effective triple" is at all, and I don't know for sure that it's right to callComputeEffectiveClangTriple(Args) to make one. So if there's any reason why that will give the wrong answer in a particular situation (e.g. because some information it depends on isn't finalized yet) then please don't assume I have a clever reason for knowing why it's safe after all 🙂

(Thanks to clang-format for pointing out the trailing space on thatline, which was there because I meant to type a word after it!)
// 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 intogetARMMultilibFlags? 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
CollaboratorAuthor

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 ingetARMMultilibFlags, 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 intogetARMMultilibFlags where it can add the Arm-specific options.

@statham-arm
Copy link
CollaboratorAuthor

But I'm notvery confident of what an "effective triple" is at all, and I don't know for sure that it's right to callComputeEffectiveClangTriple(Args) to make one.

Answering my own question: I had failed to spot thatToolChain::getMultilibFlags wasalready callingComputeEffectiveClangTriple at the top of the function! So I'm now more confident that it's sensible, but also, I could have just reused the existing value 🙂

All the CHECK lines are checked in a single run of FileCheck, so theoptions they mention must appear in the same order that the flags areshown in the -print-multi-flags output, which is ASCII sorting order.
@statham-armstatham-arm merged commit3ce06b8 intollvm:mainJul 18, 2025
9 checks passed
statham-arm added a commit to arm/arm-toolchain that referenced this pull requestJul 18, 2025
ATfE doesn't currently provide any library variants built for RWPI. Andif you link RWPI with non-RWPI code, nothing good will happen – theyhave incompatible ABIs. So we ought to give an error message rather thansilently choose an incompatible library.Usingllvm/llvm-project#149132 which allowedmultilib selection to be aware of the relocation model at all, thiscommit does the simplest possible thing: adds a catch-all error messagethat will trigger on _any_ use of `-frwpi`, and report that there's nosuitable library variant.(Another possibility would have been to add `-fno-rwpi` to the validitycriteria for each existing library, but that seemed less likely to givea good error message. It would allow RWPI variants to be present forsome cases but not all, but at the moment, we don't need that.)Since the error message works the same everywhere, I've just added onetest.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@vhscamposvhscamposvhscampos approved these changes

@compnerdcompnerdAwaiting requested review from compnerd

@zygoloidzygoloidAwaiting requested review from zygoloid

@jroelofsjroelofsAwaiting requested review from jroelofs

@smithp35smithp35Awaiting requested review from smithp35

Assignees
No one assigned
Labels
clang:driver'clang' and 'clang++' user-facing binaries. Not 'clang-cl'clangClang issues not falling into any other category
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@statham-arm@llvmbot@vhscampos

[8]ページ先頭

©2009-2025 Movatter.jp