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 @@ -122,6 +122,15 @@ int16_t Index; + virtual uint64_t advanceFileOffset(const uint64_t MaxRawDataSize, + const uint64_t RawPointer) { + FileOffsetToData = RawPointer; + uint64_t NewPointer = RawPointer + Size; + if (NewPointer > MaxRawDataSize) + report_fatal_error("Section raw data overflowed this object file."); + return NewPointer; + } + // XCOFF has special section numbers for symbols: // -2 Specifies N_DEBUG, a special symbolic debugging symbol. // -1 Specifies N_ABS, an absolute symbol. The symbol has a value but is not @@ -189,6 +198,19 @@ // is for the size the DWARF section occupies including paddings. uint32_t MemorySize; + // TODO: Remove this override. Loadable sections (e.g., .text, .data) may need + // to be aligned. Other sections generally don't need any alignment, but if + // they're aligned, the RawPointer should be adjusted before writing the + // section. Then a dwarf-specific function wouldn't be needed. + uint64_t advanceFileOffset(const uint64_t MaxRawDataSize, + const uint64_t RawPointer) override { + FileOffsetToData = RawPointer; + uint64_t NewPointer = RawPointer + MemorySize; + assert(NewPointer <= MaxRawDataSize && + "Section raw data overflowed this object file."); + return NewPointer; + } + DwarfSectionEntry(StringRef N, int32_t Flags, std::unique_ptr Sect) : SectionEntry(N, Flags | XCOFF::STYP_DWARF), DwarfSect(std::move(Sect)), @@ -1162,28 +1184,18 @@ if (Sec->Index == SectionEntry::UninitializedIndex || Sec->IsVirtual) continue; - Sec->FileOffsetToData = RawPointer; - RawPointer += Sec->Size; - if (RawPointer > MaxRawDataSize) - report_fatal_error("Section raw data overflowed this object file."); + RawPointer = Sec->advanceFileOffset(MaxRawDataSize, RawPointer); } if (!DwarfSections.empty()) { RawPointer += PaddingsBeforeDwarf; for (auto &DwarfSection : DwarfSections) { - DwarfSection.FileOffsetToData = RawPointer; - RawPointer += DwarfSection.MemorySize; - if (RawPointer > MaxRawDataSize) - report_fatal_error("Section raw data overflowed this object file."); + RawPointer = DwarfSection.advanceFileOffset(MaxRawDataSize, RawPointer); } } if (hasExceptionSection()) { - ExceptionSection.FileOffsetToData = RawPointer; - RawPointer += ExceptionSection.Size; - - assert(RawPointer <= MaxRawDataSize && - "Section raw data overflowed this object file."); + RawPointer = ExceptionSection.advanceFileOffset(MaxRawDataSize, RawPointer); } for (auto *Sec : Sections) {