Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -130,6 +130,7 @@ bool EhFrameHdr; bool EmitRelocs; bool EnableNewDtags; + bool ExecuteOnly; bool ExportDynamic; bool FixCortexA53Errata843419; bool GcSections; 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->ExecuteOnly) { + if (Config->EMachine != EM_AARCH64) + error("-execute-only is only supported on AArch64 targets"); + + if (Config->SingleRoRx) + error("-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->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); Index: ELF/Options.td =================================================================== --- ELF/Options.td +++ ELF/Options.td @@ -131,6 +131,10 @@ 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.">; + defm export_dynamic: B<"export-dynamic", "Put symbols in the dynamic symbol table", "Do not put symbols in the dynamic symbol table (default)">; Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -488,6 +488,7 @@ // their own segment. We do the same if SECTIONS command is present in linker // script. See comment for computeFlags(). Config->SingleRoRx = true; + Config->ExecuteOnly = false; expect("{"); std::vector V; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1768,6 +1768,8 @@ return PF_R | PF_W | PF_X; if (Config->SingleRoRx && !(Flags & PF_W)) return Flags | PF_X; + if (Config->ExecuteOnly && (Flags & PF_X)) + return Flags & ~PF_R; return Flags; } Index: test/ELF/execute-only.s =================================================================== --- /dev/null +++ test/ELF/execute-only.s @@ -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 0x00000000cafe0000 0x000004 0x000004 E 0x{{.*}} +// CHECK-NOT: LOAD {{.*}} 0x00000000cafe0000 0x00000000cafe0000 0x000004 0x000004 R E 0x{{.*}} + + br lr