Skip to content

Commit 3ec858b

Browse files
authored
[BOLT] Refactor patchELFPHDRTable() (#90290)
Mostly NFC accept for one assertion that was converted into an error.
1 parent ad2816e commit 3ec858b

File tree

1 file changed

+56
-49
lines changed

1 file changed

+56
-49
lines changed

bolt/lib/Rewrite/RewriteInstance.cpp

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,11 +3926,6 @@ void RewriteInstance::patchELFPHDRTable() {
39263926

39273927
OS.seek(PHDRTableOffset);
39283928

3929-
bool ModdedGnuStack = false;
3930-
(void)ModdedGnuStack;
3931-
bool AddedSegment = false;
3932-
(void)AddedSegment;
3933-
39343929
auto createNewTextPhdr = [&]() {
39353930
ELF64LEPhdrTy NewPhdr;
39363931
NewPhdr.p_type = ELF::PT_LOAD;
@@ -3946,38 +3941,51 @@ void RewriteInstance::patchELFPHDRTable() {
39463941
NewPhdr.p_filesz = NewTextSegmentSize;
39473942
NewPhdr.p_memsz = NewTextSegmentSize;
39483943
NewPhdr.p_flags = ELF::PF_X | ELF::PF_R;
3949-
// FIXME: Currently instrumentation is experimental and the runtime data
3950-
// is emitted with code, thus everything needs to be writable
3951-
if (opts::Instrument)
3944+
if (opts::Instrument) {
3945+
// FIXME: Currently instrumentation is experimental and the runtime data
3946+
// is emitted with code, thus everything needs to be writable.
39523947
NewPhdr.p_flags |= ELF::PF_W;
3948+
}
39533949
NewPhdr.p_align = BC->PageAlign;
39543950

39553951
return NewPhdr;
39563952
};
39573953

3958-
auto createNewWritableSectionsPhdr = [&]() {
3959-
ELF64LEPhdrTy NewPhdr;
3960-
NewPhdr.p_type = ELF::PT_LOAD;
3961-
NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress);
3962-
NewPhdr.p_vaddr = NewWritableSegmentAddress;
3963-
NewPhdr.p_paddr = NewWritableSegmentAddress;
3964-
NewPhdr.p_filesz = NewWritableSegmentSize;
3965-
NewPhdr.p_memsz = NewWritableSegmentSize;
3966-
NewPhdr.p_align = BC->RegularPageSize;
3967-
NewPhdr.p_flags = ELF::PF_R | ELF::PF_W;
3968-
return NewPhdr;
3954+
auto writeNewSegmentPhdrs = [&]() {
3955+
ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
3956+
OS.write(reinterpret_cast<const char *>(&NewTextPhdr), sizeof(NewTextPhdr));
3957+
3958+
if (NewWritableSegmentSize) {
3959+
ELF64LEPhdrTy NewPhdr;
3960+
NewPhdr.p_type = ELF::PT_LOAD;
3961+
NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress);
3962+
NewPhdr.p_vaddr = NewWritableSegmentAddress;
3963+
NewPhdr.p_paddr = NewWritableSegmentAddress;
3964+
NewPhdr.p_filesz = NewWritableSegmentSize;
3965+
NewPhdr.p_memsz = NewWritableSegmentSize;
3966+
NewPhdr.p_align = BC->RegularPageSize;
3967+
NewPhdr.p_flags = ELF::PF_R | ELF::PF_W;
3968+
OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr));
3969+
}
39693970
};
39703971

3972+
bool ModdedGnuStack = false;
3973+
bool AddedSegment = false;
3974+
39713975
// Copy existing program headers with modifications.
39723976
for (const ELF64LE::Phdr &Phdr : cantFail(Obj.program_headers())) {
39733977
ELF64LE::Phdr NewPhdr = Phdr;
3974-
if (PHDRTableAddress && Phdr.p_type == ELF::PT_PHDR) {
3975-
NewPhdr.p_offset = PHDRTableOffset;
3976-
NewPhdr.p_vaddr = PHDRTableAddress;
3977-
NewPhdr.p_paddr = PHDRTableAddress;
3978-
NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum;
3979-
NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum;
3980-
} else if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) {
3978+
switch (Phdr.p_type) {
3979+
case ELF::PT_PHDR:
3980+
if (PHDRTableAddress) {
3981+
NewPhdr.p_offset = PHDRTableOffset;
3982+
NewPhdr.p_vaddr = PHDRTableAddress;
3983+
NewPhdr.p_paddr = PHDRTableAddress;
3984+
NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum;
3985+
NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum;
3986+
}
3987+
break;
3988+
case ELF::PT_GNU_EH_FRAME: {
39813989
ErrorOr<BinarySection &> EHFrameHdrSec = BC->getUniqueSectionByName(
39823990
getNewSecPrefix() + getEHFrameHdrSectionName());
39833991
if (EHFrameHdrSec && EHFrameHdrSec->isAllocatable() &&
@@ -3988,37 +3996,36 @@ void RewriteInstance::patchELFPHDRTable() {
39883996
NewPhdr.p_filesz = EHFrameHdrSec->getOutputSize();
39893997
NewPhdr.p_memsz = EHFrameHdrSec->getOutputSize();
39903998
}
3991-
} else if (opts::UseGnuStack && Phdr.p_type == ELF::PT_GNU_STACK) {
3992-
NewPhdr = createNewTextPhdr();
3993-
ModdedGnuStack = true;
3994-
} else if (!opts::UseGnuStack && Phdr.p_type == ELF::PT_DYNAMIC) {
3995-
// Insert the new header before DYNAMIC.
3996-
ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
3997-
OS.write(reinterpret_cast<const char *>(&NewTextPhdr),
3998-
sizeof(NewTextPhdr));
3999-
if (NewWritableSegmentSize) {
4000-
ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr();
4001-
OS.write(reinterpret_cast<const char *>(&NewWritablePhdr),
4002-
sizeof(NewWritablePhdr));
3999+
break;
4000+
}
4001+
case ELF::PT_GNU_STACK:
4002+
if (opts::UseGnuStack) {
4003+
// Overwrite the header with the new text segment header.
4004+
NewPhdr = createNewTextPhdr();
4005+
ModdedGnuStack = true;
4006+
}
4007+
break;
4008+
case ELF::PT_DYNAMIC:
4009+
if (!opts::UseGnuStack) {
4010+
// Insert new headers before DYNAMIC.
4011+
writeNewSegmentPhdrs();
4012+
AddedSegment = true;
40034013
}
4004-
AddedSegment = true;
4014+
break;
40054015
}
40064016
OS.write(reinterpret_cast<const char *>(&NewPhdr), sizeof(NewPhdr));
40074017
}
40084018

40094019
if (!opts::UseGnuStack && !AddedSegment) {
4010-
// Append the new header to the end of the table.
4011-
ELF64LE::Phdr NewTextPhdr = createNewTextPhdr();
4012-
OS.write(reinterpret_cast<const char *>(&NewTextPhdr), sizeof(NewTextPhdr));
4013-
if (NewWritableSegmentSize) {
4014-
ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr();
4015-
OS.write(reinterpret_cast<const char *>(&NewWritablePhdr),
4016-
sizeof(NewWritablePhdr));
4017-
}
4020+
// Append new headers to the end of the table.
4021+
writeNewSegmentPhdrs();
40184022
}
40194023

4020-
assert((!opts::UseGnuStack || ModdedGnuStack) &&
4021-
"could not find GNU_STACK program header to modify");
4024+
if (opts::UseGnuStack && !ModdedGnuStack) {
4025+
BC->errs()
4026+
<< "BOLT-ERROR: could not find PT_GNU_STACK program header to modify\n";
4027+
exit(1);
4028+
}
40224029
}
40234030

40244031
namespace {

0 commit comments

Comments
 (0)