diff options
Diffstat (limited to 'clang/lib/Driver')
-rw-r--r-- | clang/lib/Driver/ToolChains/Darwin.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index e15f089b0d7..d8c18effd62 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -19,6 +19,7 @@ #include "clang/Driver/SanitizerArgs.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Option/ArgList.h" +#include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/TargetParser.h" @@ -1110,6 +1111,19 @@ static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) { CmdArgs.push_back(Symbol); } +/// Add a sectalign directive for \p Segment and \p Section to the maximum +/// expected page size for Darwin. +/// +/// On iPhone 6+ the max supported page size is 16K. On macOS, the max is 4K. +/// Use a common alignment constant (16K) for now, and reduce the alignment on +/// macOS if it proves important. +static void addSectalignToPage(const ArgList &Args, ArgStringList &CmdArgs, + StringRef Segment, StringRef Section) { + for (const char *A : {"-sectalign", Args.MakeArgString(Segment), + Args.MakeArgString(Section), "0x4000"}) + CmdArgs.push_back(A); +} + void Darwin::addProfileRTLibs(const ArgList &Args, ArgStringList &CmdArgs) const { if (!needsProfileRT(Args)) return; @@ -1117,11 +1131,13 @@ void Darwin::addProfileRTLibs(const ArgList &Args, AddLinkRuntimeLib(Args, CmdArgs, "profile", RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink)); + bool ForGCOV = needsGCovInstrumentation(Args); + // If we have a symbol export directive and we're linking in the profile // runtime, automatically export symbols necessary to implement some of the // runtime's functionality. if (hasExportSymbolDirective(Args)) { - if (needsGCovInstrumentation(Args)) { + if (ForGCOV) { addExportedSymbol(CmdArgs, "___gcov_flush"); addExportedSymbol(CmdArgs, "_flush_fn_list"); addExportedSymbol(CmdArgs, "_writeout_fn_list"); @@ -1131,6 +1147,24 @@ void Darwin::addProfileRTLibs(const ArgList &Args, } addExportedSymbol(CmdArgs, "_lprofDirMode"); } + + // Align __llvm_prf_{cnts,data} sections to the maximum expected page + // alignment. This allows profile counters to be mmap()'d to disk. Note that + // it's not enough to just page-align __llvm_prf_cnts: the following section + // must also be page-aligned so that its data is not clobbered by mmap(). + // + // The section alignment is only needed when continuous profile sync is + // enabled, but this is expected to be the default in Xcode. Specifying the + // extra alignment also allows the same binary to be used with/without sync + // enabled. + if (!ForGCOV) { + for (auto IPSK : {llvm::IPSK_cnts, llvm::IPSK_data}) { + addSectalignToPage( + Args, CmdArgs, "__DATA", + llvm::getInstrProfSectionName(IPSK, llvm::Triple::MachO, + /*AddSegmentInfo=*/false)); + } + } } void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args, |