[BOLT] Mark BOLTReserved segment executable (#181606)
Summary: When .bolt_reserved section is defined in the linker script, there's no way to mark the containing segment executable other than via PHDRS command which overrides program headers entirely which is impractical. Since .bolt_reserved contains executable code, mark segment executable in BOLT. Test Plan: bolt-reserved.test
This commit is contained in:
parent
31e5f86a3c
commit
393adaac1d
2 changed files with 41 additions and 1 deletions
|
|
@ -4544,7 +4544,7 @@ void RewriteInstance::patchELFPHDRTable() {
|
|||
|
||||
Phnum = Obj.getHeader().e_phnum;
|
||||
|
||||
if (BC->NewSegments.empty()) {
|
||||
if (BC->NewSegments.empty() && BC->BOLTReserved.empty()) {
|
||||
BC->outs() << "BOLT-INFO: not adding new segments\n";
|
||||
return;
|
||||
}
|
||||
|
|
@ -4597,6 +4597,13 @@ void RewriteInstance::patchELFPHDRTable() {
|
|||
for (const ELF64LE::Phdr &Phdr : cantFail(Obj.program_headers())) {
|
||||
ELF64LE::Phdr NewPhdr = Phdr;
|
||||
switch (Phdr.p_type) {
|
||||
case ELF::PT_LOAD: {
|
||||
// Mark segment as executable if it contains BOLTReserved space.
|
||||
AddressRange Seg(Phdr.p_vaddr, Phdr.p_vaddr + Phdr.p_memsz);
|
||||
if (!BC->BOLTReserved.empty() && Seg.contains(BC->BOLTReserved))
|
||||
NewPhdr.p_flags |= ELF::PF_X;
|
||||
break;
|
||||
}
|
||||
case ELF::PT_PHDR:
|
||||
if (PHDRTableAddress) {
|
||||
NewPhdr.p_offset = PHDRTableOffset;
|
||||
|
|
|
|||
33
bolt/test/bolt-reserved.test
Normal file
33
bolt/test/bolt-reserved.test
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
# Check that BOLT marks segment containing .bolt_reserved as executable
|
||||
|
||||
# RUN: split-file %s %t
|
||||
# RUN: %clang %cflags %t/src.c -Wl,--script=%t/ld.script -Wl,-q -o %t.exe
|
||||
|
||||
# Confirm the segment is not executable
|
||||
# RUN: llvm-readelf -We %t.exe | FileCheck %s --check-prefix=CHECK-SEG-BEFORE
|
||||
|
||||
# Capture section VMA and offset
|
||||
# CHECK-SEG-BEFORE: Section Headers:
|
||||
# CHECK-SEG-BEFORE: .bolt.reserved PROGBITS [[#ADDR:]] [[#OFF:]]
|
||||
|
||||
# Config segment flags
|
||||
# CHECK-SEG-BEFORE: Program Headers:
|
||||
# CHECK-SEG-BEFORE: LOAD 0x{{0*}}[[#OFF]] 0x{{0*}}[[#ADDR]] {{.*}} R 0x200000
|
||||
|
||||
# RUN: llvm-bolt %t.exe -o %t.bolt
|
||||
# Confirm the segment is now marked as executable
|
||||
# RUN: llvm-readelf -We %t.bolt | FileCheck %s --check-prefix=CHECK-SEG-AFTER
|
||||
# CHECK-SEG-AFTER: .bolt.reserved PROGBITS [[#ADDR:]] [[#OFF:]]
|
||||
# CHECK-SEG-AFTER: LOAD 0x{{0*}}[[#OFF]] 0x{{0*}}[[#ADDR]] {{.*}} R E 0x200000
|
||||
|
||||
#--- src.c
|
||||
int main() { return 0; }
|
||||
|
||||
#--- ld.script
|
||||
SECTIONS {
|
||||
.bolt.reserved : ALIGN(2M) {
|
||||
__bolt_reserved_start = .;
|
||||
. += 2M;
|
||||
__bolt_reserved_end = .;
|
||||
}
|
||||
} INSERT AFTER .text;
|
||||
Loading…
Reference in a new issue