diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1452,8 +1452,11 @@ replaceCommonSymbols(); StringRef orderFile = args.getLastArgValue(OPT_order_file); - if (!orderFile.empty()) - priorityBuilder.parseOrderFile(orderFile); + if (!orderFile.empty()) { + PriorityBuilder::SymbolOrder symbolOrder = + priorityBuilder.parseOrderFile(orderFile); + priorityBuilder.processOrderFile(symbolOrder); + } referenceStubBinder(); diff --git a/lld/MachO/SectionPriorities.h b/lld/MachO/SectionPriorities.h --- a/lld/MachO/SectionPriorities.h +++ b/lld/MachO/SectionPriorities.h @@ -24,6 +24,7 @@ // of the vertices are specified in the order file are discarded. void extractCallGraphProfile(); + using SymbolOrder = std::vector>; // Reads the order file at `path` into config->priorities. // // An order file has one entry per line, in the following format: @@ -40,7 +41,9 @@ // lowest-ordered entry (the one nearest to the front of the list.) // // The file can also have line comments that start with '#'. - void parseOrderFile(StringRef path); + SymbolOrder parseOrderFile(StringRef path) const; + + void processOrderFile(const SymbolOrder &symbolOrder); // Returns layout priorities for some or all input sections. Sections are laid // out in decreasing order; that is, a higher priority section will be closer diff --git a/lld/MachO/SectionPriorities.cpp b/lld/MachO/SectionPriorities.cpp --- a/lld/MachO/SectionPriorities.cpp +++ b/lld/MachO/SectionPriorities.cpp @@ -292,16 +292,18 @@ } } -void macho::PriorityBuilder::parseOrderFile(StringRef path) { +std::vector> +macho::PriorityBuilder::parseOrderFile(StringRef path) const { assert(callGraphProfile.empty() && "Order file must be parsed before call graph profile is processed"); Optional buffer = readFile(path); if (!buffer) { error("Could not read order file at " + path); - return; + return {}; } MemoryBufferRef mbref = *buffer; + SymbolOrder symbolOrder; for (StringRef line : args::getLines(mbref)) { StringRef objectFile, symbol; line = line.take_until([](char c) { return c == '#'; }); // ignore comments @@ -336,14 +338,25 @@ symbol = line.trim(); if (!symbol.empty()) { - SymbolPriorityEntry &entry = priorities[symbol]; - if (!objectFile.empty()) - entry.objectFiles.insert( - std::make_pair(objectFile, highestAvailablePriority)); - else - entry.anyObjectFile = - std::max(entry.anyObjectFile, highestAvailablePriority); + symbolOrder.emplace_back( + std::make_pair(StringRef(symbol), StringRef(objectFile))); } + } + + return symbolOrder; +} + +void macho::PriorityBuilder::processOrderFile(const SymbolOrder &symbolOrder) { + for (const auto &symbolObjectFile : symbolOrder) { + StringRef symbol = symbolObjectFile.first; + StringRef objectFile = symbolObjectFile.second; + SymbolPriorityEntry &entry = priorities[symbol]; + if (!objectFile.empty()) + entry.objectFiles.insert( + std::make_pair(objectFile, highestAvailablePriority)); + else + entry.anyObjectFile = + std::max(entry.anyObjectFile, highestAvailablePriority); --highestAvailablePriority; }