@@ -3926,11 +3926,6 @@ void RewriteInstance::patchELFPHDRTable() {
3926
3926
3927
3927
OS.seek (PHDRTableOffset);
3928
3928
3929
- bool ModdedGnuStack = false ;
3930
- (void )ModdedGnuStack;
3931
- bool AddedSegment = false ;
3932
- (void )AddedSegment;
3933
-
3934
3929
auto createNewTextPhdr = [&]() {
3935
3930
ELF64LEPhdrTy NewPhdr;
3936
3931
NewPhdr.p_type = ELF::PT_LOAD;
@@ -3946,38 +3941,51 @@ void RewriteInstance::patchELFPHDRTable() {
3946
3941
NewPhdr.p_filesz = NewTextSegmentSize;
3947
3942
NewPhdr.p_memsz = NewTextSegmentSize;
3948
3943
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.
3952
3947
NewPhdr.p_flags |= ELF::PF_W;
3948
+ }
3953
3949
NewPhdr.p_align = BC->PageAlign ;
3954
3950
3955
3951
return NewPhdr;
3956
3952
};
3957
3953
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
+ }
3969
3970
};
3970
3971
3972
+ bool ModdedGnuStack = false ;
3973
+ bool AddedSegment = false ;
3974
+
3971
3975
// Copy existing program headers with modifications.
3972
3976
for (const ELF64LE::Phdr &Phdr : cantFail (Obj.program_headers ())) {
3973
3977
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: {
3981
3989
ErrorOr<BinarySection &> EHFrameHdrSec = BC->getUniqueSectionByName (
3982
3990
getNewSecPrefix () + getEHFrameHdrSectionName ());
3983
3991
if (EHFrameHdrSec && EHFrameHdrSec->isAllocatable () &&
@@ -3988,37 +3996,36 @@ void RewriteInstance::patchELFPHDRTable() {
3988
3996
NewPhdr.p_filesz = EHFrameHdrSec->getOutputSize ();
3989
3997
NewPhdr.p_memsz = EHFrameHdrSec->getOutputSize ();
3990
3998
}
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 ;
4003
4013
}
4004
- AddedSegment = true ;
4014
+ break ;
4005
4015
}
4006
4016
OS.write (reinterpret_cast <const char *>(&NewPhdr), sizeof (NewPhdr));
4007
4017
}
4008
4018
4009
4019
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 ();
4018
4022
}
4019
4023
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
+ }
4022
4029
}
4023
4030
4024
4031
namespace {
0 commit comments