@@ -64,6 +64,7 @@ template <class ELFT> class Writer {
6464 void sortOrphanSections ();
6565 void finalizeSections ();
6666 void checkExecuteOnly ();
67+ void checkExecuteOnlyReport ();
6768 void setReservedSymbolSections ();
6869
6970 SmallVector<std::unique_ptr<PhdrEntry>, 0 > createPhdrs (Partition &part);
@@ -323,6 +324,7 @@ template <class ELFT> void Writer<ELFT>::run() {
323324 // finalizeSections does that.
324325 finalizeSections ();
325326 checkExecuteOnly ();
327+ checkExecuteOnlyReport ();
326328
327329 // If --compressed-debug-sections is specified, compress .debug_* sections.
328330 // Do it right now because it changes the size of output sections.
@@ -2176,6 +2178,41 @@ template <class ELFT> void Writer<ELFT>::checkExecuteOnly() {
21762178 " data and code" ;
21772179}
21782180
2181+ // Check which input sections of RX output sections don't have the
2182+ // SHF_AARCH64_PURECODE or SHF_ARM_PURECODE flag set.
2183+ template <class ELFT > void Writer<ELFT>::checkExecuteOnlyReport() {
2184+ if (ctx.arg .zExecuteOnlyReport == " none" )
2185+ return ;
2186+
2187+ auto reportUnless = [&](bool cond) -> ELFSyncStream {
2188+ if (cond)
2189+ return {ctx, DiagLevel::None};
2190+ if (ctx.arg .zExecuteOnlyReport == " error" )
2191+ return {ctx, DiagLevel::Err};
2192+ if (ctx.arg .zExecuteOnlyReport == " warning" )
2193+ return {ctx, DiagLevel::Warn};
2194+ return {ctx, DiagLevel::None};
2195+ };
2196+
2197+ uint64_t purecodeFlag =
2198+ ctx.arg .emachine == EM_AARCH64 ? SHF_AARCH64_PURECODE : SHF_ARM_PURECODE;
2199+ StringRef purecodeFlagName = ctx.arg .emachine == EM_AARCH64
2200+ ? " SHF_AARCH64_PURECODE"
2201+ : " SHF_ARM_PURECODE" ;
2202+ SmallVector<InputSection *, 0 > storage;
2203+ for (OutputSection *osec : ctx.outputSections ) {
2204+ if (osec->getPhdrFlags () != (PF_R | PF_X))
2205+ continue ;
2206+ for (InputSection *sec : getInputSections (*osec, storage)) {
2207+ if (isa<SyntheticSection>(sec))
2208+ continue ;
2209+ reportUnless (sec->flags & purecodeFlag)
2210+ << " -z execute-only-report: " << sec << " does not have "
2211+ << purecodeFlagName << " flag set" ;
2212+ }
2213+ }
2214+ }
2215+
21792216// The linker is expected to define SECNAME_start and SECNAME_end
21802217// symbols for a few sections. This function defines them.
21812218template <class ELFT > void Writer<ELFT>::addStartEndSymbols() {
0 commit comments