-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[AArch64] Always add PURECODE flag to empty .text if "+execute-only" is set #132196
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…is set The previous approach only added the `SHF_AARCH64_PURECODE` section flag to the implicitly created `.text` section if there was any other section containing the flag already. This doesn't work for the case, where the module doesn't contain any code. Now, the `SHF_AARCH64_PURECODE` is always added if the "+execute-only" target feature is set for the module.
@llvm/pr-subscribers-backend-aarch64 Author: Csanád Hajdú (Il-Capitano) ChangesThe previous approach only added the Now, the Full diff: https://github.com/llvm/llvm-project/pull/132196.diff 3 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
index 434ae32502d48..b662e75741d38 100644
--- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
+++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp
@@ -16,6 +16,7 @@
#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCValue.h"
using namespace llvm;
@@ -27,6 +28,14 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
// AARCH64 ELF ABI does not define static relocation type for TLS offset
// within a module. Do not generate AT_location for TLS variables.
SupportDebugThreadLocalLocation = false;
+
+ // Make sure the implicitly created empty .text section has the
+ // SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is
+ // present.
+ if (TM.getMCSubtargetInfo()->hasFeature(AArch64::FeatureExecuteOnly)) {
+ auto *Text = cast<MCSectionELF>(TextSection);
+ Text->setFlags(Text->getFlags() | ELF::SHF_AARCH64_PURECODE);
+ }
}
void AArch64_ELFTargetObjectFile::emitPersonalityValueImpl(
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index 98bd102d8f4c1..9803129608c4b 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -27,7 +27,6 @@
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -501,23 +500,6 @@ void AArch64TargetELFStreamer::finish() {
}
}
- // The mix of execute-only and non-execute-only at link time is
- // non-execute-only. To avoid the empty implicitly created .text
- // section from making the whole .text section non-execute-only, we
- // mark it execute-only if it is empty and there is at least one
- // execute-only section in the object.
- if (any_of(Asm, [](const MCSection &Sec) {
- return cast<MCSectionELF>(Sec).getFlags() & ELF::SHF_AARCH64_PURECODE;
- })) {
- auto *Text =
- static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
- for (auto &F : *Text)
- if (auto *DF = dyn_cast<MCDataFragment>(&F))
- if (!DF->getContents().empty())
- return;
- Text->setFlags(Text->getFlags() | ELF::SHF_AARCH64_PURECODE);
- }
-
MCSectionELF *MemtagSec = nullptr;
for (const MCSymbol &Symbol : Asm.symbols()) {
const auto &Sym = cast<MCSymbolELF>(Symbol);
diff --git a/llvm/test/CodeGen/AArch64/execute-only-empty.ll b/llvm/test/CodeGen/AArch64/execute-only-empty.ll
new file mode 100644
index 0000000000000..cdf9b3afe8daf
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/execute-only-empty.ll
@@ -0,0 +1,13 @@
+; RUN: llc -filetype=obj -mtriple=aarch64 -mattr=+execute-only %s -o %t.o
+; RUN: llvm-readobj -S %t.o | FileCheck %s
+
+; CHECK: Name: .text
+; CHECK-NEXT: Type: SHT_PROGBITS
+; CHECK-NEXT: Flags [
+; CHECK-NEXT: SHF_AARCH64_PURECODE
+; CHECK-NEXT: SHF_ALLOC
+; CHECK-NEXT: SHF_EXECINSTR
+; CHECK-NEXT: ]
+; CHECK-NEXT: Address:
+; CHECK-NEXT: Offset:
+; CHECK-NEXT: Size: 0
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Looking at the ARM backend code https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp#L46 it does it in a slightly different way, claiming that it can't modify flags on an existing section. It looks like that restriction has been lifted though.
The tests show that it is working and it is simpler to modify, so no objections to doing it that way.
Yeah, I'm not sure why it's that way in the ARM backend. A similar mechanism is needed in Target/ARM/MCTargetDesc/ARMELFStreamer.cpp (and AArch64ELFStreamer.cpp too), where it also modifies the flags on the existing section: llvm-project/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp Lines 1136 to 1154 in 382b707
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/14822 Here is the relevant piece of the build log for the reference
|
A rebuild fixed the CI failure: https://lab.llvm.org/buildbot/#/builders/59/builds/14823. Probably just a flaky test in LLDB. |
Previously, the
SHF_AARCH64_PURECODE
section flag wasn't added to the implicitly created.text
section if the module didn't contain any functions, because no other section had the flag set.Now, the
SHF_AARCH64_PURECODE
is always added if the "+execute-only" target feature is set for the module during compilation.