diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -86,6 +86,9 @@ uint32_t toIndex; // Number of calls from callee to caller in the profile. uint64_t count; + + CallGraphEntry(uint32_t fromIndex, uint32_t toIndex, uint64_t count) + : fromIndex(fromIndex), toIndex(toIndex), count(count) {} }; class InputFile { diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -262,6 +262,24 @@ return {}; } +static Error parseCallGraph(ArrayRef data, + std::vector &callGraph) { + TimeTraceScope timeScope("Parsing call graph section"); + BinaryStreamReader reader(data, support::little); + while (!reader.empty()) { + uint32_t fromIndex, toIndex; + uint64_t count; + if (Error err = reader.readInteger(fromIndex)) + return err; + if (Error err = reader.readInteger(toIndex)) + return err; + if (Error err = reader.readInteger(count)) + return err; + callGraph.emplace_back(fromIndex, toIndex, count); + } + return Error::success(); +} + // Parse the sequence of sections within a single LC_SEGMENT(_64). // Split each section into subsections. template @@ -320,25 +338,8 @@ if (name == section_names::compactUnwind) compactUnwindSection = sections.back(); } else if (segname == segment_names::llvm) { - if (name == "__cg_profile" && config->callGraphProfileSort) { - TimeTraceScope timeScope("Parsing call graph section"); - BinaryStreamReader reader(data, support::little); - while (!reader.empty()) { - uint32_t fromIndex, toIndex; - uint64_t count; - if (Error err = reader.readInteger(fromIndex)) - fatal(toString(this) + ": Expected 32-bit integer"); - if (Error err = reader.readInteger(toIndex)) - fatal(toString(this) + ": Expected 32-bit integer"); - if (Error err = reader.readInteger(count)) - fatal(toString(this) + ": Expected 64-bit integer"); - callGraph.emplace_back(); - CallGraphEntry &entry = callGraph.back(); - entry.fromIndex = fromIndex; - entry.toIndex = toIndex; - entry.count = count; - } - } + if (config->callGraphProfileSort && name == section_names::cgProfile) + checkError(parseCallGraph(data, callGraph)); // ld64 does not appear to emit contents from sections within the __LLVM // segment. Symbols within those sections point to bitcode metadata // instead of actual symbols. Global symbols within those sections could diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h --- a/lld/MachO/InputSection.h +++ b/lld/MachO/InputSection.h @@ -283,6 +283,7 @@ constexpr const char bitcodeBundle[] = "__bundle"; constexpr const char cString[] = "__cstring"; constexpr const char cfString[] = "__cfstring"; +constexpr const char cgProfile[] = "__cg_profile"; constexpr const char codeSignature[] = "__code_signature"; constexpr const char common[] = "__common"; constexpr const char compactUnwind[] = "__compact_unwind";