diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 29135ddb16d79ecc5fdafb0355797abb3f9a5b24..8b60cf2a31cc9cea3bf725cef9a52c8f55281573 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2229,6 +2229,29 @@ void SymbolTableBaseSection::finalizeContents() { } } +// This is a demonstration function. It should return the sequence number of +// input in the 'adlt' section (or -1). +// TODO: Call the corresponding function from the 'adlt' section implementation +// instead of this function. +static ssize_t getSharedOrder(InputFile *file) { + static ssize_t ish = 10000; + return ish -= 1; +} + +// This is a demonstration function. It should tell the 'adlt' section the index +// of the first local symbol for the input. +// TODO: Call the corresponding function from the 'adlt' section implementation +// instead of this function. +static void setSharedLocalSymbolIndex(InputFile *file, size_t index) { +} + +// This is a demonstration function. It should tell the 'adlt' section the index +// of the first global symbol for the input. +// TODO: Call the corresponding function from the 'adlt' section implementation +// instead of this function. +static void setSharedGlobalSymbolIndex(InputFile *file, size_t index) { +} + // The ELF spec requires that all local symbols precede global symbols, so we // sort symbol entries in this function. (For .dynsym, we don't do that because // symbols for dynamic linking are inherently all globals.) @@ -2239,8 +2262,8 @@ void SymbolTableBaseSection::finalizeContents() { void SymbolTableBaseSection::sortSymTabSymbols() { // Move all local symbols before global symbols. auto e = std::stable_partition( - symbols.begin(), symbols.end(), - [](const SymbolTableEntry &s) { return s.sym->isLocal(); }); + symbols.begin(), symbols.end(), + [](const SymbolTableEntry &s) { return s.sym->isLocal(); }); size_t numLocals = e - symbols.begin(); getParent()->info = numLocals + 1; @@ -2249,14 +2272,94 @@ void SymbolTableBaseSection::sortSymTabSymbols() { // symbols, they are already naturally placed first in each group. That // happens because STT_FILE is always the first symbol in the object and hence // precede all other local symbols we add for a file. - MapVector> arr; - for (const SymbolTableEntry &s : llvm::make_range(symbols.begin(), e)) - arr[s.sym->file].push_back(s); - - auto i = symbols.begin(); - for (auto &p : arr) - for (SymbolTableEntry &entry : p.second) - *i++ = entry; + { + MapVector> arr; + for (const SymbolTableEntry &s : llvm::make_range(symbols.begin(), e)) + arr[s.sym->file].push_back(s); + + auto i = symbols.begin(); + + if (config->adlt) { + // For the '-adlt' option, we distribute local symbols across files in + // the order that corresponds to the 'adlt' section. To do this, call + // getSharedOrder() function, which should return the sequence number of + // inputs in the 'adlt' section. Now there is no implementation of the + // 'adlt' section object, so the getSharedOrder() function is a + // demonstration that should be replaced by a correct call from the 'adlt' + // section implementation. + // Here, for the 'adlt' section, the corresponding index of the first + // local symbol and index of the first global symbol are calculated for + // input. These indices are passed to the 'adlt' section using the + // setSharedLocalSymbolIndex() and setSharedGlobalSymbolIndex() function + // calls. setSharedLocalSymbolIndex() and setSharedGlobalSymbolIndex() are + // also demonstrations, so they need to be replaced with the correct calls + // from the 'adlt' section implementation. + + using vT = std::pair; + std::vector order; + for (auto &p : arr) { + ssize_t q = getSharedOrder(p.first); + if (q < 0) { + for (SymbolTableEntry &entry : p.second) + *i++ = entry; + } + else + order.emplace_back(static_cast(q), p.first); + } + std::sort(order.begin(), order.end(), + [](const vT &l, const vT &r) {return l.first < r.first;}); + + for(size_t q = 0; q < order.size(); q++) { + setSharedLocalSymbolIndex(order[q].second, i - symbols.begin()); + auto &p = arr[order[q].second]; + for (SymbolTableEntry &entry : p) + *i++ = entry; + } + } + else { + for (auto &p : arr) + for (SymbolTableEntry &entry : p.second) + *i++ = entry; + } + } + + if (config->adlt) { + // For the '-adlt' option, global defined symbols as well as local symbols + // are distributed in groups by files, in the order that corresponds to the + // 'adlt' section. We will distribute global symbols after all local symbols + // and all external (UND) symbols. + + auto i = std::stable_partition( + symbols.begin() + numLocals, symbols.end(), + [&](const SymbolTableEntry &s) { + return !s.sym->isDefined() || (s.sym->partition != partition); + }); + + MapVector> arr; + for (const SymbolTableEntry &s : llvm::make_range(i, symbols.end())) + arr[s.sym->file].push_back(s); + + using vT = std::pair; + std::vector order; + for (auto &p : arr) { + ssize_t q = getSharedOrder(p.first); + if (q < 0) { + for (SymbolTableEntry &entry : p.second) + *i++ = entry; + } + else + order.emplace_back(static_cast(q), p.first); + } + std::sort(order.begin(), order.end(), + [](const vT &l, const vT &r) {return l.first < r.first;}); + + for(size_t q = 0; q < order.size(); q++) { + setSharedGlobalSymbolIndex(order[q].second, i - symbols.begin()); + auto &p = arr[order[q].second]; + for (SymbolTableEntry &entry : p) + *i++ = entry; + } + } } void SymbolTableBaseSection::addSymbol(Symbol *b) {