Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -113,6 +113,7 @@ llvm::MapVector, uint64_t> CallGraphProfile; + bool AArch64ExecuteOnly; bool AllowMultipleDefinition; bool AndroidPackDynRelocs; bool ARMHasBlx = false; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -299,6 +299,14 @@ if (Config->Pie) error("-r and -pie may not be used together"); } + + if (Config->AArch64ExecuteOnly) { + if (Config->EMachine != EM_AARCH64) + error("-aarch64-execute-only is only supported on AArch64 targets."); + + if (Config->SingleRoRx) + error("-aarch64-execute-only and -no-rosegment cannot be used together."); + } } static const char *getReproduceOption(opt::InputArgList &Args) { @@ -735,6 +743,8 @@ Config->EnableNewDtags = Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true); Config->Entry = Args.getLastArgValue(OPT_entry); + Config->AArch64ExecuteOnly = Args.hasFlag(OPT_aarch64_execute_only, + OPT_no_aarch64_execute_only, false); Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false); Config->FilterList = args::getStrings(Args, OPT_filter); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -243,6 +243,10 @@ "Create a position independent executable", "Do not create a position independent executable (default)">; +defm aarch64_execute_only: B<"aarch64-execute-only", + "Do not mark executable sections readable.", + "Mark executable sections readable.">; + defm print_gc_sections: B<"print-gc-sections", "List removed unused sections", "Do not list removed unused sections (default)">; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1768,6 +1768,9 @@ return PF_R | PF_W | PF_X; if (Config->SingleRoRx && !(Flags & PF_W)) return Flags | PF_X; + if (Config->EMachine == EM_AARCH64 && Config->AArch64ExecuteOnly && + (Flags & PF_X)) + return Flags & ~PF_R; return Flags; } Index: test/ELF/aarch64_execute_only.s =================================================================== --- /dev/null +++ test/ELF/aarch64_execute_only.s @@ -0,0 +1,12 @@ +// REQUIRES: aarch64 + +// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o +// RUN: ld.lld %t.o -o %t.so -shared -aarch64-execute-only +// RUN: llvm-readelf -l %t.so | FileCheck %s + +// CHECK: LOAD 0x{{.*}} 0x{{.*}} 0x{{.*}} 0x{{.*}} 0x{{.*}} E 0x{{.*}} +// CHECK-NOT: LOAD 0x{{.*}} 0x{{.*}} 0x{{.*}} 0x{{.*}} 0x{{.*}} R E 0x{{.*}} + + br lr + .section .foo,"ax" + br lr