@@ -361,6 +361,8 @@ class XCOFFObjectWriter : public MCObjectWriter {
361361 bool is64Bit () const { return TargetObjectWriter->is64Bit (); }
362362 bool nameShouldBeInStringTable (const StringRef &);
363363 void writeSymbolName (const StringRef &);
364+ bool auxFileSymNameShouldBeInStringTable (const StringRef &);
365+ void writeAuxFileSymName (const StringRef &);
364366
365367 void writeSymbolEntryForCsectMemberLabel (const Symbol &SymbolRef,
366368 const XCOFFSection &CSectionRef,
@@ -391,7 +393,8 @@ class XCOFFObjectWriter : public MCObjectWriter {
391393 const MCAsmLayout &Layout,
392394 CInfoSymSectionEntry &CInfoSymEntry,
393395 uint64_t &CurrentAddressLocation);
394- void writeSymbolTable (const MCAsmLayout &Layout);
396+ void writeSymbolTable (MCAssembler &Asm, const MCAsmLayout &Layout);
397+ void writeSymbolAuxFileEntry (StringRef &Name, uint8_t ftype);
395398 void writeSymbolAuxDwarfEntry (uint64_t LengthOfSectionPortion,
396399 uint64_t NumberOfRelocEnt = 0 );
397400 void writeSymbolAuxCsectEntry (uint64_t SectionOrLength,
@@ -416,7 +419,7 @@ class XCOFFObjectWriter : public MCObjectWriter {
416419 // *) Assigns symbol table indices.
417420 // *) Builds up the section header table by adding any non-empty sections to
418421 // `Sections`.
419- void assignAddressesAndIndices (const MCAsmLayout &);
422+ void assignAddressesAndIndices (MCAssembler &Asm, const MCAsmLayout &);
420423 // Called after relocations are recorded.
421424 void finalizeSectionInfo ();
422425 void finalizeRelocationInfo (SectionEntry *Sec, uint64_t RelCount);
@@ -640,12 +643,20 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
640643 if (FileNames.empty ())
641644 FileNames.emplace_back (" .file" , 0 );
642645 for (const std::pair<std::string, size_t > &F : FileNames) {
643- if (nameShouldBeInStringTable (F.first ))
646+ if (auxFileSymNameShouldBeInStringTable (F.first ))
644647 Strings.add (F.first );
645648 }
646649
650+ // Always add ".file" to the symbol table. The actual file name will be in
651+ // the AUX_FILE auxiliary entry.
652+ if (nameShouldBeInStringTable (" .file" ))
653+ Strings.add (" .file" );
654+ StringRef Vers = Asm.getCompilerVersion ();
655+ if (auxFileSymNameShouldBeInStringTable (Vers))
656+ Strings.add (Vers);
657+
647658 Strings.finalize ();
648- assignAddressesAndIndices (Layout);
659+ assignAddressesAndIndices (Asm, Layout);
649660}
650661
651662void XCOFFObjectWriter::recordRelocation (MCAssembler &Asm,
@@ -818,7 +829,7 @@ uint64_t XCOFFObjectWriter::writeObject(MCAssembler &Asm,
818829 writeSectionHeaderTable ();
819830 writeSections (Asm, Layout);
820831 writeRelocations ();
821- writeSymbolTable (Layout);
832+ writeSymbolTable (Asm, Layout);
822833 // Write the string table.
823834 Strings.write (W.OS );
824835
@@ -878,6 +889,36 @@ void XCOFFObjectWriter::writeSymbolAuxCsectEntry(uint64_t SectionOrLength,
878889 }
879890}
880891
892+ bool XCOFFObjectWriter::auxFileSymNameShouldBeInStringTable (
893+ const StringRef &SymbolName) {
894+ return SymbolName.size () > XCOFF::AuxFileEntNameSize;
895+ }
896+
897+ void XCOFFObjectWriter::writeAuxFileSymName (const StringRef &SymbolName) {
898+ // Magic, Offset or SymbolName.
899+ if (auxFileSymNameShouldBeInStringTable (SymbolName)) {
900+ W.write <int32_t >(0 );
901+ W.write <uint32_t >(Strings.getOffset (SymbolName));
902+ W.OS .write_zeros (XCOFF::FileNamePadSize);
903+ } else {
904+ char Name[XCOFF::AuxFileEntNameSize + 1 ];
905+ std::strncpy (Name, SymbolName.data (), XCOFF::AuxFileEntNameSize);
906+ ArrayRef<char > NameRef (Name, XCOFF::AuxFileEntNameSize);
907+ W.write (NameRef);
908+ }
909+ }
910+
911+ void XCOFFObjectWriter::writeSymbolAuxFileEntry (StringRef &Name,
912+ uint8_t ftype) {
913+ writeAuxFileSymName (Name);
914+ W.write <uint8_t >(ftype);
915+ W.OS .write_zeros (2 );
916+ if (is64Bit ())
917+ W.write <uint8_t >(XCOFF::AUX_FILE);
918+ else
919+ W.OS .write_zeros (1 );
920+ }
921+
881922void XCOFFObjectWriter::writeSymbolAuxDwarfEntry (
882923 uint64_t LengthOfSectionPortion, uint64_t NumberOfRelocEnt) {
883924 writeWord (LengthOfSectionPortion);
@@ -1109,8 +1150,11 @@ void XCOFFObjectWriter::writeRelocations() {
11091150 writeRelocation (Reloc, *DwarfSection.DwarfSect );
11101151}
11111152
1112- void XCOFFObjectWriter::writeSymbolTable (const MCAsmLayout &Layout) {
1153+ void XCOFFObjectWriter::writeSymbolTable (MCAssembler &Asm,
1154+ const MCAsmLayout &Layout) {
11131155 // Write C_FILE symbols.
1156+ StringRef Vers = Asm.getCompilerVersion ();
1157+
11141158 for (const std::pair<std::string, size_t > &F : FileNames) {
11151159 // The n_name of a C_FILE symbol is the source file's name when no auxiliary
11161160 // entries are present.
@@ -1139,9 +1183,15 @@ void XCOFFObjectWriter::writeSymbolTable(const MCAsmLayout &Layout) {
11391183 else
11401184 CpuID = XCOFF::TCPU_COM;
11411185
1142- writeSymbolEntry (FileName, /* Value=*/ 0 , XCOFF::ReservedSectionNum::N_DEBUG,
1186+ int NumberOfFileAuxEntries = 1 ;
1187+ if (!Vers.empty ())
1188+ ++NumberOfFileAuxEntries;
1189+ writeSymbolEntry (" .file" , /* Value=*/ 0 , XCOFF::ReservedSectionNum::N_DEBUG,
11431190 /* SymbolType=*/ (LangID << 8 ) | CpuID, XCOFF::C_FILE,
1144- /* NumberOfAuxEntries=*/ 0 );
1191+ NumberOfFileAuxEntries);
1192+ writeSymbolAuxFileEntry (FileName, XCOFF::XFT_FN);
1193+ if (!Vers.empty ())
1194+ writeSymbolAuxFileEntry (Vers, XCOFF::XFT_CV);
11451195 }
11461196
11471197 if (CInfoSymSection.Entry )
@@ -1357,9 +1407,12 @@ void XCOFFObjectWriter::addCInfoSymEntry(StringRef Name, StringRef Metadata) {
13571407 std::make_unique<CInfoSymInfo>(Name.str (), Metadata.str ()));
13581408}
13591409
1360- void XCOFFObjectWriter::assignAddressesAndIndices (const MCAsmLayout &Layout) {
1361- // The symbol table starts with all the C_FILE symbols.
1362- uint32_t SymbolTableIndex = FileNames.size ();
1410+ void XCOFFObjectWriter::assignAddressesAndIndices (MCAssembler &Asm,
1411+ const MCAsmLayout &Layout) {
1412+ // The symbol table starts with all the C_FILE symbols. Each C_FILE symbol
1413+ // requires 1 or 2 auxiliary entries.
1414+ uint32_t SymbolTableIndex =
1415+ (2 + (Asm.getCompilerVersion ().empty () ? 0 : 1 )) * FileNames.size ();
13631416
13641417 if (CInfoSymSection.Entry )
13651418 SymbolTableIndex++;
0 commit comments