diff options
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r-- | lib/MC/WinCOFFObjectWriter.cpp | 70 |
1 files changed, 40 insertions, 30 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp index 1046e04..c519a9d 100644 --- a/lib/MC/WinCOFFObjectWriter.cpp +++ b/lib/MC/WinCOFFObjectWriter.cpp @@ -13,9 +13,9 @@ #include "llvm/MC/MCWinCOFFObjectWriter.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" @@ -175,7 +175,7 @@ public: const MCFragment &FB, bool InSet, bool IsPCRel) const override; - void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, + void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) override; @@ -266,12 +266,12 @@ COFFSymbol *WinCOFFObjectWriter::createSymbol(StringRef Name) { return createCOFFEntity<COFFSymbol>(Name, Symbols); } -COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol * Symbol){ +COFFSymbol *WinCOFFObjectWriter::GetOrCreateCOFFSymbol(const MCSymbol *Symbol) { symbol_map::iterator i = SymbolMap.find(Symbol); if (i != SymbolMap.end()) return i->second; - COFFSymbol *RetSymbol - = createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); + COFFSymbol *RetSymbol = + createCOFFEntity<COFFSymbol>(Symbol->getName(), Symbols); SymbolMap[Symbol] = RetSymbol; return RetSymbol; } @@ -640,7 +640,7 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) { // "Define" each section & symbol. This creates section & symbol // entries in the staging area. - for (const auto & Section : Asm) + for (const auto &Section : Asm) DefineSection(Section); for (MCSymbolData &SD : Asm.symbols()) @@ -661,13 +661,9 @@ bool WinCOFFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( InSet, IsPCRel); } -void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - bool &IsPCRel, - uint64_t &FixedValue) { +void WinCOFFObjectWriter::RecordRelocation( + MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, + const MCFixup &Fixup, MCValue Target, bool &IsPCRel, uint64_t &FixedValue) { assert(Target.getSymA() && "Relocation must reference a symbol!"); const MCSymbol &Symbol = Target.getSymA()->getSymbol(); @@ -710,17 +706,22 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, CrossSection = &Symbol.getSection() != &B->getSection(); // Offset of the symbol in the section - int64_t a = Layout.getSymbolOffset(&B_SD); - - // Offset of the relocation in the section - int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + int64_t OffsetOfB = Layout.getSymbolOffset(&B_SD); - FixedValue = b - a; // In the case where we have SymbA and SymB, we just need to store the delta // between the two symbols. Update FixedValue to account for the delta, and // skip recording the relocation. - if (!CrossSection) + if (!CrossSection) { + int64_t OffsetOfA = Layout.getSymbolOffset(&A_SD); + FixedValue = (OffsetOfA - OffsetOfB) + Target.getConstant(); return; + } + + // Offset of the relocation in the section + int64_t OffsetOfRelocation = + Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + + FixedValue = OffsetOfRelocation - OffsetOfB; } else { FixedValue = Target.getConstant(); } @@ -741,8 +742,9 @@ void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm, ++Reloc.Symb->Relocations; Reloc.Data.VirtualAddress += Fixup.getOffset(); - Reloc.Data.Type = TargetObjectWriter->getRelocType(Target, Fixup, - CrossSection); + Reloc.Data.Type = + TargetObjectWriter->getRelocType(Target, Fixup, CrossSection, + Asm.getBackend()); // FIXME: Can anyone explain what this does other than adjust for the size // of the offset? @@ -835,7 +837,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, unsigned Offset = 0; unsigned Length = FI->size(); - for (auto & Aux : file->Aux) { + for (auto &Aux : file->Aux) { Aux.AuxType = ATFile; if (Length > SymbolSize) { @@ -881,7 +883,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, SetSymbolName(*S); // Fixup weak external references. - for (auto & Symbol : Symbols) { + for (auto &Symbol : Symbols) { if (Symbol->Other) { assert(Symbol->Index != -1); assert(Symbol->Aux.size() == 1 && "Symbol must contain one aux symbol!"); @@ -892,7 +894,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, } // Fixup associative COMDAT sections. - for (auto & Section : Sections) { + for (auto &Section : Sections) { if (Section->Symbol->Aux[0].Aux.SectionDefinition.Selection != COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) continue; @@ -928,7 +930,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, offset += COFF::Header16Size; offset += COFF::SectionSize * Header.NumberOfSections; - for (const auto & Section : Asm) { + for (const auto &Section : Asm) { COFFSection *Sec = SectionMap[&Section.getSection()]; if (Sec->Number == -1) @@ -937,6 +939,8 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, Sec->Header.SizeOfRawData = Layout.getSectionAddressSize(&Section); if (IsPhysicalSection(Sec)) { + // Align the section data to a four byte boundary. + offset = RoundUpToAlignment(offset, 4); Sec->Header.PointerToRawData = offset; offset += Sec->Header.SizeOfRawData; @@ -961,7 +965,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, offset += COFF::RelocationSize * Sec->Relocations.size(); - for (auto & Relocation : Sec->Relocations) { + for (auto &Relocation : Sec->Relocations) { assert(Relocation.Symb->Index != -1); Relocation.Data.SymbolTableIndex = Relocation.Symb->Index; } @@ -991,7 +995,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, sections::iterator i, ie; MCAssembler::const_iterator j, je; - for (auto & Section : Sections) { + for (auto &Section : Sections) { if (Section->Number != -1) { if (Section->Relocations.size() >= 0xffff) Section->Header.Characteristics |= COFF::IMAGE_SCN_LNK_NRELOC_OVFL; @@ -1007,9 +1011,15 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, continue; if ((*i)->Header.PointerToRawData != 0) { - assert(OS.tell() == (*i)->Header.PointerToRawData && + assert(OS.tell() <= (*i)->Header.PointerToRawData && "Section::PointerToRawData is insane!"); + unsigned SectionDataPadding = (*i)->Header.PointerToRawData - OS.tell(); + assert(SectionDataPadding < 4 && + "Should only need at most three bytes of padding!"); + + WriteZeros(SectionDataPadding); + Asm.writeSectionData(j, Layout); } @@ -1027,7 +1037,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, WriteRelocation(r); } - for (const auto & Relocation : (*i)->Relocations) + for (const auto &Relocation : (*i)->Relocations) WriteRelocation(Relocation.Data); } else assert((*i)->Header.PointerToRelocations == 0 && @@ -1038,7 +1048,7 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm, assert(OS.tell() == Header.PointerToSymbolTable && "Header::PointerToSymbolTable is insane!"); - for (auto & Symbol : Symbols) + for (auto &Symbol : Symbols) if (Symbol->Index != -1) WriteSymbol(*Symbol); |