Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -112,6 +112,11 @@ // True if this is an argument for --just-symbols. Usually false. bool JustSymbols = false; + // This is a unique monotonically-increasing number assigned to each + // file. This doesn't have a big role but is convenient to sort + // symbols quickly in a reproducible manner. + uint32_t FileId; + // GroupId is used for --warn-backrefs which is an optional error // checking feature. All files within the same --{start,end}-group // get the same group ID. Otherwise, each file gets a new group @@ -127,6 +132,7 @@ private: const Kind FileKind; + static uint32_t NextFileId; static uint32_t NextGroupId; }; Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -39,6 +39,7 @@ using namespace lld::elf; bool InputFile::IsInGroup; +uint32_t InputFile::NextFileId; uint32_t InputFile::NextGroupId; std::vector elf::BinaryFiles; std::vector elf::BitcodeFiles; @@ -48,7 +49,7 @@ TarWriter *elf::Tar; InputFile::InputFile(Kind K, MemoryBufferRef M) - : MB(M), GroupId(NextGroupId), FileKind(K) { + : MB(M), FileId(NextFileId++), GroupId(NextGroupId), FileKind(K) { // All files within the same --{start,end}-group get the same group ID. // Otherwise, a new file will get a new group ID. if (!IsInGroup) Index: lld/ELF/SyntheticSections.cpp =================================================================== --- lld/ELF/SyntheticSections.cpp +++ lld/ELF/SyntheticSections.cpp @@ -1561,18 +1561,15 @@ size_t NumLocals = E - Symbols.begin(); getParent()->Info = NumLocals + 1; - // Assign the growing unique ID for each local symbol's file. - DenseMap FileIDs; - for (auto I = Symbols.begin(); I != E; ++I) - FileIDs.insert({I->Sym->File, FileIDs.size()}); - // Sort the local symbols to group them by file. We do not need to care about // the STT_FILE 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. std::stable_sort(Symbols.begin(), E, [&](const SymbolTableEntry &L, const SymbolTableEntry &R) { - return FileIDs[L.Sym->File] < FileIDs[R.Sym->File]; + if (!L.Sym->File || !R.Sym->File) + return false; + return L.Sym->File->FileId < R.Sym->File->FileId; }); } Index: lld/test/ELF/local-symbols-order.s =================================================================== --- lld/test/ELF/local-symbols-order.s +++ lld/test/ELF/local-symbols-order.s @@ -7,26 +7,25 @@ # RUN: ld.lld -o %t %t1.o %t2.o --emit-relocs # RUN: llvm-readobj -symbols -sections -elf-output-style=GNU %t | FileCheck %s -## Check we sort local symbols to match the following order: +## Check we sort local symbols to match the following order: ## file1, local1, section1, hidden1, file2, local2, section2, hidden2 ... # CHECK: Section Headers: -# CHECK: [Nr] Name -# CHECK: [ [[ST:.*]]] .text -# CHECK: [ [[SD:.*]]] .data -# CHECK: [ [[SC:.*]]] .comment +# CHECK: [ 1] .text +# CHECK: [ 2] .data +# CHECK: [ 3] .comment # CHECK: Num: Value Size Type Bind Vis Ndx Name # CHECK-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND # CHECK-NEXT: 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS file1 # CHECK-NEXT: 2: 0000000000201000 0 NOTYPE LOCAL DEFAULT 1 foo1 -# CHECK-NEXT: 3: 0000000000201000 0 SECTION LOCAL DEFAULT [[ST]] +# CHECK-NEXT: 3: 0000000000201000 0 SECTION LOCAL DEFAULT 1 # CHECK-NEXT: 4: 0000000000201000 0 NOTYPE LOCAL HIDDEN 1 bar1 # CHECK-NEXT: 5: 0000000000000000 0 FILE LOCAL DEFAULT ABS file2 # CHECK-NEXT: 6: 0000000000201000 0 NOTYPE LOCAL DEFAULT 2 foo2 -# CHECK-NEXT: 7: 0000000000201000 0 SECTION LOCAL DEFAULT [[SD]] -# CHECK-NEXT: 8: 0000000000201000 0 NOTYPE LOCAL HIDDEN 2 bar2 -# CHECK-NEXT: 9: 0000000000000000 0 SECTION LOCAL DEFAULT [[SC]] +# CHECK-NEXT: 7: 0000000000201000 0 SECTION LOCAL DEFAULT 2 +# CHECK-NEXT: 8: 0000000000000000 0 SECTION LOCAL DEFAULT 3 +# CHECK-NEXT: 9: 0000000000201000 0 NOTYPE LOCAL HIDDEN 2 bar2 foo1: