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 @@ -203,7 +203,7 @@ uint64_t writeObject(MCAssembler &, const MCAsmLayout &) override; - static bool nameShouldBeInStringTable(const StringRef &); + bool nameShouldBeInStringTable(const StringRef &); void writeSymbolName(const StringRef &); void writeSymbolTableEntryForCsectMemberLabel(const Symbol &, const ControlSection &, int16_t, @@ -344,8 +344,9 @@ void XCOFFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { + // TODO: Add ".file" in the StringTableBuilder implicitly for XCOFF64. if (TargetObjectWriter->is64Bit()) - report_fatal_error("64-bit XCOFF object files are not supported yet."); + Strings.add(".file"); for (const auto &S : Asm) { const auto *MCSec = cast(&S); @@ -559,9 +560,6 @@ if (Asm.isIncrementalLinkerCompatible()) report_fatal_error("Incremental linking not supported for XCOFF."); - if (TargetObjectWriter->is64Bit()) - report_fatal_error("64-bit XCOFF object files are not supported yet."); - finalizeSectionInfo(); uint64_t StartOffset = W.OS.tell(); @@ -578,29 +576,37 @@ } bool XCOFFObjectWriter::nameShouldBeInStringTable(const StringRef &SymbolName) { - return SymbolName.size() > XCOFF::NameSize; + return SymbolName.size() > XCOFF::NameSize || TargetObjectWriter->is64Bit(); } void XCOFFObjectWriter::writeSymbolName(const StringRef &SymbolName) { - if (nameShouldBeInStringTable(SymbolName)) { - W.write(0); - W.write(Strings.getOffset(SymbolName)); - } else { - char Name[XCOFF::NameSize+1]; - std::strncpy(Name, SymbolName.data(), XCOFF::NameSize); - ArrayRef NameRef(Name, XCOFF::NameSize); - W.write(NameRef); + if (TargetObjectWriter->is64Bit()) + W.write(Strings.getOffset(SymbolName)); + else { + if (nameShouldBeInStringTable(SymbolName)) { + W.write(0); + W.write(Strings.getOffset(SymbolName)); + } else { + char Name[XCOFF::NameSize+1]; + std::strncpy(Name, SymbolName.data(), XCOFF::NameSize); + ArrayRef NameRef(Name, XCOFF::NameSize); + W.write(NameRef); + } } } void XCOFFObjectWriter::writeSymbolTableEntryForCsectMemberLabel( const Symbol &SymbolRef, const ControlSection &CSectionRef, int16_t SectionIndex, uint64_t SymbolOffset) { - // Name or Zeros and string table offset + if (TargetObjectWriter->is64Bit()) + W.write(CSectionRef.Address + SymbolOffset); + // Name or string table offset writeSymbolName(SymbolRef.getSymbolTableName()); - assert(SymbolOffset <= UINT32_MAX - CSectionRef.Address && - "Symbol address overflows."); - W.write(CSectionRef.Address + SymbolOffset); + if (!TargetObjectWriter->is64Bit()) { + assert(SymbolOffset <= UINT32_MAX - CSectionRef.Address && + "Symbol address overflows."); + W.write(CSectionRef.Address + SymbolOffset); + } W.write(SectionIndex); // Basic/Derived type. See the description of the n_type field for symbol // table entries for a detailed description. Since we don't yet support @@ -624,19 +630,36 @@ W.write(XCOFF::XTY_LD); // Storage mapping class. W.write(CSectionRef.MCCsect->getMappingClass()); - // Reserved (x_stab). - W.write(0); - // Reserved (x_snstab). - W.write(0); + if (TargetObjectWriter->is64Bit()) { + // High 4 bytes length. + W.write((CSectionRef.SymbolTableIndex & 0xFFFFFFFF00000000) >> + 32); + // Reserved (pad). + W.write(0); + // Auxiliary type entry. + W.write(XCOFF::SymbolAuxType::AUX_CSECT); + } else { + // Reserved (x_stab). + W.write(0); + // Reserved (x_snstab). + W.write(0); + } } void XCOFFObjectWriter::writeSymbolTableEntryForControlSection( const ControlSection &CSectionRef, int16_t SectionIndex, XCOFF::StorageClass StorageClass) { - // n_name, n_zeros, n_offset - writeSymbolName(CSectionRef.getSymbolTableName()); - // n_value - W.write(CSectionRef.Address); + if (TargetObjectWriter->is64Bit()) { + // n_value + W.write(CSectionRef.Address); + // n_offset + writeSymbolName(CSectionRef.getSymbolTableName()); + } else { + // n_name, n_zeros, n_offset + writeSymbolName(CSectionRef.getSymbolTableName()); + // n_value + W.write(CSectionRef.Address); + } // n_scnum W.write(SectionIndex); // Basic/Derived type. See the description of the n_type field for symbol @@ -662,10 +685,19 @@ W.write(getEncodedType(CSectionRef.MCCsect)); // Storage mapping class. W.write(CSectionRef.MCCsect->getMappingClass()); - // Reserved (x_stab). - W.write(0); - // Reserved (x_snstab). - W.write(0); + if (TargetObjectWriter->is64Bit()) { + // High 4 bytes length. + W.write((CSectionRef.Size & 0xFFFFFFFF00000000) >> 32); + // Reserved (pad). + W.write(0); + // Auxiliary type entry. + W.write(XCOFF::SymbolAuxType::AUX_CSECT); + } else { + // Reserved (x_stab). + W.write(0); + // Reserved (x_snstab). + W.write(0); + } } void XCOFFObjectWriter::writeFileHeader() { @@ -751,6 +783,9 @@ void XCOFFObjectWriter::writeRelocation(XCOFFRelocation Reloc, const ControlSection &CSection) { + if (TargetObjectWriter->is64Bit()) + report_fatal_error("64-bit XCOFF object files are not supported yet."); + W.write(CSection.Address + Reloc.FixupOffsetInCsect); W.write(Reloc.SymbolTableIndex); W.write(Reloc.SignAndSize); @@ -784,9 +819,15 @@ // provided by an auxiliary entry, in which case the n_name of the C_FILE // symbol is `.file`. // FIXME: add the real source filename. - writeSymbolName(".file"); - // n_value. The n_value of a C_FILE symbol is its symbol table index. - W.write(0); + if (TargetObjectWriter->is64Bit()) { + // n_value. The n_value of a C_FILE symbol is its symbol table index. + W.write(0); + writeSymbolName(".file"); + } else { + writeSymbolName(".file"); + // n_value. + W.write(0); + } // n_scnum. N_DEBUG is a reserved section number for indicating a special // symbolic debugging symbol. W.write(XCOFF::ReservedSectionNum::N_DEBUG);