Index: llvm/lib/MC/XCOFFObjectWriter.cpp =================================================================== --- llvm/lib/MC/XCOFFObjectWriter.cpp +++ llvm/lib/MC/XCOFFObjectWriter.cpp @@ -55,7 +55,7 @@ struct XCOFFRelocation { uint32_t SymbolTableIndex; - uint32_t FixupOffsetInCsect; + uint64_t FixupOffsetInCsect; uint8_t SignAndSize; uint8_t Type; }; @@ -77,8 +77,8 @@ struct XCOFFSection { const MCSectionXCOFF *const MCSec; uint32_t SymbolTableIndex; - uint32_t Address; - uint32_t Size; + uint64_t Address; + uint64_t Size; SmallVector Syms; SmallVector Relocations; @@ -100,10 +100,10 @@ char Name[XCOFF::NameSize]; // The physical/virtual address of the section. For an object file // these values are equivalent. - uint32_t Address; - uint32_t Size; - uint32_t FileOffsetToData; - uint32_t FileOffsetToRelocations; + uint64_t Address; + uint64_t Size; + uint64_t FileOffsetToData; + uint64_t FileOffsetToRelocations; uint32_t RelocationCount; int32_t Flags; @@ -171,7 +171,7 @@ class XCOFFObjectWriter : public MCObjectWriter { uint32_t SymbolTableEntryCount = 0; - uint32_t SymbolTableOffset = 0; + uint64_t SymbolTableOffset = 0; uint16_t SectionCount = 0; uint32_t RelocationEntryOffset = 0; @@ -498,7 +498,7 @@ (TargetObjectWriter->is64Bit() || Fixup.getOffset() <= UINT32_MAX - Layout.getFragmentOffset(Fragment)) && "Fragment offset + fixup offset is overflowed in 32-bit mode."); - uint32_t FixupOffsetInCsect = + uint64_t FixupOffsetInCsect = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); XCOFFRelocation Reloc = {Index, FixupOffsetInCsect, SignAndSize, Type}; @@ -537,7 +537,7 @@ void XCOFFObjectWriter::writeSections(const MCAssembler &Asm, const MCAsmLayout &Layout) { - uint32_t CurrentAddressLocation = 0; + uint64_t CurrentAddressLocation = 0; for (const auto *Section : Sections) { // Nothing to write for this Section. if (Section->Index == SectionEntry::UninitializedIndex || @@ -694,20 +694,30 @@ void XCOFFObjectWriter::writeFileHeader() { // Magic. - W.write(0x01df); + if (TargetObjectWriter->is64Bit()) + W.write(0x01f7); + else + W.write(0x01df); // Number of sections. W.write(SectionCount); // Timestamp field. For reproducible output we write a 0, which represents no // timestamp. W.write(0); // Byte Offset to the start of the symbol table. - W.write(SymbolTableOffset); - // Number of entries in the symbol table. - W.write(SymbolTableEntryCount); + if (TargetObjectWriter->is64Bit()) + W.write(SymbolTableOffset); + else { + W.write(SymbolTableOffset); + // Number of entries in the symbol table. + W.write(SymbolTableEntryCount); + } // Size of the optional header. W.write(0); // Flags. W.write(0); + if (TargetObjectWriter->is64Bit()) + // Number of entries in the symbol table. + W.write(SymbolTableEntryCount); } void XCOFFObjectWriter::writeSectionHeaderTable() { @@ -720,24 +730,46 @@ ArrayRef NameRef(Sec->Name, XCOFF::NameSize); W.write(NameRef); - // Write the Physical Address and Virtual Address. In an object file these - // are the same. - W.write(Sec->Address); - W.write(Sec->Address); + if (TargetObjectWriter->is64Bit()) { + // Write the Physical Address and Virtual Address. In an object file these + // are the same. + W.write(Sec->Address); + W.write(Sec->Address); + + W.write(Sec->Size); + W.write(Sec->FileOffsetToData); + W.write(Sec->FileOffsetToRelocations); + + // Line number pointer. Not supported yet. + W.write(0); - W.write(Sec->Size); - W.write(Sec->FileOffsetToData); - W.write(Sec->FileOffsetToRelocations); + W.write(Sec->RelocationCount); - // Line number pointer. Not supported yet. - W.write(0); + // Line number counts. Not supported yet. + W.write(0); - W.write(Sec->RelocationCount); + W.write(Sec->Flags); + W.write(0); + } else { + // Write the Physical Address and Virtual Address. In an object file these + // are the same. + W.write(Sec->Address); + W.write(Sec->Address); - // Line number counts. Not supported yet. - W.write(0); + W.write(Sec->Size); + W.write(Sec->FileOffsetToData); + W.write(Sec->FileOffsetToRelocations); - W.write(Sec->Flags); + // Line number pointer. Not supported yet. + W.write(0); + + W.write(Sec->RelocationCount); + + // Line number counts. Not supported yet. + W.write(0); + + W.write(Sec->Flags); + } } } @@ -851,10 +883,16 @@ continue; Sec->FileOffsetToRelocations = RawPointer; - const uint32_t RelocationSizeInSec = - Sec->RelocationCount * XCOFF::RelocationSerializationSize32; + uint64_t RelocationSizeInSec; + if (TargetObjectWriter->is64Bit()) + RelocationSizeInSec = + Sec->RelocationCount * XCOFF::RelocationSerializationSize64; + else + RelocationSizeInSec = + Sec->RelocationCount * XCOFF::RelocationSerializationSize32; + RawPointer += RelocationSizeInSec; - if (RawPointer > UINT32_MAX) + if (RawPointer > UINT32_MAX && !TargetObjectWriter->is64Bit()) report_fatal_error("Relocation data overflowed this object file."); } @@ -881,7 +919,7 @@ // 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. - uint32_t Address = 0; + uint64_t Address = 0; // Section indices are 1-based in XCOFF. int32_t SectionIndex = 1; bool HasTDataSection = false; @@ -947,15 +985,20 @@ SymbolTableEntryCount = SymbolTableIndex; // Calculate the RawPointer value for each section. - uint64_t RawPointer = XCOFF::FileHeaderSize32 + auxiliaryHeaderSize() + - SectionCount * XCOFF::SectionHeaderSize32; + uint64_t RawPointer; + if (TargetObjectWriter->is64Bit()) + RawPointer = XCOFF::FileHeaderSize64 + auxiliaryHeaderSize() + + SectionCount * XCOFF::SectionHeaderSize64; + else + RawPointer = XCOFF::FileHeaderSize32 + auxiliaryHeaderSize() + + SectionCount * XCOFF::SectionHeaderSize32; for (auto *Sec : Sections) { if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual) continue; Sec->FileOffsetToData = RawPointer; RawPointer += Sec->Size; - if (RawPointer > UINT32_MAX) + if (RawPointer > UINT32_MAX && !TargetObjectWriter->is64Bit()) report_fatal_error("Section raw data overflowed this object file."); }