#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/JamCRC.h"
#include "llvm/Support/TimeValue.h"
#include <cstdio>
+#include <ctime>
using namespace llvm;
}
// if this is a safeseh handler, keep it
- if (MC && (MC->getFlags() & COFF::SF_SafeSEH))
+ if (MC && (cast<MCSymbolCOFF>(MC)->isSafeSEH()))
return true;
// if the section its in is being droped, drop it
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
SymbolMap[&Symbol] = coff_symbol;
- if (Symbol.getFlags() & COFF::SF_WeakExternal) {
+ if (cast<MCSymbolCOFF>(Symbol).isWeakExternal()) {
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
if (Symbol.isVariable()) {
const MCSymbolCOFF &SymbolCOFF = cast<MCSymbolCOFF>(Symbol);
coff_symbol->Data.Type = SymbolCOFF.getType();
- coff_symbol->Data.StorageClass =
- (Symbol.getFlags() & COFF::SF_ClassMask) >> COFF::SF_ClassShift;
+ coff_symbol->Data.StorageClass = SymbolCOFF.getClass();
// If no storage class was specified in the streamer, define it here.
if (coff_symbol->Data.StorageClass == COFF::IMAGE_SYM_CLASS_NULL) {
if (!Symbol.isTemporary())
return true;
- // Absolute temporary labels are never visible.
- if (!Symbol.isInSection())
+ // Temporary variable symbols are invisible.
+ if (Symbol.isVariable())
return false;
- // For now, all non-variable symbols are exported,
- // the linker will sort the rest out for us.
- return !Symbol.isVariable();
+ // Absolute temporary labels are never visible.
+ return !Symbol.isAbsolute();
}
bool WinCOFFObjectWriter::IsPhysicalSection(COFFSection *S) {
Header.PointerToSymbolTable = offset;
- // We want a deterministic output. It looks like GNU as also writes 0 in here.
- Header.TimeDateStamp = 0;
+ // MS LINK expects to be able to use this timestamp to implement their
+ // /INCREMENTAL feature.
+ std::time_t Now = time(nullptr);
+ if (Now < 0 || Now > UINT32_MAX)
+ Now = UINT32_MAX;
+ Header.TimeDateStamp = Now;
// Write it all to disk...
WriteFileHeader(Header);
}
}
+ SmallVector<char, 128> SectionContents;
for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(),
je = Asm.end();
(i != ie) && (j != je); ++i, ++j) {
continue;
if ((*i)->Header.PointerToRawData != 0) {
- assert(OS.tell() <= (*i)->Header.PointerToRawData &&
+ assert(getStream().tell() <= (*i)->Header.PointerToRawData &&
"Section::PointerToRawData is insane!");
- unsigned SectionDataPadding = (*i)->Header.PointerToRawData - OS.tell();
+ unsigned SectionDataPadding =
+ (*i)->Header.PointerToRawData - getStream().tell();
assert(SectionDataPadding < 4 &&
"Should only need at most three bytes of padding!");
WriteZeros(SectionDataPadding);
+ // Save the contents of the section to a temporary buffer, we need this
+ // to CRC the data before we dump it into the object file.
+ SectionContents.clear();
+ raw_svector_ostream VecOS(SectionContents);
+ raw_pwrite_stream &OldStream = getStream();
+ // Redirect the output stream to our buffer.
+ setStream(VecOS);
+ // Fill our buffer with the section data.
Asm.writeSectionData(&*j, Layout);
+ // Reset the stream back to what it was before.
+ setStream(OldStream);
+
+ // Calculate our CRC with an initial value of '0', this is not how
+ // JamCRC is specified but it aligns with the expected output.
+ JamCRC JC(/*Init=*/0x00000000U);
+ JC.update(SectionContents);
+
+ // Write the section contents to the object file.
+ getStream() << SectionContents;
+
+ // Update the section definition auxiliary symbol to record the CRC.
+ COFFSection *Sec = SectionMap[&*j];
+ COFFSymbol::AuxiliarySymbols &AuxSyms = Sec->Symbol->Aux;
+ assert(AuxSyms.size() == 1 &&
+ AuxSyms[0].AuxType == ATSectionDefinition);
+ AuxSymbol &SecDef = AuxSyms[0];
+ SecDef.Aux.SectionDefinition.CheckSum = JC.getCRC();
}
if ((*i)->Relocations.size() > 0) {
- assert(OS.tell() == (*i)->Header.PointerToRelocations &&
+ assert(getStream().tell() == (*i)->Header.PointerToRelocations &&
"Section::PointerToRelocations is insane!");
if ((*i)->Relocations.size() >= 0xffff) {
}
}
- assert(OS.tell() == Header.PointerToSymbolTable &&
+ assert(getStream().tell() == Header.PointerToSymbolTable &&
"Header::PointerToSymbolTable is insane!");
for (auto &Symbol : Symbols)
if (Symbol->getIndex() != -1)
WriteSymbol(*Symbol);
- OS.write(Strings.data().data(), Strings.data().size());
+ getStream().write(Strings.data().data(), Strings.data().size());
}
MCWinCOFFObjectTargetWriter::MCWinCOFFObjectTargetWriter(unsigned Machine_)