summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-09-01 21:23:58 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-09-01 21:23:58 +0000
commit6ddc636862095a3d6f1b02ea034a353c19fff328 (patch)
tree6d0ce200909cf6de6484896ac403384425cd604e /llvm/lib/MC
parentee1cff5fab3c713f40a89741369bbcaf26b7c8be (diff)
downloadbcm5719-llvm-6ddc636862095a3d6f1b02ea034a353c19fff328.tar.gz
bcm5719-llvm-6ddc636862095a3d6f1b02ea034a353c19fff328.zip
[MC] Add support for generating COFF CRCs
COFF sections are accompanied with an auxiliary symbol which includes a checksum. This checksum used to be filled with just zero but this seems to upset LINK.exe when it is processing a /INCREMENTAL link job. Instead, fill the CheckSum field with the JamCRC of the section contents. This matches MSVC's behavior. This fixes PR19666. N.B. A rather simple implementation of JamCRC is given. It implements a byte-wise calculation using the method given by Sarwate. There are implementations with higher throughput like slice-by-eight and making use of PCLMULQDQ. We can switch to one of those techniques if it turns out to be a significant use of time. llvm-svn: 246590
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/WinCOFFObjectWriter.cpp28
1 files changed, 28 insertions, 0 deletions
diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp
index a0a11d42111..9abd1a15906 100644
--- a/llvm/lib/MC/WinCOFFObjectWriter.cpp
+++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp
@@ -32,6 +32,7 @@
#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>
@@ -1029,6 +1030,7 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
}
}
+ SmallVector<char, 128> SectionContents;
for (i = Sections.begin(), ie = Sections.end(), j = Asm.begin(),
je = Asm.end();
(i != ie) && (j != je); ++i, ++j) {
@@ -1047,7 +1049,33 @@ void WinCOFFObjectWriter::writeObject(MCAssembler &Asm,
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) {
OpenPOWER on IntegriCloud