[llvm] [BOLT] Refactor patchELFPHDRTable() (PR #90290)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 26 16:02:34 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Maksim Panchenko (maksfb)
<details>
<summary>Changes</summary>
Mostly NFC accept for one assertion that was converted into an error.
---
Full diff: https://github.com/llvm/llvm-project/pull/90290.diff
1 Files Affected:
- (modified) bolt/lib/Rewrite/RewriteInstance.cpp (+56-49)
``````````diff
diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 409835537fdeee..065260936e70a5 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3926,11 +3926,6 @@ void RewriteInstance::patchELFPHDRTable() {
OS.seek(PHDRTableOffset);
- bool ModdedGnuStack = false;
- (void)ModdedGnuStack;
- bool AddedSegment = false;
- (void)AddedSegment;
-
auto createNewTextPhdr = [&]() {
ELF64LEPhdrTy NewPhdr;
NewPhdr.p_type = ELF::PT_LOAD;
@@ -3946,38 +3941,51 @@ void RewriteInstance::patchELFPHDRTable() {
NewPhdr.p_filesz = NewTextSegmentSize;
NewPhdr.p_memsz = NewTextSegmentSize;
NewPhdr.p_flags = ELF::PF_X | ELF::PF_R;
- // FIXME: Currently instrumentation is experimental and the runtime data
- // is emitted with code, thus everything needs to be writable
- if (opts::Instrument)
+ if (opts::Instrument) {
+ // FIXME: Currently instrumentation is experimental and the runtime data
+ // is emitted with code, thus everything needs to be writable.
NewPhdr.p_flags |= ELF::PF_W;
+ }
NewPhdr.p_align = BC->PageAlign;
return NewPhdr;
};
- auto createNewWritableSectionsPhdr = [&]() {
- ELF64LEPhdrTy NewPhdr;
- NewPhdr.p_type = ELF::PT_LOAD;
- NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress);
- NewPhdr.p_vaddr = NewWritableSegmentAddress;
- NewPhdr.p_paddr = NewWritableSegmentAddress;
- NewPhdr.p_filesz = NewWritableSegmentSize;
- NewPhdr.p_memsz = NewWritableSegmentSize;
- NewPhdr.p_align = BC->RegularPageSize;
- NewPhdr.p_flags = ELF::PF_R | ELF::PF_W;
- return NewPhdr;
+ auto writeNewSegmentPhdrs = [&]() {
+ ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
+ OS.write(reinterpret_cast<const char *>(&NewTextPhdr), sizeof(NewTextPhdr));
+
+ if (NewWritableSegmentSize) {
+ ELF64LEPhdrTy NewPhdr;
+ NewPhdr.p_type = ELF::PT_LOAD;
+ NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress);
+ NewPhdr.p_vaddr = NewWritableSegmentAddress;
+ NewPhdr.p_paddr = NewWritableSegmentAddress;
+ NewPhdr.p_filesz = NewWritableSegmentSize;
+ NewPhdr.p_memsz = NewWritableSegmentSize;
+ NewPhdr.p_align = BC->RegularPageSize;
+ NewPhdr.p_flags = ELF::PF_R | ELF::PF_W;
+ OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr));
+ }
};
+ bool ModdedGnuStack = false;
+ bool AddedSegment = false;
+
// Copy existing program headers with modifications.
for (const ELF64LE::Phdr &Phdr : cantFail(Obj.program_headers())) {
ELF64LE::Phdr NewPhdr = Phdr;
- if (PHDRTableAddress && Phdr.p_type == ELF::PT_PHDR) {
- NewPhdr.p_offset = PHDRTableOffset;
- NewPhdr.p_vaddr = PHDRTableAddress;
- NewPhdr.p_paddr = PHDRTableAddress;
- NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum;
- NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum;
- } else if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {
+ switch (Phdr.p_type) {
+ case ELF::PT_PHDR:
+ if (PHDRTableAddress) {
+ NewPhdr.p_offset = PHDRTableOffset;
+ NewPhdr.p_vaddr = PHDRTableAddress;
+ NewPhdr.p_paddr = PHDRTableAddress;
+ NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum;
+ NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum;
+ }
+ break;
+ case ELF::PT_GNU_EH_FRAME: {
ErrorOr<BinarySection &> EHFrameHdrSec = BC->getUniqueSectionByName(
getNewSecPrefix() + getEHFrameHdrSectionName());
if (EHFrameHdrSec && EHFrameHdrSec->isAllocatable() &&
@@ -3988,37 +3996,36 @@ void RewriteInstance::patchELFPHDRTable() {
NewPhdr.p_filesz = EHFrameHdrSec->getOutputSize();
NewPhdr.p_memsz = EHFrameHdrSec->getOutputSize();
}
- } else if (opts::UseGnuStack && Phdr.p_type == ELF::PT_GNU_STACK) {
- NewPhdr = createNewTextPhdr();
- ModdedGnuStack = true;
- } else if (!opts::UseGnuStack && Phdr.p_type == ELF::PT_DYNAMIC) {
- // Insert the new header before DYNAMIC.
- ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
- OS.write(reinterpret_cast<const char *>(&NewTextPhdr),
- sizeof(NewTextPhdr));
- if (NewWritableSegmentSize) {
- ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr();
- OS.write(reinterpret_cast<const char *>(&NewWritablePhdr),
- sizeof(NewWritablePhdr));
+ break;
+ }
+ case ELF::PT_GNU_STACK:
+ if (opts::UseGnuStack) {
+ // Overwrite the header with the new text segment header.
+ NewPhdr = createNewTextPhdr();
+ ModdedGnuStack = true;
+ }
+ break;
+ case ELF::PT_DYNAMIC:
+ if (!opts::UseGnuStack) {
+ // Insert new headers before DYNAMIC.
+ writeNewSegmentPhdrs();
+ AddedSegment = true;
}
- AddedSegment = true;
+ break;
}
OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr));
}
if (!opts::UseGnuStack && !AddedSegment) {
- // Append the new header to the end of the table.
- ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
- OS.write(reinterpret_cast<const char *>(&NewTextPhdr), sizeof(NewTextPhdr));
- if (NewWritableSegmentSize) {
- ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr();
- OS.write(reinterpret_cast<const char *>(&NewWritablePhdr),
- sizeof(NewWritablePhdr));
- }
+ // Append new headers to the end of the table.
+ writeNewSegmentPhdrs();
}
- assert((!opts::UseGnuStack || ModdedGnuStack) &&
- "could not find GNU_STACK program header to modify");
+ if (opts::UseGnuStack && !ModdedGnuStack) {
+ BC->errs()
+ << "BOLT-ERROR: could not find PT_GNU_STACK program header to modify\n";
+ exit(1);
+ }
}
namespace {
``````````
</details>
https://github.com/llvm/llvm-project/pull/90290
More information about the llvm-commits
mailing list