Skip to content

Commit eb0490e

Browse files
[ILASM] Add support for deterministic builds and PDB checksums (#109091)
Follow-up to #85344. Fixes #8293. Fixes #62484.
1 parent 9cf8a80 commit eb0490e

File tree

21 files changed

+537
-102
lines changed

21 files changed

+537
-102
lines changed

src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,11 @@ HRESULT CeeFileGenWriter::getFileTimeStamp(DWORD *pTimeStamp)
482482
return getPEWriter().getFileTimeStamp(pTimeStamp);
483483
} // HRESULT CeeFileGenWriter::getFileTimeStamp()
484484

485+
void CeeFileGenWriter::setFileHeaderTimeStamp(DWORD timeStamp)
486+
{
487+
return getPEWriter().setFileHeaderTimeStamp(timeStamp);
488+
} // void CeeFileGenWriter::setFileHeaderTimeStamp()
489+
485490
HRESULT CeeFileGenWriter::setAddrReloc(UCHAR *instrAddr, DWORD value)
486491
{
487492
*(DWORD *)instrAddr = VAL32(value);

src/coreclr/dlls/mscorpe/iceefilegen.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ HRESULT ICeeFileGen::SetVTableEntry64(HCEEFILE ceeFile, ULONG size, void* ptr)
446446
return gen->setVTableEntry64(size, ptr);
447447
}
448448

449-
HRESULT ICeeFileGen::GetFileTimeStamp (HCEEFILE ceeFile, DWORD *pTimeStamp)
449+
HRESULT ICeeFileGen::GetFileTimeStamp(HCEEFILE ceeFile, DWORD *pTimeStamp)
450450
{
451451
TESTANDRETURNPOINTER(ceeFile);
452452
TESTANDRETURNPOINTER(pTimeStamp);
@@ -455,3 +455,12 @@ HRESULT ICeeFileGen::GetFileTimeStamp (HCEEFILE ceeFile, DWORD *pTimeStamp)
455455
return(gen->getFileTimeStamp(pTimeStamp));
456456
}
457457

458+
HRESULT ICeeFileGen::SetFileHeaderTimeStamp(HCEEFILE ceeFile, DWORD timeStamp)
459+
{
460+
TESTANDRETURNPOINTER(ceeFile);
461+
462+
CeeFileGenWriter *gen = reinterpret_cast<CeeFileGenWriter*>(ceeFile);
463+
gen->setFileHeaderTimeStamp(timeStamp);
464+
return S_OK;
465+
}
466+

src/coreclr/dlls/mscorpe/pewriter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,11 @@ HRESULT PEWriter::getFileTimeStamp(DWORD *pTimeStamp)
16371637
return S_OK;
16381638
}
16391639

1640+
void PEWriter::setFileHeaderTimeStamp(DWORD timeStamp)
1641+
{
1642+
m_ntHeaders->FileHeader.TimeDateStamp = timeStamp;
1643+
}
1644+
16401645
DWORD PEWriter::getImageBase32()
16411646
{
16421647
_ASSERTE(isPE32());

src/coreclr/dlls/mscorpe/pewriter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class PEWriter : public PESectionMan
8383
size_t getImageBase();
8484

8585
HRESULT getFileTimeStamp(DWORD *pTimeStamp);
86+
void setFileHeaderTimeStamp(DWORD timeStamp);
8687

8788
IMAGE_NT_HEADERS32* ntHeaders32() { return (IMAGE_NT_HEADERS32*) m_ntHeaders; }
8889
IMAGE_NT_HEADERS64* ntHeaders64() { return (IMAGE_NT_HEADERS64*) m_ntHeaders; }

src/coreclr/ilasm/assem.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
#include "assembler.h"
1717

18+
#if !defined(_WIN32) && !defined(__APPLE__)
19+
#include "sha256.h"
20+
#endif
21+
1822
void indexKeywords(Indx* indx); // defined in asmparse.y
1923

2024
unsigned int g_uCodePage = CP_ACP;
@@ -28,6 +32,7 @@ Assembler::Assembler()
2832
{
2933
m_pDisp = NULL;
3034
m_pEmitter = NULL;
35+
m_pInternalEmitForDeterministicMvid = NULL;
3136
m_pImporter = NULL;
3237

3338
char* pszFQN = new char[16];
@@ -107,6 +112,7 @@ Assembler::Assembler()
107112
m_fGeneratePDB = FALSE;
108113
m_fIsMscorlib = FALSE;
109114
m_fOptimize = FALSE;
115+
m_fDeterministic = FALSE;
110116
m_tkSysObject = 0;
111117
m_tkSysString = 0;
112118
m_tkSysValue = 0;
@@ -208,6 +214,11 @@ Assembler::~Assembler()
208214
m_pEmitter->Release();
209215
m_pEmitter = NULL;
210216
}
217+
if (m_pInternalEmitForDeterministicMvid != NULL)
218+
{
219+
m_pInternalEmitForDeterministicMvid->Release();
220+
m_pInternalEmitForDeterministicMvid = NULL;
221+
}
211222
if (m_pPortablePdbWriter != NULL)
212223
{
213224
delete m_pPortablePdbWriter;
@@ -233,13 +244,19 @@ BOOL Assembler::Init(BOOL generatePdb)
233244
}
234245

235246
if (FAILED(CreateICeeFileGen(&m_pCeeFileGen))) return FALSE;
236-
237247
if (FAILED(m_pCeeFileGen->CreateCeeFileEx(&m_pCeeFile,(ULONG)m_dwCeeFileFlags))) return FALSE;
238-
239248
if (FAILED(m_pCeeFileGen->GetSectionCreate(m_pCeeFile, ".il", sdReadOnly, &m_pILSection))) return FALSE;
240249
if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".sdata", sdReadWrite, &m_pGlobalDataSection))) return FALSE;
241250
if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".tls", sdReadWrite, &m_pTLSSection))) return FALSE;
242251

252+
#if !defined(_WIN32) && !defined(__APPLE__)
253+
if (m_fDeterministic && !IsOpenSslAvailable())
254+
{
255+
fprintf(stderr, "OpenSSL is not available, but required for build determinism\n");
256+
return FALSE;
257+
}
258+
#endif
259+
243260
m_fGeneratePDB = generatePdb;
244261

245262
return TRUE;

src/coreclr/ilasm/assembler.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2434,12 +2434,9 @@ void Assembler::SetPdbFileName(_In_ __nullterminated char* szName)
24342434
HRESULT Assembler::SavePdbFile()
24352435
{
24362436
HRESULT hr = S_OK;
2437-
mdMethodDef entryPoint;
24382437

24392438
if (FAILED(hr = (m_pPortablePdbWriter == NULL ? E_FAIL : S_OK))) goto exit;
24402439
if (FAILED(hr = (m_pPortablePdbWriter->GetEmitter() == NULL ? E_FAIL : S_OK))) goto exit;
2441-
if (FAILED(hr = m_pCeeFileGen->GetEntryPoint(m_pCeeFile, &entryPoint))) goto exit;
2442-
if (FAILED(hr = m_pPortablePdbWriter->BuildPdbStream(m_pEmitter, entryPoint))) goto exit;
24432440
if (FAILED(hr = m_pPortablePdbWriter->GetEmitter()->Save(m_wzPdbFileName, 0))) goto exit;
24442441

24452442
exit:

src/coreclr/ilasm/assembler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,7 @@ class Assembler {
752752
BOOL m_fIsMscorlib;
753753
BOOL m_fTolerateDupMethods;
754754
BOOL m_fOptimize;
755+
BOOL m_fDeterministic;
755756
mdToken m_tkSysObject;
756757
mdToken m_tkSysString;
757758
mdToken m_tkSysValue;
@@ -760,6 +761,7 @@ class Assembler {
760761

761762
IMetaDataDispenserEx2 *m_pDisp;
762763
IMetaDataEmit3 *m_pEmitter;
764+
IMDInternalEmit *m_pInternalEmitForDeterministicMvid;
763765
ICeeFileGen *m_pCeeFileGen;
764766
IMetaDataImport2 *m_pImporter; // Import interface.
765767
HCEEFILE m_pCeeFile;
@@ -845,7 +847,7 @@ class Assembler {
845847
BOOL EmitClass(Class *pClass);
846848
HRESULT CreatePEFile(_In_ __nullterminated WCHAR *pwzOutputFilename);
847849
HRESULT CreateTLSDirectory();
848-
HRESULT CreateDebugDirectory();
850+
HRESULT CreateDebugDirectory(BYTE(&pdbChecksum)[32]);
849851
HRESULT InitMetaData();
850852
Class *FindCreateClass(_In_ __nullterminated const char *pszFQN);
851853
BOOL EmitFieldRef(_In_z_ char *pszArg, int opcode);

src/coreclr/ilasm/main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv)
180180
printf("\n/DEBUG Disable JIT optimization, create PDB file, use sequence points from PDB");
181181
printf("\n/DEBUG=IMPL Disable JIT optimization, create PDB file, use implicit sequence points");
182182
printf("\n/DEBUG=OPT Enable JIT optimization, create PDB file, use implicit sequence points");
183+
printf("\n/DET Produce deterministic outputs");
183184
printf("\n/OPTIMIZE Optimize long instructions to short");
184185
printf("\n/FOLD Fold the identical method bodies into one");
185186
printf("\n/CLOCK Measure and report compilation times");
@@ -316,6 +317,10 @@ extern "C" int _cdecl wmain(int argc, _In_ WCHAR **argv)
316317
{
317318
pAsm->m_fOptimize = TRUE;
318319
}
320+
else if (!_stricmp(szOpt, "DET"))
321+
{
322+
pAsm->m_fDeterministic = TRUE;
323+
}
319324
else if (!_stricmp(szOpt, "X64"))
320325
{
321326
pAsm->m_dwCeeFileFlags &= ~ICEE_CREATE_MACHINE_MASK;

src/coreclr/ilasm/portable_pdb.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "portable_pdb.h"
55
#include <time.h>
66
#include "assembler.h"
7+
#include "sha256.h"
78

89
//*****************************************************************************
910
// Document
@@ -103,6 +104,10 @@ HRESULT PortablePdbWriter::Init(IMetaDataDispenserEx2* mdDispenser)
103104
0,
104105
IID_IMetaDataEmit3,
105106
(IUnknown**)&m_pdbEmitter);
107+
108+
if (FAILED(hr)) goto exit;
109+
110+
hr = m_pdbEmitter->QueryInterface(IID_IILAsmPortablePdbWriter, (void**)&m_ilasmPdbWriter);
106111
exit:
107112
return hr;
108113
}
@@ -122,6 +127,16 @@ ULONG PortablePdbWriter::GetTimestamp()
122127
return m_pdbStream.id.pdbTimeStamp;
123128
}
124129

130+
void PortablePdbWriter::SetGuid(REFGUID newGuid)
131+
{
132+
m_pdbStream.id.pdbGuid = newGuid;
133+
}
134+
135+
void PortablePdbWriter::SetTimestamp(const ULONG newTimestamp)
136+
{
137+
m_pdbStream.id.pdbTimeStamp = newTimestamp;
138+
}
139+
125140
Document* PortablePdbWriter::GetCurrentDocument()
126141
{
127142
return m_currentDocument;
@@ -145,6 +160,17 @@ HRESULT PortablePdbWriter::BuildPdbStream(IMetaDataEmit3* peEmitter, mdMethodDef
145160
return hr;
146161
}
147162

163+
HRESULT PortablePdbWriter::ComputeSha256PdbStreamChecksum(BYTE(&checksum)[32])
164+
{
165+
return m_ilasmPdbWriter->ComputeSha256PdbStreamChecksum(Sha256Hash, checksum);
166+
}
167+
168+
HRESULT PortablePdbWriter::ChangePdbStreamGuid(REFGUID newGuid)
169+
{
170+
m_pdbStream.id.pdbGuid = newGuid;
171+
return m_ilasmPdbWriter->ChangePdbStreamGuid(newGuid);
172+
}
173+
148174
HRESULT PortablePdbWriter::DefineDocument(char* name, GUID* language)
149175
{
150176
HRESULT hr = S_OK;

src/coreclr/ilasm/portable_pdb.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ class PortablePdbWriter
4646
IMetaDataEmit3* GetEmitter();
4747
GUID* GetGuid();
4848
ULONG GetTimestamp();
49+
void SetGuid(REFGUID newGuid);
50+
void SetTimestamp(const ULONG newTimestamp);
4951
Document* GetCurrentDocument();
5052
HRESULT BuildPdbStream(IMetaDataEmit3* peEmitter, mdMethodDef entryPoint);
53+
HRESULT ComputeSha256PdbStreamChecksum(BYTE (&checksum)[32]);
54+
HRESULT ChangePdbStreamGuid(REFGUID newGuid);
5155
HRESULT DefineDocument(char* name, GUID* language);
5256
HRESULT DefineSequencePoints(Method* method);
5357
HRESULT DefineLocalScope(Method* method);
@@ -59,10 +63,11 @@ class PortablePdbWriter
5963
BOOL _DefineLocalScope(mdMethodDef methodDefToken, Scope* currScope);
6064

6165
private:
62-
IMetaDataEmit3* m_pdbEmitter;
63-
PORT_PDB_STREAM m_pdbStream;
64-
DocumentList m_documentList;
65-
Document* m_currentDocument;
66+
IMetaDataEmit3* m_pdbEmitter;
67+
IILAsmPortablePdbWriter* m_ilasmPdbWriter;
68+
PORT_PDB_STREAM m_pdbStream;
69+
DocumentList m_documentList;
70+
Document* m_currentDocument;
6671
};
6772

6873
#endif

0 commit comments

Comments
 (0)