#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"
const MCFragment &FB, bool InSet,
bool IsPCRel) const override;
- void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ bool isWeak(const MCSymbolData &SD) const override;
+
+ void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
const MCFragment *Fragment, const MCFixup &Fixup,
MCValue Target, bool &IsPCRel,
uint64_t &FixedValue) override;
coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol());
} else {
- std::string WeakName = std::string(".weak.")
- + Symbol.getName().str()
- + ".default";
+ std::string WeakName = (".weak." + Symbol.getName() + ".default").str();
COFFSymbol *WeakDefault = createSymbol(WeakName);
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
WeakDefault->Data.StorageClass = COFF::IMAGE_SYM_CLASS_EXTERNAL;
InSet, IsPCRel);
}
-void WinCOFFObjectWriter::RecordRelocation(const MCAssembler &Asm,
- const MCAsmLayout &Layout,
- const MCFragment *Fragment,
- const MCFixup &Fixup,
- MCValue Target,
- bool &IsPCRel,
- uint64_t &FixedValue) {
+bool WinCOFFObjectWriter::isWeak(const MCSymbolData &SD) const {
+ // FIXME: this is for PR23025. Write a good description on
+ // why this is needed.
+ return SD.isExternal();
+}
+
+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();
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();
}
++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?
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;
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);
}