Skip to content

Portable PDB support for ilasm #37702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e9a267a
[WIP] Adding new command line argument to specify desired PDB format
Jun 2, 2020
a3653ba
[WIP] Extending IMetaDataDispenserEx to create a metadata emitter use…
Jun 3, 2020
0798ac4
[WIP] Adding PortablePdbWritter class as a wrapper around emitter use…
Jun 4, 2020
632f0e9
[WIP] Adding methods for setting PDB file name and saving PDB file
Jun 4, 2020
0dd5f9c
[WIP] Updating CreateDebugDirectory method to support portable PDB
Jun 4, 2020
890d8e4
[WIP] Adding PdbStream generation
Jun 8, 2020
34861c6
[WIP] Adding portable PDB table definitions
Jun 8, 2020
9c4ef5a
[WIP] Adding the logic for defining documents
Jun 9, 2020
da35491
[WIP] Adding the logic for defining sequence points
Jun 9, 2020
7b728e9
[WIP] Make sure String heap is never empty for portable PDB metadata …
Jun 9, 2020
bbe7976
[WIP] Adding the logic for defining local scopes and local variables
Jun 10, 2020
c86c8c4
[WIP] Removing line continuation in comments
Jun 10, 2020
466b846
[WIP] Linux build failure fix
Jun 11, 2020
f51d26b
[WIP] Another attempt to fix build issues for different systems
Jun 11, 2020
8a9b16d
[WIP] Proper use of IfFailGo macro for checked build
Jun 12, 2020
b99bdf5
[WIP] Removing inappropriate use of IfFailGo macro
Jun 14, 2020
453d332
[WIP] Introducing new COM interfaces for portable PDB metadata genera…
Jun 16, 2020
69e20d6
[WIP] Surrounding all portable PDB metadata changes with FEATURE_META…
Jun 16, 2020
5ff964e
[WIP] Enabling only ilasm to use portable PDB metadata generation
Jun 17, 2020
586e52d
[WIP] Fix for UNIX paths when defining documents
Jun 26, 2020
0393d6f
[WIP] Fix for local scope generation
Jul 2, 2020
4aea292
[WIP] Adding functional tests for ilasm portable PDB support
Jul 2, 2020
a8c2649
[WIP] Spelling out PORTABLE correctly in preprocessor directive contr…
Jul 6, 2020
9c9b3f5
[WIP] Typo: Naming PortablePdbWriter instead of PortablePdbWritter
Jul 6, 2020
a164156
[WIP] Clarifying command line parameters for pdb format by using thei…
Jul 6, 2020
89c8519
[WIP] Removing dependency on layout verification from all mdcompiler …
Jul 8, 2020
ecc437a
Merge branch 'master' into ilasm_portable_pdb
ivanpovazan Jul 8, 2020
c92c8ec
[WIP] Simplifying the makefile for building mdcompiler_wks library
Jul 8, 2020
703266f
[WIP] Moving ilasm portable PDB tests to a new location to make them …
Jul 8, 2020
c348528
Merge branch 'master' into ilasm_portable_pdb
Jul 10, 2020
5791a51
Merge branch 'master' into ilasm_portable_pdb
Jul 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/coreclr/src/ilasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_definitions(-DUNICODE)
add_definitions(-D_UNICODE)
add_definitions(-D_FEATURE_NO_HOST)
add_definitions(-D__ILASM__)
add_definitions(-DFEATURE_METADATA_EMIT_PORTABLE_PDB)

add_definitions(-DFEATURE_CORECLR)

Expand All @@ -18,6 +19,7 @@ set(ILASM_SOURCES
main.cpp
assembler.cpp
prebuilt/asmparse.cpp
portable_pdb.cpp
)

set(ILASM_HEADERS
Expand All @@ -32,6 +34,7 @@ set(ILASM_HEADERS
method.hpp
nvpair.h
typar.hpp
portable_pdb.h
)

if(CLR_CMAKE_TARGET_WIN32)
Expand Down Expand Up @@ -72,11 +75,11 @@ set(ILASM_LINK_LIBRARIES
utilcodestaticnohost
mscorpe
${START_LIBRARY_GROUP} # Start group of libraries that have circular references
mdhotdata_full
mdcompiler_wks
mdruntime_wks
mdruntimerw_wks
mdstaticapi
mdhotdata_ppdb
mdcompiler_ppdb
mdruntime_ppdb
mdruntimerw_ppdb
mdstaticapi_ppdb
${END_LIBRARY_GROUP} # End group of libraries that have circular references
ceefgen
corguids
Expand Down
113 changes: 67 additions & 46 deletions src/coreclr/src/ilasm/assem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ Assembler::Assembler()

dummyClass = new Class(NULL);
indexKeywords(&indxKeywords);

m_pdbFormat = CLASSIC;
m_pPortablePdbWriter = NULL;
}


Expand Down Expand Up @@ -218,7 +221,11 @@ Assembler::~Assembler()
m_pEmitter->Release();
m_pEmitter = NULL;
}

if (m_pPortablePdbWriter != NULL)
{
delete m_pPortablePdbWriter;
m_pPortablePdbWriter = NULL;
}
if (m_pDisp != NULL)
{
m_pDisp->Release();
Expand All @@ -227,7 +234,7 @@ Assembler::~Assembler()
}


BOOL Assembler::Init()
BOOL Assembler::Init(BOOL generatePdb, PdbFormat pdbFormat)
{
if (m_pCeeFileGen != NULL) {
if (m_pCeeFile)
Expand All @@ -246,6 +253,9 @@ BOOL Assembler::Init()
if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".sdata", sdReadWrite, &m_pGlobalDataSection))) return FALSE;
if (FAILED(m_pCeeFileGen->GetSectionCreate (m_pCeeFile, ".tls", sdReadWrite, &m_pTLSSection))) return FALSE;

m_fGeneratePDB = generatePdb;
m_pdbFormat = pdbFormat;

return TRUE;
}

Expand Down Expand Up @@ -468,6 +478,8 @@ BOOL Assembler::AddMethod(Method *pMethod)

BOOL Assembler::EmitMethodBody(Method* pMethod, BinStr* pbsOut)
{
HRESULT hr = S_OK;

if(pMethod)
{
BinStr* pbsBody = pMethod->m_pbsBody;
Expand All @@ -483,7 +495,6 @@ BOOL Assembler::EmitMethodBody(Method* pMethod, BinStr* pbsOut)
VarDescr* pVD;
BinStr* pbsSig = new BinStr();
unsigned cnt;
HRESULT hr;
DWORD cSig;
const COR_SIGNATURE* mySig;

Expand Down Expand Up @@ -514,57 +525,67 @@ BOOL Assembler::EmitMethodBody(Method* pMethod, BinStr* pbsOut)
pFH->SetLocalVarSigTok(pMethod->m_LocalsSig);
}
//--------------------------------------------------------------------------------
if(m_fGeneratePDB && (m_pSymWriter != NULL))
if(m_fGeneratePDB)
{
m_pSymWriter->OpenMethod(pMethod->m_Tok);
ULONG N = pMethod->m_LinePCList.COUNT();
if(pMethod->m_fEntryPoint) m_pSymWriter->SetUserEntryPoint(pMethod->m_Tok);
if(N)
if (m_pSymWriter != NULL)
{
LinePC *pLPC;
ULONG32 *offsets=new ULONG32[N], *lines = new ULONG32[N], *columns = new ULONG32[N];
ULONG32 *endlines=new ULONG32[N], *endcolumns=new ULONG32[N];
if(offsets && lines && columns && endlines && endcolumns)
m_pSymWriter->OpenMethod(pMethod->m_Tok);
ULONG N = pMethod->m_LinePCList.COUNT();
if(pMethod->m_fEntryPoint) m_pSymWriter->SetUserEntryPoint(pMethod->m_Tok);
if(N)
{
DocWriter* pDW;
unsigned j=0;
while((pDW = m_DocWriterList.PEEK(j++)))
LinePC *pLPC;
ULONG32 *offsets=new ULONG32[N], *lines = new ULONG32[N], *columns = new ULONG32[N];
ULONG32 *endlines=new ULONG32[N], *endcolumns=new ULONG32[N];
if(offsets && lines && columns && endlines && endcolumns)
{
if((m_pSymDocument = pDW->pWriter))
DocWriter* pDW;
unsigned j=0;
while((pDW = m_DocWriterList.PEEK(j++)))
{
int i, n;
for(i=0, n=0; (pLPC = pMethod->m_LinePCList.PEEK(i)); i++)
if((m_pSymDocument = pDW->pWriter))
{
if(pLPC->pWriter == m_pSymDocument)
int i, n;
for(i=0, n=0; (pLPC = pMethod->m_LinePCList.PEEK(i)); i++)
{
offsets[n] = pLPC->PC;
lines[n] = pLPC->Line;
columns[n] = pLPC->Column;
endlines[n] = pLPC->LineEnd;
endcolumns[n] = pLPC->ColumnEnd;
n++;
if(pLPC->pWriter == m_pSymDocument)
{
offsets[n] = pLPC->PC;
lines[n] = pLPC->Line;
columns[n] = pLPC->Column;
endlines[n] = pLPC->LineEnd;
endcolumns[n] = pLPC->ColumnEnd;
n++;
}
}
}
if(n) m_pSymWriter->DefineSequencePoints(m_pSymDocument,n,
offsets,lines,columns,endlines,endcolumns);
} // end if(pSymDocument)
} // end while(pDW = next doc.writer)
pMethod->m_LinePCList.RESET(true);
}
else report->error("\nOutOfMemory!\n");
delete [] offsets;
delete [] lines;
delete [] columns;
delete [] endlines;
delete [] endcolumns;
}//enf if(N)
HRESULT hrr;
if(pMethod->m_ulLines[1])
hrr = m_pSymWriter->SetMethodSourceRange(m_pSymDocument,pMethod->m_ulLines[0], pMethod->m_ulColumns[0],
m_pSymDocument,pMethod->m_ulLines[1], pMethod->m_ulColumns[1]);
EmitScope(&(pMethod->m_MainScope)); // recursively emits all nested scopes

m_pSymWriter->CloseMethod();
if(n) m_pSymWriter->DefineSequencePoints(m_pSymDocument,n,
offsets,lines,columns,endlines,endcolumns);
} // end if(pSymDocument)
} // end while(pDW = next doc.writer)
pMethod->m_LinePCList.RESET(true);
}
else report->error("\nOutOfMemory!\n");
delete [] offsets;
delete [] lines;
delete [] columns;
delete [] endlines;
delete [] endcolumns;
}//enf if(N)
HRESULT hrr;
if(pMethod->m_ulLines[1])
hrr = m_pSymWriter->SetMethodSourceRange(m_pSymDocument,pMethod->m_ulLines[0], pMethod->m_ulColumns[0],
m_pSymDocument,pMethod->m_ulLines[1], pMethod->m_ulColumns[1]);
EmitScope(&(pMethod->m_MainScope)); // recursively emits all nested scopes

m_pSymWriter->CloseMethod();
}
else if (IsPortablePdb())
{
if (FAILED(m_pPortablePdbWriter->DefineSequencePoints(pMethod)))
return FALSE;
if (FAILED(m_pPortablePdbWriter->DefineLocalScope(pMethod)))
return FALSE;
}
} // end if(fIncludeDebugInfo)
//-----------------------------------------------------

Expand Down
106 changes: 82 additions & 24 deletions src/coreclr/src/ilasm/assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,20 @@ void Assembler::EmitOpcode(Instr* instr)
pLPC->ColumnEnd = instr->column_end;
pLPC->PC = m_CurPC;
pLPC->pWriter = instr->pWriter;

pLPC->pOwnerDocument = instr->pOwnerDocument;
if (0xfeefee == instr->linenum &&
0xfeefee == instr->linenum_end &&
0 == instr->column &&
0 == instr->column_end)
{
pLPC->IsHidden = TRUE;
}
else
{
pLPC->IsHidden = FALSE;
}

m_pCurMethod->m_LinePCList.PUSH(pLPC);
}
else report->error("\nOut of memory!\n");
Expand Down Expand Up @@ -2375,40 +2389,51 @@ void Assembler::SetSourceFileName(__in __nullterminated char* szName)
}
if(m_fGeneratePDB)
{
DocWriter* pDW;
unsigned i=0;
while((pDW = m_DocWriterList.PEEK(i++)) != NULL)
{
if(!strcmp(szName,pDW->Name)) break;
}
if(pDW)
if (IsPortablePdb())
{
m_pSymDocument = pDW->pWriter;
delete [] szName;
if (FAILED(m_pPortablePdbWriter->DefineDocument(szName, &m_guidLang)))
{
report->error("Failed to define a document: '%s'", szName);
}
delete[] szName;
}
else if(m_pSymWriter)
else
{
HRESULT hr;
WszMultiByteToWideChar(g_uCodePage,0,szName,-1,wzUniBuf,dwUniBuf);
if(FAILED(hr=m_pSymWriter->DefineDocument(wzUniBuf,&m_guidLang,
&m_guidLangVendor,&m_guidDoc,&m_pSymDocument)))
DocWriter* pDW;
unsigned i = 0;
while ((pDW = m_DocWriterList.PEEK(i++)) != NULL)
{
m_pSymDocument = NULL;
report->error("Failed to define a document writer");
if (!strcmp(szName, pDW->Name)) break;
}
if((pDW = new DocWriter()) != NULL)
if (pDW)
{
pDW->Name = szName;
pDW->pWriter = m_pSymDocument;
m_DocWriterList.PUSH(pDW);
m_pSymDocument = pDW->pWriter;
delete[] szName;
}
else
else if (m_pSymWriter)
{
report->error("Out of memory");
delete [] szName;
HRESULT hr;
WszMultiByteToWideChar(g_uCodePage, 0, szName, -1, wzUniBuf, dwUniBuf);
if (FAILED(hr = m_pSymWriter->DefineDocument(wzUniBuf, &m_guidLang,
&m_guidLangVendor, &m_guidDoc, &m_pSymDocument)))
{
m_pSymDocument = NULL;
report->error("Failed to define a document writer");
}
if ((pDW = new DocWriter()) != NULL)
{
pDW->Name = szName;
pDW->pWriter = m_pSymDocument;
m_DocWriterList.PUSH(pDW);
}
else
{
report->error("Out of memory");
delete[] szName;
}
}
else delete[] szName;
}
else delete [] szName;
}
else delete [] szName;
}
Expand All @@ -2428,6 +2453,39 @@ void Assembler::SetSourceFileName(BinStr* pbsName)
}
}

// Portable PDB paraphernalia
void Assembler::SetPdbFileName(__in __nullterminated char* szName)
{
if (szName)
{
if (*szName)
{
strcpy_s(m_szPdbFileName, MAX_FILENAME_LENGTH * 3 + 1, szName);
WszMultiByteToWideChar(g_uCodePage, 0, szName, -1, m_wzPdbFileName, MAX_FILENAME_LENGTH);
}
}
}
HRESULT Assembler::SavePdbFile()
{
HRESULT hr = S_OK;
mdMethodDef entryPoint;

if (m_pdbFormat == PORTABLE)
{
if (FAILED(hr = (m_pPortablePdbWriter == NULL ? E_FAIL : S_OK))) goto exit;
if (FAILED(hr = (m_pPortablePdbWriter->GetEmitter() == NULL ? E_FAIL : S_OK))) goto exit;
if (FAILED(hr = m_pCeeFileGen->GetEntryPoint(m_pCeeFile, &entryPoint))) goto exit;
if (FAILED(hr = m_pPortablePdbWriter->BuildPdbStream(m_pEmitter, entryPoint))) goto exit;
if (FAILED(hr = m_pPortablePdbWriter->GetEmitter()->Save(m_wzPdbFileName, NULL))) goto exit;
}
exit:
return hr;
}
BOOL Assembler::IsPortablePdb()
{
return (m_pdbFormat == PORTABLE) && (m_pPortablePdbWriter != NULL);
}

void Assembler::RecordTypeConstraints(GenericParamConstraintList* pGPCList, int numTyPars, TyParDescr* tyPars)
{
if (numTyPars > 0)
Expand Down
Loading