diff --git a/llvm/lib/MC/XCOFFObjectWriter.cpp b/llvm/lib/MC/XCOFFObjectWriter.cpp --- a/llvm/lib/MC/XCOFFObjectWriter.cpp +++ b/llvm/lib/MC/XCOFFObjectWriter.cpp @@ -84,6 +84,7 @@ uint32_t SymbolTableIndex; uint64_t Address; uint64_t Size; + uint32_t Order; SmallVector Syms; SmallVector Relocations; @@ -92,7 +93,7 @@ return MCSec->getVisibilityType(); } XCOFFSection(const MCSectionXCOFF *MCSec) - : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0) {} + : MCSec(MCSec), SymbolTableIndex(-1), Address(-1), Size(0), Order(0) {} }; // Type to be used for a container representing a set of csects with @@ -200,7 +201,7 @@ uint64_t SymbolTableOffset = 0; uint16_t SectionCount = 0; uint64_t RelocationEntryOffset = 0; - StringRef SourceFileName = ".file"; + std::vector> FileNames; support::endian::Writer W; std::unique_ptr TargetObjectWriter; @@ -301,6 +302,7 @@ // *) Builds up the section header table by adding any non-empty sections to // `Sections`. void assignAddressesAndIndices(const MCAsmLayout &); + void assignIndicesForSymTbl(); void finalizeSectionInfo(); // TODO aux header support not implemented. @@ -455,18 +457,19 @@ llvm_unreachable("unsupport section type!"); } - for (const MCSymbol &S : Asm.symbols()) { + for (auto It : llvm::enumerate(Asm.symbols())) { // Nothing to do for temporary symbols. - if (S.isTemporary()) + if (It.value().isTemporary()) continue; - const MCSymbolXCOFF *XSym = cast(&S); + const MCSymbolXCOFF *XSym = cast(&It.value()); const MCSectionXCOFF *ContainingCsect = getContainingCsect(XSym); if (ContainingCsect->getCSectType() == XCOFF::XTY_ER) { // Handle undefined symbol. UndefinedCsects.emplace_back(ContainingCsect); SectionMap[ContainingCsect] = &UndefinedCsects.back(); + SectionMap[ContainingCsect]->Order = It.index(); if (nameShouldBeInStringTable(ContainingCsect->getSymbolTableName())) Strings.add(ContainingCsect->getSymbolTableName()); continue; @@ -484,6 +487,7 @@ assert(SectionMap.find(ContainingCsect) != SectionMap.end() && "Expected containing csect to exist in map"); XCOFFSection *Csect = SectionMap[ContainingCsect]; + Csect->Order = It.index(); // Lookup the containing csect and add the symbol to it. assert(Csect->MCSec->isCsect() && "only csect is supported now!"); Csect->Syms.emplace_back(XSym); @@ -494,9 +498,13 @@ Strings.add(XSym->getSymbolTableName()); } - // The first symbol entry is for the source file's name. - if (nameShouldBeInStringTable(SourceFileName)) - Strings.add(SourceFileName); + FileNames = Asm.getFileNames(); + if (FileNames.empty()) + FileNames.emplace_back(".file", 0); + for (const std::pair &F : FileNames) { + if (nameShouldBeInStringTable(F.first)) + Strings.add(F.first); + } Strings.finalize(); assignAddressesAndIndices(Layout); @@ -853,46 +861,60 @@ } void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) { - // Write symbol 0 as C_FILE. - // The n_name of a C_FILE symbol is the source file's name when no auxiliary - // entries are present. The source file's name is alternatively provided by an - // auxiliary entry, in which case the n_name of the C_FILE symbol is `.file`. - // FIXME: add the real source file's name. - writeSymbolEntry(SourceFileName, /*Value=*/0, - XCOFF::ReservedSectionNum::N_DEBUG, - /*SymbolType=*/0, XCOFF::C_FILE, - /*NumberOfAuxEntries=*/0); - - for (const auto &Csect : UndefinedCsects) { - writeSymbolEntryForControlSection(Csect, XCOFF::ReservedSectionNum::N_UNDEF, - Csect.MCSec->getStorageClass()); - } - - for (const auto *Section : Sections) { - if (Section->Index == SectionEntry::UninitializedIndex) - // Nothing to write for this Section. - continue; - - for (const auto *Group : Section->Groups) { - if (Group->empty()) + for (auto FileNameIt = FileNames.begin(); FileNameIt != FileNames.end(); + ++FileNameIt) { + // Write the file symbol. + writeSymbolEntry(FileNameIt->first, /*Value=*/0, + XCOFF::ReservedSectionNum::N_DEBUG, + /*SymbolType=*/0, XCOFF::C_FILE, + /*NumberOfAuxEntries=*/0); + + uint32_t CurrFileSymbolIdx = FileNameIt->second; + uint32_t NextFileSymbolIdx = (FileNameIt + 1) != FileNames.end() + ? (FileNameIt + 1)->second + : INT32_MAX; + + for (const auto &Csect : UndefinedCsects) { + if (Csect.Order < CurrFileSymbolIdx || Csect.Order >= NextFileSymbolIdx) continue; + writeSymbolEntryForControlSection(Csect, + XCOFF::ReservedSectionNum::N_UNDEF, + Csect.MCSec->getStorageClass()); + } - const int16_t SectionIndex = Section->Index; - for (const auto &Csect : *Group) { - // Write out the control section first and then each symbol in it. - writeSymbolEntryForControlSection(Csect, SectionIndex, - Csect.MCSec->getStorageClass()); + for (const auto *Section : Sections) { + if (Section->Index == SectionEntry::UninitializedIndex) + // Nothing to write for this Section. + continue; - for (const auto &Sym : Csect.Syms) - writeSymbolEntryForCsectMemberLabel( - Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym))); + for (const auto *Group : Section->Groups) { + if (Group->empty()) + continue; + + const int16_t SectionIndex = Section->Index; + for (const auto &Csect : *Group) { + if (Csect.Order < CurrFileSymbolIdx || + Csect.Order >= NextFileSymbolIdx) + continue; + // Write out the control section first and then each symbol in it. + writeSymbolEntryForControlSection(Csect, SectionIndex, + Csect.MCSec->getStorageClass()); + + for (const auto &Sym : Csect.Syms) + writeSymbolEntryForCsectMemberLabel( + Sym, Csect, SectionIndex, Layout.getSymbolOffset(*(Sym.MCSym))); + } } } - } - for (const auto &DwarfSection : DwarfSections) - writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect, - DwarfSection.Index); + for (const auto &DwarfSection : DwarfSections) { + if (DwarfSection.DwarfSect->Order < CurrFileSymbolIdx || + DwarfSection.DwarfSect->Order >= NextFileSymbolIdx) + continue; + writeSymbolEntryForDwarfSection(*DwarfSection.DwarfSect, + DwarfSection.Index); + } + } } void XCOFFObjectWriter::finalizeSectionInfo() { @@ -956,20 +978,78 @@ SymbolTableOffset = RawPointer; } -void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { - // The first symbol table entry (at index 0) is for the file name. - uint32_t SymbolTableIndex = 1; - - // Calculate indices for undefined symbols. - for (auto &Csect : UndefinedCsects) { - Csect.Size = 0; - Csect.Address = 0; - Csect.SymbolTableIndex = SymbolTableIndex; - SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; - // 1 main and 1 auxiliary symbol table entry for each contained symbol. - SymbolTableIndex += 2; +void XCOFFObjectWriter::assignIndicesForSymTbl() { + uint32_t SymbolTableIndex = 0; + + for (auto FileNameIt = FileNames.begin(); FileNameIt != FileNames.end(); + ++FileNameIt) { + // The first symbol table entry is for the file name. + SymbolTableIndex++; + + uint32_t CurrFileSymbolIdx = FileNameIt->second; + uint32_t NextFileSymbolIdx = (FileNameIt + 1) != FileNames.end() + ? (FileNameIt + 1)->second + : INT32_MAX; + + // Calculate indices for undefined symbols. + for (auto &Csect : UndefinedCsects) { + if (Csect.Order < CurrFileSymbolIdx || Csect.Order >= NextFileSymbolIdx) + continue; + Csect.Size = 0; + Csect.Address = 0; + Csect.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for each contained symbol. + SymbolTableIndex += 2; + } + + for (auto *Section : Sections) { + if (Section->Index == SectionEntry::UninitializedIndex) + continue; + + for (auto *Group : Section->Groups) { + if (Group->empty()) + continue; + + for (auto &Csect : *Group) { + if (Csect.Order < CurrFileSymbolIdx || + Csect.Order >= NextFileSymbolIdx) + continue; + Csect.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[Csect.MCSec->getQualNameSymbol()] = + Csect.SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for the csect. + SymbolTableIndex += 2; + + for (auto &Sym : Csect.Syms) { + Sym.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for each contained + // symbol. + SymbolTableIndex += 2; + } + } + } + } + + for (auto &DwarfSection : DwarfSections) { + XCOFFSection &DwarfSect = *DwarfSection.DwarfSect; + if (DwarfSect.Order < CurrFileSymbolIdx || + DwarfSect.Order >= NextFileSymbolIdx) + continue; + + // Symbol index. + DwarfSect.SymbolTableIndex = SymbolTableIndex; + SymbolIndexMap[DwarfSect.MCSec->getQualNameSymbol()] = + DwarfSect.SymbolTableIndex; + // 1 main and 1 auxiliary symbol table entry for the Dwarf section. + SymbolTableIndex += 2; + } } + SymbolTableEntryCount = SymbolTableIndex; +} +void XCOFFObjectWriter::assignAddressesAndIndices(const MCAsmLayout &Layout) { // The address corrresponds to the address of sections and symbols in the // object file. We place the shared address 0 immediately after the // section header table. @@ -1010,18 +1090,6 @@ Csect.Address = alignTo(Address, MCSec->getAlignment()); Csect.Size = Layout.getSectionAddressSize(MCSec); Address = Csect.Address + Csect.Size; - Csect.SymbolTableIndex = SymbolTableIndex; - SymbolIndexMap[MCSec->getQualNameSymbol()] = Csect.SymbolTableIndex; - // 1 main and 1 auxiliary symbol table entry for the csect. - SymbolTableIndex += 2; - - for (auto &Sym : Csect.Syms) { - Sym.SymbolTableIndex = SymbolTableIndex; - SymbolIndexMap[Sym.MCSym] = Sym.SymbolTableIndex; - // 1 main and 1 auxiliary symbol table entry for each contained - // symbol. - SymbolTableIndex += 2; - } } if (!SectionAddressSet) { @@ -1046,12 +1114,6 @@ DwarfSection.Index = SectionIndex++; SectionCount++; - // Symbol index. - DwarfSect.SymbolTableIndex = SymbolTableIndex; - SymbolIndexMap[MCSec->getQualNameSymbol()] = DwarfSect.SymbolTableIndex; - // 1 main and 1 auxiliary symbol table entry for the csect. - SymbolTableIndex += 2; - // Section address. Make it align to section alignment. // We use address 0 for DWARF sections' Physical and Virtual Addresses. // This address is used to tell where is the section in the final object. @@ -1067,7 +1129,7 @@ Address = alignTo(DwarfSect.Address + DwarfSect.Size, DefaultSectionAlign); } - SymbolTableEntryCount = SymbolTableIndex; + assignIndicesForSymTbl(); // Calculate the RawPointer value for each section. uint64_t RawPointer = diff --git a/llvm/test/CodeGen/PowerPC/aix-extern-weak.ll b/llvm/test/CodeGen/PowerPC/aix-extern-weak.ll --- a/llvm/test/CodeGen/PowerPC/aix-extern-weak.ll +++ b/llvm/test/CodeGen/PowerPC/aix-extern-weak.ll @@ -66,7 +66,7 @@ ; CHECKSYM: Symbols [ ; CHECKSYM-NEXT: Symbol { ; CHECKSYM-NEXT: Index: 0 -; CHECKSYM-NEXT: Name: .file +; CHECKSYM-NEXT: Name: ; CHECKSYM-NEXT: Value (SymbolTableIndex): 0x0 ; CHECKSYM-NEXT: Section: N_DEBUG ; CHECKSYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-extern.ll b/llvm/test/CodeGen/PowerPC/aix-extern.ll --- a/llvm/test/CodeGen/PowerPC/aix-extern.ll +++ b/llvm/test/CodeGen/PowerPC/aix-extern.ll @@ -89,7 +89,7 @@ ; CHECKSYM: Symbols [ ; CHECKSYM-NEXT: Symbol { ; CHECKSYM-NEXT: Index: 0 -; CHECKSYM-NEXT: Name: .file +; CHECKSYM-NEXT: Name: ; CHECKSYM-NEXT: Value (SymbolTableIndex): 0x0 ; CHECKSYM-NEXT: Section: N_DEBUG ; CHECKSYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-func-dsc-gen.ll b/llvm/test/CodeGen/PowerPC/aix-func-dsc-gen.ll --- a/llvm/test/CodeGen/PowerPC/aix-func-dsc-gen.ll +++ b/llvm/test/CodeGen/PowerPC/aix-func-dsc-gen.ll @@ -13,7 +13,7 @@ ; CHECK-NEXT: AddressSize: 32bit ; CHECK: Symbol { ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: Name: .file +; CHECK-NEXT: Name: ; CHECK-NEXT: Value (SymbolTableIndex): 0x0 ; CHECK-NEXT: Section: N_DEBUG ; CHECK-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll b/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll --- a/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll +++ b/llvm/test/CodeGen/PowerPC/aix-llvm-intrinsic.ll @@ -39,7 +39,7 @@ ; CHECKSYM: Symbol { ; CHECKSYM-NEXT: Index: 0 -; CHECKSYM-NEXT: Name: .file +; CHECKSYM-NEXT: Name: ; CHECKSYM-NEXT: Value (SymbolTableIndex): 0x0 ; CHECKSYM-NEXT: Section: N_DEBUG ; CHECKSYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc-large.ll b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc-large.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc-large.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc-large.ll @@ -210,7 +210,7 @@ ; SYM-NEXT: Symbols [ ; SYM-NEXT: Symbol { ; SYM-NEXT: Index: 0 -; SYM-NEXT: Name: .file +; SYM-NEXT: Name: ; SYM-NEXT: Value (SymbolTableIndex): 0x0 ; SYM-NEXT: Section: N_DEBUG ; SYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-reloc.ll @@ -171,7 +171,7 @@ ; SYM-NEXT: Symbols [ ; SYM-NEXT: Symbol { ; SYM-NEXT: Index: 0 -; SYM-NEXT: Name: .file +; SYM-NEXT: Name: ; SYM-NEXT: Value (SymbolTableIndex): 0x0 ; SYM-NEXT: Section: N_DEBUG ; SYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-variables.ll b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-variables.ll --- a/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-variables.ll +++ b/llvm/test/CodeGen/PowerPC/aix-tls-xcoff-variables.ll @@ -66,7 +66,7 @@ ; SYMS-NEXT: Symbols [ ; SYMS-NEXT: Symbol { ; SYMS-NEXT: Index: 0 -; SYMS-NEXT: Name: .file +; SYMS-NEXT: Name: ; SYMS-NEXT: Value (SymbolTableIndex): 0x0 ; SYMS-NEXT: Section: N_DEBUG ; SYMS-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-weak.ll b/llvm/test/CodeGen/PowerPC/aix-weak.ll --- a/llvm/test/CodeGen/PowerPC/aix-weak.ll +++ b/llvm/test/CodeGen/PowerPC/aix-weak.ll @@ -101,7 +101,7 @@ ; CHECKSYM: Symbols [ ; CHECKSYM-NEXT: Symbol { ; CHECKSYM-NEXT: Index: 0 -; CHECKSYM-NEXT: Name: .file +; CHECKSYM-NEXT: Name: ; CHECKSYM-NEXT: Value (SymbolTableIndex): 0x0 ; CHECKSYM-NEXT: Section: N_DEBUG ; CHECKSYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-data.ll @@ -208,7 +208,7 @@ ; SYMS: Symbols [ ; SYMS-NEXT: Symbol { ; SYMS-NEXT: Index: 0 -; SYMS-NEXT: Name: .file +; SYMS-NEXT: Name: ; SYMS-NEXT: Value (SymbolTableIndex): 0x0 ; SYMS-NEXT: Section: N_DEBUG ; SYMS-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll --- a/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll +++ b/llvm/test/CodeGen/PowerPC/aix-xcoff-reloc.ll @@ -159,7 +159,7 @@ ; SYM: Symbols [ ; SYM-NEXT: Symbol { ; SYM-NEXT: Index: 0 -; SYM-NEXT: Name: .file +; SYM-NEXT: Name: ; SYM-NEXT: Value (SymbolTableIndex): 0x0 ; SYM-NEXT: Section: N_DEBUG ; SYM-NEXT: Source Language ID: TB_C (0x0) diff --git a/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test b/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test --- a/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test +++ b/llvm/test/tools/llvm-objdump/XCOFF/symbol-table.test @@ -66,7 +66,7 @@ } ; SYM: SYMBOL TABLE: -; SYM-NEXT: 00000000 df *DEBUG* 00000000 .file +; SYM-NEXT: 00000000 df *DEBUG* 00000000 ; SYM-NEXT: 00000000 *UND* 00000000 ei ; SYM-NEXT: 00000000 l .text 00000091 .text ; SYM-NEXT: 00000000 g F .text (csect: .text) 00000000 .bar @@ -88,7 +88,7 @@ ; SYM-NEXT: 000000ec l O *COM* 00000004 si ; SYM-DES: SYMBOL TABLE: -; SYM-DES-NEXT: 00000000 df *DEBUG* 00000000 (idx: 0) .file +; SYM-DES-NEXT: 00000000 df *DEBUG* 00000000 (idx: 0) ; SYM-DES-NEXT: 00000000 *UND* 00000000 (idx: 1) ei[UA] ; SYM-DES-NEXT: 00000000 l .text 00000091 (idx: 3) .text[PR] ; SYM-DES-NEXT: 00000000 g F .text (csect: (idx: 3) .text[PR]) 00000000 (idx: 5) .bar