aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp70
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);