diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-09-01 21:23:58 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-09-01 21:23:58 +0000 |
| commit | 6ddc636862095a3d6f1b02ea034a353c19fff328 (patch) | |
| tree | 6d0ce200909cf6de6484896ac403384425cd604e /llvm/lib/MC | |
| parent | ee1cff5fab3c713f40a89741369bbcaf26b7c8be (diff) | |
| download | bcm5719-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.cpp | 28 |
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) { |

