forked from OSchip/llvm-project
[AArch64] Support execute-only LOAD segments.
Summary: This adds an LLD flag to mark executable LOAD segments execute-only for AArch64 targets. In AArch64 the expectation is that code is execute-only compatible, so this just adds a linker option to enforce this. Patch by: ivanlozano (Ivan Lozano) Reviewers: srhines, echristo, peter.smith, eugenis, javed.absar, espindola, ruiu Reviewed By: ruiu Subscribers: dokyungs, emaste, arichardson, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D49456 llvm-svn: 338271
This commit is contained in:
parent
2fa7fb14ea
commit
a932cd409b
|
@ -133,6 +133,7 @@ struct Configuration {
|
|||
bool EhFrameHdr;
|
||||
bool EmitRelocs;
|
||||
bool EnableNewDtags;
|
||||
bool ExecuteOnly;
|
||||
bool ExportDynamic;
|
||||
bool FixCortexA53Errata843419;
|
||||
bool GcSections;
|
||||
|
|
|
@ -302,6 +302,14 @@ static void checkOptions(opt::InputArgList &Args) {
|
|||
if (Config->Pie)
|
||||
error("-r and -pie may not be used together");
|
||||
}
|
||||
|
||||
if (Config->ExecuteOnly) {
|
||||
if (Config->EMachine != EM_AARCH64)
|
||||
error("-execute-only is only supported on AArch64 targets");
|
||||
|
||||
if (Config->SingleRoRx && !Script->HasSectionsCommand)
|
||||
error("-execute-only and -no-rosegment cannot be used together");
|
||||
}
|
||||
}
|
||||
|
||||
static const char *getReproduceOption(opt::InputArgList &Args) {
|
||||
|
@ -747,6 +755,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
|||
Config->EnableNewDtags =
|
||||
Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
|
||||
Config->Entry = Args.getLastArgValue(OPT_entry);
|
||||
Config->ExecuteOnly =
|
||||
Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
|
||||
Config->ExportDynamic =
|
||||
Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
|
||||
Config->FilterList = args::getStrings(Args, OPT_filter);
|
||||
|
|
|
@ -131,6 +131,10 @@ def error_unresolved_symbols: F<"error-unresolved-symbols">,
|
|||
|
||||
defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
|
||||
|
||||
defm execute_only: B<"execute-only",
|
||||
"Do not mark executable sections readable",
|
||||
"Mark executable sections readable (default)">;
|
||||
|
||||
defm export_dynamic: B<"export-dynamic",
|
||||
"Put symbols in the dynamic symbol table",
|
||||
"Do not put symbols in the dynamic symbol table (default)">;
|
||||
|
|
|
@ -1608,6 +1608,15 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
if (auto *Sec = dyn_cast<OutputSection>(Base))
|
||||
OutputSections.push_back(Sec);
|
||||
|
||||
// Ensure data sections are not mixed with executable sections when
|
||||
// -execute-only is used.
|
||||
if (Config->ExecuteOnly)
|
||||
for (OutputSection *OS : OutputSections)
|
||||
if (OS->Flags & SHF_EXECINSTR)
|
||||
for (InputSection *IS : getInputSections(OS))
|
||||
if (!(IS->Flags & SHF_EXECINSTR))
|
||||
error("-execute-only does not support intermingling data and code");
|
||||
|
||||
// Prefer command line supplied address over other constraints.
|
||||
for (OutputSection *Sec : OutputSections) {
|
||||
auto I = Config->SectionStartMap.find(Sec->Name);
|
||||
|
@ -1767,6 +1776,8 @@ static bool needsPtLoad(OutputSection *Sec) {
|
|||
static uint64_t computeFlags(uint64_t Flags) {
|
||||
if (Config->Omagic)
|
||||
return PF_R | PF_W | PF_X;
|
||||
if (Config->ExecuteOnly && (Flags & PF_X))
|
||||
return Flags & ~PF_R;
|
||||
if (Config->SingleRoRx && !(Flags & PF_W))
|
||||
return Flags | PF_X;
|
||||
return Flags;
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
// REQUIRES: aarch64
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
|
||||
|
||||
// RUN: echo "SECTIONS \
|
||||
// RUN: { \
|
||||
// RUN: .text : { *(.text) *(.rodata.foo) } \
|
||||
// RUN: .rodata : { *(.rodata.bar) } \
|
||||
// RUN: }" > %t.lds
|
||||
// RUN: not ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: echo "SECTIONS \
|
||||
// RUN: { \
|
||||
// RUN: .text : { *(.text) } \
|
||||
// RUN: .rodata : { *(.rodata.bar) *(.rodata.foo) } \
|
||||
// RUN: }" > %t.lds
|
||||
// RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1
|
||||
|
||||
// CHECK: -execute-only does not support intermingling data and code
|
||||
|
||||
br lr
|
||||
|
||||
.section .rodata.foo
|
||||
.word 0x1
|
||||
.section .rodata.bar
|
||||
.word 0x2
|
|
@ -0,0 +1,10 @@
|
|||
// REQUIRES: aarch64
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
|
||||
// RUN: ld.lld -Ttext=0xcafe0000 %t.o -o %t.so -shared -execute-only
|
||||
// RUN: llvm-readelf -l %t.so | FileCheck %s
|
||||
|
||||
// CHECK: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 E 0x{{.*}}
|
||||
// CHECK-NOT: LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 R E 0x{{.*}}
|
||||
|
||||
br lr
|
Loading…
Reference in New Issue