1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
9 // Zapping of soft bound references to elements outside the current module
11 // ======================================================================================
15 #include "zapimport.h"
17 #include "nibblestream.h"
18 #include "sigbuilder.h"
20 #if defined(FEATURE_READYTORUN_COMPILER)
21 // A flag to indicate that a helper call uses VSD
22 const DWORD READYTORUN_HELPER_FLAG_VSD = 0x10000000;
29 void ZapImportTable::Save(ZapWriter * pZapWriter)
31 for (COUNT_T i = 0; i < m_modules.GetCount(); i++)
33 ModuleReferenceEntry * pModuleReference = m_modules[i];
34 _ASSERTE(pModuleReference != NULL);
36 CORCOMPILE_IMPORT_TABLE_ENTRY entry;
38 entry.wAssemblyRid = pModuleReference->m_wAssemblyRid;
39 entry.wModuleRid = pModuleReference->m_wModuleRid;
41 pZapWriter->Write(&entry, sizeof(entry));
45 ZapImportTable::ModuleReferenceEntry * ZapImportTable::GetModuleReference(CORINFO_MODULE_HANDLE handle)
47 ModuleReferenceEntry * pEntry = m_moduleReferences.Lookup(handle);
52 if (!GetCompileInfo()->IsInCurrentVersionBubble(handle))
54 // FUTURE TODO: Version resilience
55 _ASSERTE(!"Invalid reference to module outside of current version bubble");
59 pEntry = new (m_pImage->GetHeap()) ModuleReferenceEntry();
60 pEntry->m_module = handle;
62 DWORD assemblyIndex = 0;
63 DWORD moduleIndex = 0;
64 GetCompileInfo()->EncodeModuleAsIndexes(m_pImage->GetModuleHandle(), handle,
65 &assemblyIndex, &moduleIndex,
66 m_pImage->GetAssemblyEmit());
67 _ASSERTE(assemblyIndex <= USHRT_MAX);
68 _ASSERTE(moduleIndex <= USHRT_MAX);
69 pEntry->m_wAssemblyRid = (USHORT) assemblyIndex;
70 pEntry->m_wModuleRid = (USHORT) moduleIndex;
72 pEntry->m_index = m_modules.GetCount();
73 m_modules.Append(pEntry);
75 m_moduleReferences.Add(pEntry);
80 ZapBlob * ZapImportTable::GetBlob(SigBuilder * pSigBuilder, BOOL fEager)
83 PVOID pSignature = pSigBuilder->GetSignature(&cbBlob);
87 // Use dedicated section for blobs of eager fixups
88 return ZapBlob::NewBlob(m_pImage, pSignature, cbBlob);
91 ZapBlob * pBlob = m_blobs.Lookup(ZapBlob::SHashKey(pSignature, cbBlob));
95 pBlob = ZapBlob::NewBlob(m_pImage, pSignature, cbBlob);
103 ZapBlob * ZapImportTable::PlaceImportBlob(ZapImport * pImport, BOOL fEager)
106 if (pImport->HasBlob())
108 pBlob = pImport->GetBlob();
112 SigBuilder sigBuilder;
113 pImport->EncodeSignature(this, &sigBuilder);
115 pBlob = GetBlob(&sigBuilder, fEager);
117 pImport->SetBlob(pBlob);
120 if (!pBlob->IsPlaced())
121 PlaceBlob(pBlob, fEager);
126 static const struct ImportSectionProperties
132 c_ImportSectionProperties[ZapImportSectionType_Count] =
134 { /* ZapImportSectionType_Handle, */ CORCOMPILE_IMPORT_TYPE_UNKNOWN, 0, 0 },
135 { /* ZapImportSectionType_TypeHandle, */ CORCOMPILE_IMPORT_TYPE_TYPE_HANDLE, sizeof(TADDR), 0 },
136 { /* ZapImportSectionType_MethodHandle, */ CORCOMPILE_IMPORT_TYPE_METHOD_HANDLE, sizeof(TADDR), 0 },
138 { /* ZapImportSectionType_PCode, */ CORCOMPILE_IMPORT_TYPE_UNKNOWN, 0, CORCOMPILE_IMPORT_FLAGS_PCODE },
140 { /* ZapImportSectionType_StringHandle, */ CORCOMPILE_IMPORT_TYPE_STRING_HANDLE, sizeof(TADDR), 0 },
143 void ZapImportTable::PlaceImport(ZapImport * pImport)
145 BOOL fIsEager, fNeedsSignature;
146 ZapImportSectionType table = pImport->ComputePlacement(m_pImage, &fIsEager, &fNeedsSignature);
150 table = ZapImportSectionType_Eager;
153 if (!m_pImage->IsCurrentCodeRegionHot())
155 table = (ZapImportSectionType)(table + ZapImportSectionType_Cold);
158 _ASSERTE(table < ZapImportSectionType_Total);
163 PlaceImportBlob(pImport, fIsEager);
166 ZapVirtualSection * pVirtualSection = m_pImage->m_pDelayLoadInfoTableSection[table];
168 if (m_nImportSectionSizes[table] == 0)
170 const ImportSectionProperties * pProps = &c_ImportSectionProperties[table % ZapImportSectionType_Count];
172 WORD flags = pProps->Flags;
175 flags |= CORCOMPILE_IMPORT_FLAGS_EAGER;
177 m_nImportSectionIndices[table] = m_pImage->GetImportSectionsTable()->Append(pProps->Type, flags, pProps->EntrySize,
178 pVirtualSection, m_pImage->m_pDelayLoadInfoDataTable[table]);
181 pImport->SetSectionIndexAndOffset(m_nImportSectionIndices[table], m_nImportSectionSizes[table]);
183 pVirtualSection->Place(pImport);
185 m_nImportSectionSizes[table] += pImport->GetSize();
188 // Sort ZapImport* by CorCompileTokenTable as primary key and offset within the table as secondary key
189 static int __cdecl fixupCmp(const void* a_, const void* b_)
191 ZapImport *a = *(ZapImport **)a_;
192 ZapImport *b = *(ZapImport **)b_;
194 int tableDiff = a->GetSectionIndex() - b->GetSectionIndex();
198 // Sort by offset within the table
199 return (a->GetOffset() - b->GetOffset());
202 void ZapImportTable::PlaceFixups(ZapImport ** pImports, NibbleWriter& writer)
204 COUNT_T nImports = 0;
208 ZapImport * pImport = pImports[nImports];
209 if (pImport == NULL) // end of the list
211 if (!pImport->IsPlaced())
212 PlaceImport(pImport);
216 qsort(pImports, nImports, sizeof(ZapImport *), fixupCmp);
219 // Build the encoded fixup list
222 int curTableIndex = -1;
225 for (COUNT_T iImport = 0; iImport < nImports; iImport++)
227 ZapImport * pImport = pImports[iImport];
229 int tableIndex = pImport->GetSectionIndex();
230 unsigned offset = pImport->GetOffset();
232 _ASSERTE(offset % sizeof(SIZE_T) == 0);
233 offset /= sizeof(SIZE_T);
235 if (tableIndex != curTableIndex)
237 // Write delta relative to the previous table index
238 _ASSERTE(tableIndex > curTableIndex);
239 if (curTableIndex != -1)
241 writer.WriteEncodedU32(0); // table separator, so add except for the first entry
242 writer.WriteEncodedU32(tableIndex - curTableIndex); // add table index delta
246 writer.WriteEncodedU32(tableIndex);
248 curTableIndex = tableIndex;
250 // This is the first fixup in the current table.
251 // We will write it out completely (without delta-encoding)
252 writer.WriteEncodedU32(offset);
256 // This is not the first entry in the current table.
257 // We will write out the delta relative to the previous fixup value
258 int delta = offset - curOffset;
260 writer.WriteEncodedU32(delta);
263 // future entries for this table would be relative to this rva
267 writer.WriteEncodedU32(0); // table separator
268 writer.WriteEncodedU32(0); // fixup list ends
273 ZapFixupInfo * ZapImportTable::PlaceFixups(ZapImport ** pImports)
277 PlaceFixups(pImports, writer);
280 PVOID pBlob = writer.GetBlob(&cbBlob);
283 // Intern the fixup info
286 ZapFixupInfo * pFixupInfo = m_blobs.Lookup(ZapBlob::SHashKey(pBlob, cbBlob));
288 if (pFixupInfo == NULL)
290 // Fixup infos are mixed with other blobs
291 pFixupInfo = ZapBlob::NewBlob(m_pImage, pBlob, cbBlob);
292 m_blobs.Add(pFixupInfo);
295 if (!pFixupInfo->IsPlaced())
296 PlaceBlob(pFixupInfo);
301 void ZapImportTable::PlaceBlob(ZapBlob * pBlob, BOOL fEager)
303 ZapVirtualSection * pSection;
305 pSection = m_pImage->m_pDelayLoadInfoDelayListSectionEager;
307 if (m_pImage->IsCurrentCodeRegionHot())
308 pSection = m_pImage->m_pDelayLoadInfoDelayListSectionHot;
310 pSection = m_pImage->m_pDelayLoadInfoDelayListSectionCold;
311 pSection->Place(pBlob);
314 // ======================================================================================
316 // Generic signatures
318 ZapGenericSignature * ZapImportTable::GetGenericSignature(PVOID signature, BOOL fMethod)
324 SigBuilder sigBuilder;
325 GetCompileInfo()->EncodeGenericSignature(signature, fMethod, &sigBuilder, this, EncodeModuleHelper);
328 PVOID pSig = sigBuilder.GetSignature(&cbSig);
330 ZapGenericSignature * pGenericSignature = (ZapGenericSignature *)m_genericSignatures.Lookup(ZapBlob::SHashKey(pSig, cbSig));
332 if (pGenericSignature != NULL)
333 return pGenericSignature;
335 S_SIZE_T cbAllocSize = S_SIZE_T(sizeof(ZapGenericSignature)) + S_SIZE_T(cbSig);
337 if (cbAllocSize.IsOverflow())
338 ThrowHR(COR_E_OVERFLOW);
340 void * pMemory = new (m_pImage->GetHeap()) BYTE[cbAllocSize.Value()];
342 pGenericSignature = new (pMemory) ZapGenericSignature(cbSig);
343 memcpy((void *)(pGenericSignature + 1), pSig, cbSig);
345 m_genericSignatures.Add(pGenericSignature);
347 return pGenericSignature;
351 // At ngen time Zapper::CompileModule PlaceFixups called from
352 // code:ZapSig.GetSignatureForTypeHandle
354 /*static*/ DWORD ZapImportTable::EncodeModuleHelper( LPVOID compileContext,
355 CORINFO_MODULE_HANDLE referencedModule)
357 ZapImportTable * pTable = (ZapImportTable *)compileContext;
358 return pTable->GetIndexOfModule(referencedModule);
361 void ZapImport::Save(ZapWriter * pZapWriter)
363 if (IsReadyToRunCompilation())
366 pZapWriter->Write(&value, sizeof(value));
370 SIZE_T token = CORCOMPILE_TAG_TOKEN(GetBlob()->GetRVA());
371 pZapWriter->Write(&token, sizeof(token));
375 // CORCOMPILE_CODE_IMPORT_SECTION
378 COUNT_T ZapImportSectionsTable::Append(BYTE Type, USHORT Flags, BYTE EntrySize, ZapVirtualSection * pSection, ZapNode * pSignatures, ZapNode * pAuxiliaryData)
382 entry.m_pSection = pSection;
383 entry.m_pSignatures = pSignatures;
384 entry.m_pAuxiliaryData = pAuxiliaryData;
385 entry.m_Flags = Flags;
387 entry.m_EntrySize = EntrySize;
389 m_ImportSectionsTable.Append(entry);
391 return m_ImportSectionsTable.GetCount() - 1;
394 DWORD ZapImportSectionsTable::GetSize()
396 return m_ImportSectionsTable.GetCount() * sizeof(CORCOMPILE_IMPORT_SECTION);
399 void ZapImportSectionsTable::Save(ZapWriter * pZapWriter)
401 COUNT_T nSections = m_ImportSectionsTable.GetCount();
402 for (COUNT_T iSection = 0; iSection < nSections; iSection++)
404 ImportSection * p = &m_ImportSectionsTable[iSection];
406 CORCOMPILE_IMPORT_SECTION entry;
408 ZapWriter::SetDirectoryData(&entry.Section, p->m_pSection);
410 entry.Flags = p->m_Flags;
411 entry.Type = p->m_Type;
412 entry.EntrySize = p->m_EntrySize;
414 entry.Signatures = (p->m_pSignatures != NULL) ? p->m_pSignatures->GetRVA() : NULL;
415 entry.AuxiliaryData = (p->m_pAuxiliaryData != NULL) ? p->m_pAuxiliaryData->GetRVA() : NULL;
417 pZapWriter->Write(&entry, sizeof(entry));
422 ZapImportSectionSignatures::ZapImportSectionSignatures(ZapImage * pImage, ZapVirtualSection * pImportSection, ZapVirtualSection * pGCSection)
423 : m_pImportSection(pImportSection), m_pImage(pImage)
425 if (pGCSection != NULL)
427 m_pGCRefMapTable = new (pImage->GetHeap()) ZapGCRefMapTable(pImage);
428 pGCSection->Place(m_pGCRefMapTable);
432 ZapImportSectionSignatures::~ZapImportSectionSignatures()
434 if (m_pGCRefMapTable != NULL)
435 m_pGCRefMapTable->~ZapGCRefMapTable();
438 DWORD ZapImportSectionSignatures::GetSize()
440 return m_pImportSection->GetNodeCount() * sizeof(DWORD);
443 void ZapImportSectionSignatures::Save(ZapWriter * pZapWriter)
445 COUNT_T nCount = m_pImportSection->GetNodeCount();
446 for (COUNT_T i = 0; i < nCount; i++)
448 ZapNode * pNode = m_pImportSection->GetNode(i);
449 DWORD dwRVA = ((ZapImport *)pNode)->GetBlob()->GetRVA();
450 pZapWriter->Write(&dwRVA, sizeof(dwRVA));
454 // ======================================================================================
456 // Special lazy imports for lazily resolved method calls
460 // External method thunk is a patchable thunk used for cross-module direct calls
462 class ZapExternalMethodThunk : public ZapImport
465 ZapExternalMethodThunk()
469 CORINFO_METHOD_HANDLE GetMethod()
471 return (CORINFO_METHOD_HANDLE)GetHandle();
474 virtual DWORD GetSize()
476 return sizeof(CORCOMPILE_EXTERNAL_METHOD_THUNK);
479 virtual ZapNodeType GetType()
481 return ZapNodeType_ExternalMethodThunk;
484 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
486 CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)GetHandle();
488 CORINFO_MODULE_HANDLE referencingModule;
489 mdToken token = pTable->GetCompileInfo()->TryEncodeMethodAsToken(handle, NULL, &referencingModule);
490 if (token != mdTokenNil)
492 _ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
494 pTable->EncodeModule(
495 (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
496 referencingModule, pSigBuilder);
498 pSigBuilder->AppendData(RidFromToken(token));
502 pTable->EncodeMethod(ENCODE_METHOD_ENTRY, handle, pSigBuilder);
506 virtual void Save(ZapWriter * pZapWriter);
509 void ZapExternalMethodThunk::Save(ZapWriter * pZapWriter)
511 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
512 ZapNode * helper = pImage->GetHelperThunk(CORINFO_HELP_EE_EXTERNAL_FIXUP);
514 CORCOMPILE_EXTERNAL_METHOD_THUNK thunk;
515 memset(&thunk, DEFAULT_CODE_BUFFER_INIT, sizeof(thunk));
516 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
517 thunk.callJmp[0] = 0xE8; // call rel32
518 pImage->WriteReloc(&thunk, 1, helper, 0, IMAGE_REL_BASED_REL32);
519 thunk.precodeType = _PRECODE_EXTERNAL_METHOD_THUNK;
520 #elif defined(_TARGET_ARM_)
521 // Setup the call to ExternalMethodFixupStub
525 // Per ARM architecture reference manual section A2.3,
526 // reading the value of PC register will read the address
527 // of the current instruction plus 4. In this case,
528 // R12 will containing the address of "F004" below once
529 // the "mov" is executed.
531 // Since this is 4 bytes ahead of the start of the thunk,
532 // the assembly helper we will call into will adjust this
533 // so that we point to the start of the thunk correctly.
534 thunk.m_rgCode[0] = 0x46fc;
537 thunk.m_rgCode[1] = 0xf8df;
538 thunk.m_rgCode[2] = 0xf004;
540 // Setup the initial target to be our assembly helper.
541 pImage->WriteReloc(&thunk, offsetof(CORCOMPILE_EXTERNAL_METHOD_THUNK, m_pTarget), helper, 0, IMAGE_REL_BASED_PTR);
542 #elif defined(_TARGET_ARM64_)
544 thunk.m_rgCode[0] = 0x1000000C; //adr x12, #0
545 thunk.m_rgCode[1] = 0xF940098A; //ldr x10, [x12, #16]
546 thunk.m_rgCode[2] = 0xD61F0140; //br x10
548 pImage->WriteReloc(&thunk, offsetof(CORCOMPILE_EXTERNAL_METHOD_THUNK, m_pTarget), helper, 0, IMAGE_REL_BASED_PTR);
550 PORTABILITY_ASSERT("ZapExternalMethodThunk::Save");
554 pZapWriter->Write(&thunk, sizeof(thunk));
555 _ASSERTE(sizeof(thunk) == GetSize());
558 void ZapImportSectionSignatures::PlaceExternalMethodThunk(ZapImport * pImport)
560 ZapExternalMethodThunk * pThunk = (ZapExternalMethodThunk *)pImport;
562 if (m_pImportSection->GetNodeCount() == 0)
564 m_dwIndex = m_pImage->GetImportSectionsTable()->Append(CORCOMPILE_IMPORT_TYPE_EXTERNAL_METHOD, CORCOMPILE_IMPORT_FLAGS_CODE,
565 sizeof(CORCOMPILE_EXTERNAL_METHOD_THUNK), m_pImportSection, this, m_pGCRefMapTable);
567 // Make sure the helper created
568 m_pImage->GetHelperThunk(CORINFO_HELP_EE_EXTERNAL_FIXUP);
571 // Add entry to both the the cell and data sections
572 m_pImportSection->Place(pThunk);
574 m_pImage->GetImportTable()->PlaceImportBlob(pThunk);
576 m_pGCRefMapTable->Append(pThunk->GetMethod());
579 ZapImport * ZapImportTable::GetExternalMethodThunk(CORINFO_METHOD_HANDLE handle)
581 return GetImport<ZapExternalMethodThunk, ZapNodeType_ExternalMethodThunk>((PVOID)handle);
585 // Stub dispatch cell is lazily initialized indirection used for virtual stub dispatch
587 class ZapStubDispatchCell : public ZapImport
589 ZapNode * m_pDelayLoadHelper;
592 void SetDelayLoadHelper(ZapNode * pDelayLoadHelper)
594 _ASSERTE(m_pDelayLoadHelper == NULL);
595 m_pDelayLoadHelper = pDelayLoadHelper;
598 CORINFO_METHOD_HANDLE GetMethod()
600 return (CORINFO_METHOD_HANDLE)GetHandle();
603 CORINFO_CLASS_HANDLE GetClass()
605 return (CORINFO_CLASS_HANDLE)GetHandle2();
608 virtual DWORD GetSize()
610 return sizeof(TADDR);
613 virtual UINT GetAlignment()
615 return sizeof(TADDR);
618 virtual ZapNodeType GetType()
620 return ZapNodeType_StubDispatchCell;
623 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
625 CORINFO_MODULE_HANDLE referencingModule = pTable->GetJitInfo()->getClassModule(GetClass());
626 referencingModule = pTable->TryEncodeModule(ENCODE_VIRTUAL_ENTRY_SLOT, referencingModule, pSigBuilder);
628 DWORD slot = pTable->GetCompileInfo()->TryEncodeMethodSlot(GetMethod());
630 // We expect the encoding to always succeed
631 _ASSERTE(slot != (DWORD)-1);
633 pSigBuilder->AppendData(slot);
635 pTable->EncodeClassInContext(referencingModule, GetClass(), pSigBuilder);
638 virtual void Save(ZapWriter * pZapWriter)
640 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
643 pImage->WriteReloc(&cell, 0, m_pDelayLoadHelper, 0, IMAGE_REL_BASED_PTR);
644 pZapWriter->Write(&cell, sizeof(cell));
648 ZapImport * ZapImportTable::GetStubDispatchCell(CORINFO_CLASS_HANDLE typeHnd, CORINFO_METHOD_HANDLE methHnd)
650 // Do not intern stub dispatch imports. Each callsite should get own cell.
651 ZapImport * pImport = new (m_pImage->GetHeap()) ZapStubDispatchCell();
652 pImport->SetHandle(methHnd);
653 pImport->SetHandle2(typeHnd);
657 void ZapImportSectionSignatures::PlaceStubDispatchCell(ZapImport * pImport)
659 ZapStubDispatchCell * pCell = (ZapStubDispatchCell *)pImport;
661 if (m_pImportSection->GetNodeCount() == 0)
663 m_dwIndex = m_pImage->GetImportSectionsTable()->Append(CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH, CORCOMPILE_IMPORT_FLAGS_PCODE,
664 sizeof(TADDR), m_pImportSection, this, m_pGCRefMapTable);
667 #ifdef FEATURE_READYTORUN_COMPILER
668 if (IsReadyToRunCompilation())
670 // Create the delay load helper
671 ReadyToRunHelper helper = (ReadyToRunHelper)(READYTORUN_HELPER_DelayLoad_MethodCall | READYTORUN_HELPER_FLAG_VSD);
672 ZapNode * pDelayLoadHelper = m_pImage->GetImportTable()->GetPlacedIndirectHelperThunk(helper, (PVOID)(SIZE_T)m_dwIndex);
673 pCell->SetDelayLoadHelper(pDelayLoadHelper);
678 pCell->SetDelayLoadHelper(m_pImage->GetHelperThunk(CORINFO_HELP_EE_VSD_FIXUP));
681 // Add entry to both the cell and data sections
682 m_pImportSection->Place(pCell);
684 m_pImage->GetImportTable()->PlaceImportBlob(pCell);
686 m_pGCRefMapTable->Append(pCell->GetMethod());
690 // External method cell is lazily initialized indirection used for method calls
692 class ZapExternalMethodCell : public ZapImport
694 ZapNode * m_pDelayLoadHelper;
697 void SetDelayLoadHelper(ZapNode * pDelayLoadHelper)
699 _ASSERTE(m_pDelayLoadHelper == NULL);
700 m_pDelayLoadHelper = pDelayLoadHelper;
702 CORINFO_METHOD_HANDLE GetMethod()
704 return (CORINFO_METHOD_HANDLE)GetHandle();
707 virtual DWORD GetSize()
709 return sizeof(TADDR);
712 virtual UINT GetAlignment()
714 return sizeof(TADDR);
717 virtual ZapNodeType GetType()
719 return ZapNodeType_ExternalMethodCell;
722 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
724 CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)GetHandle();
726 CORINFO_MODULE_HANDLE referencingModule;
727 mdToken token = pTable->GetCompileInfo()->TryEncodeMethodAsToken(handle, NULL, &referencingModule);
728 if (token != mdTokenNil)
730 _ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
732 pTable->EncodeModule(
733 (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
734 referencingModule, pSigBuilder);
736 pSigBuilder->AppendData(RidFromToken(token));
740 pTable->EncodeMethod(ENCODE_METHOD_ENTRY, handle, pSigBuilder);
744 virtual void Save(ZapWriter * pZapWriter)
746 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
749 pImage->WriteReloc(&cell, 0, m_pDelayLoadHelper, 0, IMAGE_REL_BASED_PTR);
750 pZapWriter->Write(&cell, sizeof(cell));
754 ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle)
756 return GetImport<ZapExternalMethodCell, ZapNodeType_ExternalMethodCell>((PVOID)handle);
759 void ZapImportSectionSignatures::PlaceExternalMethodCell(ZapImport * pImport)
761 ZapExternalMethodCell * pCell = (ZapExternalMethodCell *)pImport;
763 if (m_pImportSection->GetNodeCount() == 0)
765 m_dwIndex = m_pImage->GetImportSectionsTable()->Append(CORCOMPILE_IMPORT_TYPE_STUB_DISPATCH, CORCOMPILE_IMPORT_FLAGS_PCODE,
766 sizeof(TADDR), m_pImportSection, this, m_pGCRefMapTable);
769 #ifdef FEATURE_READYTORUN_COMPILER
770 if (IsReadyToRunCompilation())
772 // Create the delay load helper
773 ZapNode * pDelayLoadHelper = m_pImage->GetImportTable()->GetPlacedIndirectHelperThunk(READYTORUN_HELPER_DelayLoad_MethodCall, (PVOID)(SIZE_T)m_dwIndex);
774 pCell->SetDelayLoadHelper(pDelayLoadHelper);
779 pCell->SetDelayLoadHelper(m_pImage->GetHelperThunk(CORINFO_HELP_EE_EXTERNAL_FIXUP));
782 // Add entry to both the cell and data sections
783 m_pImportSection->Place(pCell);
785 m_pImage->GetImportTable()->PlaceImportBlob(pCell);
787 m_pGCRefMapTable->Append(pCell->GetMethod());
791 // Virtual import thunk is a patchable thunk used for cross-module virtual calls.
793 class ZapVirtualMethodThunk : public ZapImport
796 virtual DWORD GetSize()
798 return sizeof(CORCOMPILE_VIRTUAL_IMPORT_THUNK);
801 virtual ZapNodeType GetType()
803 return ZapNodeType_VirtualMethodThunk;
806 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
808 // Virtual import thunks do not have signatures
812 virtual void Save(ZapWriter * pZapWriter);
815 void ZapVirtualMethodThunk::Save(ZapWriter * pZapWriter)
817 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
819 CORCOMPILE_VIRTUAL_IMPORT_THUNK thunk;
820 memset(&thunk, DEFAULT_CODE_BUFFER_INIT, sizeof(thunk));
822 // On ARM, the helper would already have the thumb-bit set. Refer to
823 // GetHelperThunk implementation.
824 ZapNode * helper = pImage->GetHelperThunk(CORINFO_HELP_EE_VTABLE_FIXUP);
825 _ASSERTE(FitsIn<UINT16>((SIZE_T)GetHandle2() - 1));
826 USHORT slotNum = (USHORT)((SIZE_T)GetHandle2() - 1);
828 #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
829 thunk.callJmp[0] = 0xE8; // call rel32
830 pImage->WriteReloc(&thunk, 1, helper, 0, IMAGE_REL_BASED_REL32);
832 // Mark this as a Virtual Import Thunk
833 thunk.precodeType = _PRECODE_VIRTUAL_IMPORT_THUNK;
834 #elif defined(_TARGET_ARM_)
835 // Setup the call to VirtualMethodFixupStub
839 // Per ARM architecture reference manual section A2.3,
840 // reading the value of PC register will read the address
841 // of the current instruction plus 4. In this case,
842 // R12 will containing the address of "F004" below once
843 // the "mov" is executed.
845 // Since this is 4 bytes ahead of the start of the thunk,
846 // the assembly helper we will call into will adjust this
847 // so that we point to the start of the thunk correctly.
848 thunk.m_rgCode[0] = 0x46fc;
851 thunk.m_rgCode[1] = 0xf8df;
852 thunk.m_rgCode[2] = 0xf004;
854 // Slot ID is setup below, so now setup the initial target
855 // to be our assembly helper.
856 pImage->WriteReloc(&thunk, offsetof(CORCOMPILE_VIRTUAL_IMPORT_THUNK, m_pTarget), helper, 0, IMAGE_REL_BASED_PTR);
857 #elif defined(_TARGET_ARM64_)
859 thunk.m_rgCode[0] = 0x1000000C; //adr x12, #0
860 thunk.m_rgCode[1] = 0xF940098A; //ldr x10, [x12, #16]
861 thunk.m_rgCode[2] = 0xD61F0140; //br x10
863 // Slot ID is setup below, so now setup the initial target
864 // to be our assembly helper.
865 pImage->WriteReloc(&thunk, offsetof(CORCOMPILE_VIRTUAL_IMPORT_THUNK, m_pTarget), helper, 0, IMAGE_REL_BASED_PTR);
867 PORTABILITY_ASSERT("ZapVirtualMethodThunk::Save");
870 thunk.slotNum = slotNum;
872 pZapWriter->Write(&thunk, sizeof(thunk));
875 void ZapImportTable::PlaceVirtualImportThunk(ZapImport * pVirtualImportThunk)
877 if (m_pImage->m_pVirtualImportThunkSection->GetNodeCount() == 0)
879 m_pImage->GetImportSectionsTable()->Append(CORCOMPILE_IMPORT_TYPE_VIRTUAL_METHOD, CORCOMPILE_IMPORT_FLAGS_CODE,
880 sizeof(CORCOMPILE_VIRTUAL_IMPORT_THUNK), m_pImage->m_pVirtualImportThunkSection);
882 // Make sure the helper created
883 m_pImage->GetHelperThunk(CORINFO_HELP_EE_VTABLE_FIXUP);
886 m_pImage->m_pVirtualImportThunkSection->Place(pVirtualImportThunk);
889 ZapImport * ZapImportTable::GetVirtualImportThunk(CORINFO_METHOD_HANDLE handle, int slot)
891 return GetImport<ZapVirtualMethodThunk, ZapNodeType_VirtualMethodThunk>(handle, (PVOID)(SIZE_T)(slot+1));
894 // ======================================================================================
896 // GCRefMapTable is used to encode for GC references locations for lazily resolved calls
899 void ZapGCRefMapTable::Append(CORINFO_METHOD_HANDLE handle)
901 m_pImage->GetCompileInfo()->GetCallRefMap(handle, &m_GCRefMapBuilder);
905 DWORD ZapGCRefMapTable::GetSize()
907 if (m_nCount == 0) return 0;
909 COUNT_T nLookupEntries = (1 + m_nCount / GCREFMAP_LOOKUP_STRIDE);
911 return (nLookupEntries * sizeof(DWORD)) + m_GCRefMapBuilder.GetBlobLength();
914 void ZapGCRefMapTable::Save(ZapWriter * pZapWriter)
916 if (m_nCount == 0) return;
918 COUNT_T nLookupEntries = (1 + m_nCount / GCREFMAP_LOOKUP_STRIDE);
921 BYTE * pBlob = (BYTE *)m_GCRefMapBuilder.GetBlob(&dwBlobLength);
924 COUNT_T iLookupEntry = 0;
927 DWORD relOfs = (nLookupEntries * sizeof(DWORD)) + pos;
928 pZapWriter->Write(&relOfs, sizeof(relOfs));
931 if (iLookupEntry >= nLookupEntries)
934 for (int i = 0; i < GCREFMAP_LOOKUP_STRIDE; i++)
936 while ((*(pBlob + pos) & 0x80) != 0)
940 _ASSERTE(pos <= dwBlobLength);
944 pZapWriter->Write(pBlob, dwBlobLength);
947 // ======================================================================================
949 // Getters for existing imports.
952 ZapImport * ZapImportTable::GetExistingClassHandleImport(CORINFO_CLASS_HANDLE handle)
954 return GetExistingImport(ZapNodeType_Import_ClassHandle, handle);
957 ZapImport * ZapImportTable::GetExistingFieldHandleImport(CORINFO_FIELD_HANDLE handle)
959 return GetExistingImport(ZapNodeType_Import_FieldHandle, handle);
962 ZapImport * ZapImportTable::GetExistingMethodHandleImport(CORINFO_METHOD_HANDLE handle)
964 return GetExistingImport(ZapNodeType_Import_MethodHandle, handle);
967 CORINFO_MODULE_HANDLE ZapImportTable::TryEncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder)
969 if (!GetCompileInfo()->IsInCurrentVersionBubble(module))
970 module = GetImage()->GetModuleHandle();
972 EncodeModule(kind, module, pSigBuilder);
976 void ZapImportTable::EncodeModule(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_MODULE_HANDLE module, SigBuilder * pSigBuilder)
978 if (module != GetImage()->GetModuleHandle())
980 pSigBuilder->AppendByte(kind | ENCODE_MODULE_OVERRIDE);
981 pSigBuilder->AppendData(GetIndexOfModule(module));
985 pSigBuilder->AppendByte(kind);
989 void ZapImportTable::EncodeClass(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle, SigBuilder * pSigBuilder)
991 CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(handle);
992 referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder);
993 GetCompileInfo()->EncodeClass(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper);
996 void ZapImportTable::EncodeClassInContext(CORINFO_MODULE_HANDLE context, CORINFO_CLASS_HANDLE handle, SigBuilder * pSigBuilder)
998 GetCompileInfo()->EncodeClass(context, handle, pSigBuilder, this, EncodeModuleHelper);
1001 void ZapImportTable::EncodeField(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, SigBuilder * pSigBuilder,
1002 CORINFO_RESOLVED_TOKEN * pResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams)
1004 CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getFieldClass(handle);
1005 CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle);
1006 referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder);
1007 GetCompileInfo()->EncodeField(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper,
1008 pResolvedToken, fEncodeUsingResolvedTokenSpecStreams);
1011 void ZapImportTable::EncodeMethod(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, SigBuilder * pSigBuilder,
1012 CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken, BOOL fEncodeUsingResolvedTokenSpecStreams)
1014 CORINFO_CLASS_HANDLE clsHandle = GetJitInfo()->getMethodClass(handle);
1015 CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle);
1016 referencingModule = TryEncodeModule(kind, referencingModule, pSigBuilder);
1017 GetCompileInfo()->EncodeMethod(referencingModule, handle, pSigBuilder, this, EncodeModuleHelper,
1018 pResolvedToken, pConstrainedResolvedToken, fEncodeUsingResolvedTokenSpecStreams);
1021 // ======================================================================================
1026 class ZapModuleHandleImport : public ZapImport
1029 virtual ZapNodeType GetType()
1031 return ZapNodeType_Import_ModuleHandle;
1034 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
1036 ZapImport::ComputePlacement(pImage, pfIsEager, pfNeedsSignature);
1038 CORINFO_MODULE_HANDLE handle = (CORINFO_MODULE_HANDLE)GetHandle();
1039 if (pImage->m_pPreloader->CanEmbedModuleHandle(handle))
1044 return ZapImportSectionType_Handle;
1047 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1049 pTable->EncodeModule(ENCODE_MODULE_HANDLE, (CORINFO_MODULE_HANDLE)GetHandle(), pSigBuilder);
1053 ZapImport * ZapImportTable::GetModuleHandleImport(CORINFO_MODULE_HANDLE handle)
1055 return GetImport<ZapModuleHandleImport, ZapNodeType_Import_ModuleHandle>(handle);
1058 class ZapClassHandleImport : public ZapImport
1061 virtual ZapNodeType GetType()
1063 return ZapNodeType_Import_ClassHandle;
1066 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
1068 ZapImport::ComputePlacement(pImage, pfIsEager, pfNeedsSignature);
1070 if (IsReadyToRunCompilation())
1071 return ZapImportSectionType_Handle;
1073 CORINFO_CLASS_HANDLE handle = (CORINFO_CLASS_HANDLE)GetHandle();
1074 if (pImage->m_pPreloader->CanEmbedClassHandle(handle))
1076 // We may have entries pointing to our module that exist in the handle table to trigger restore.
1077 if (pImage->GetCompileInfo()->GetLoaderModuleForEmbeddableType(handle) == pImage->GetModuleHandle())
1079 *pfNeedsSignature = FALSE;
1087 return ZapImportSectionType_TypeHandle;
1090 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1092 pTable->EncodeClass(ENCODE_TYPE_HANDLE, (CORINFO_CLASS_HANDLE)GetHandle(), pSigBuilder);
1095 virtual void Save(ZapWriter * pZapWriter)
1097 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1099 // We may have entries pointing to our module that exist in the handle table to trigger restore.
1103 ZapNode handle(pImage->m_pPreloader->MapClassHandle((CORINFO_CLASS_HANDLE)GetHandle()));
1104 pImage->WriteReloc(&cell, 0, &handle, 0, IMAGE_REL_BASED_PTR);
1105 pZapWriter->Write(&cell, sizeof(cell));
1109 ZapImport::Save(pZapWriter);
1114 ZapImport * ZapImportTable::GetClassHandleImport(CORINFO_CLASS_HANDLE handle, PVOID pUniqueId)
1116 // pUniqueId is workaround for loading of generic parent method table. It would be nice to clean it up.
1117 if (pUniqueId != NULL)
1119 return GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle, pUniqueId);
1122 ZapImport * pImport = GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle);
1124 if (IsReadyToRunCompilation() && !pImport->HasBlob())
1126 SigBuilder sigBuilder;
1128 EncodeClass(ENCODE_TYPE_HANDLE, handle, &sigBuilder);
1130 pImport->SetBlob(GetBlob(&sigBuilder));
1136 class ZapFieldHandleImport : public ZapImport
1139 virtual ZapNodeType GetType()
1141 return ZapNodeType_Import_FieldHandle;
1144 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1146 pTable->EncodeField(ENCODE_FIELD_HANDLE, (CORINFO_FIELD_HANDLE)GetHandle(), pSigBuilder);
1150 ZapImport * ZapImportTable::GetFieldHandleImport(CORINFO_FIELD_HANDLE handle)
1152 return GetImport<ZapFieldHandleImport, ZapNodeType_Import_FieldHandle>(handle);
1155 class ZapMethodHandleImport : public ZapImport
1158 virtual ZapNodeType GetType()
1160 return ZapNodeType_Import_MethodHandle;
1163 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
1165 ZapImport::ComputePlacement(pImage, pfIsEager, pfNeedsSignature);
1167 if (IsReadyToRunCompilation())
1168 return ZapImportSectionType_Handle;
1170 CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)GetHandle();
1171 if (pImage->m_pPreloader->CanEmbedMethodHandle(handle))
1173 // We may have entries pointing to our module that exist in the handle table to trigger restore.
1174 if (pImage->GetCompileInfo()->GetLoaderModuleForEmbeddableMethod(handle) == pImage->GetModuleHandle())
1176 *pfNeedsSignature = FALSE;
1180 return ZapImportSectionType_MethodHandle;
1183 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1185 pTable->EncodeMethod(ENCODE_METHOD_HANDLE, (CORINFO_METHOD_HANDLE)GetHandle(), pSigBuilder);
1188 virtual void Save(ZapWriter * pZapWriter)
1190 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1192 // We may have entries pointing to our module that exist in the handle table to trigger restore.
1196 ZapNode handle(pImage->m_pPreloader->MapMethodHandle((CORINFO_METHOD_HANDLE)GetHandle()));
1197 pImage->WriteReloc(&cell, 0, &handle, 0, IMAGE_REL_BASED_PTR);
1198 pZapWriter->Write(&cell, sizeof(cell));
1202 ZapImport::Save(pZapWriter);
1207 ZapImport * ZapImportTable::GetMethodHandleImport(CORINFO_METHOD_HANDLE handle)
1209 return GetImport<ZapMethodHandleImport, ZapNodeType_Import_MethodHandle>(handle);
1212 class ZapStringHandleImport : public ZapImport
1215 virtual ZapNodeType GetType()
1217 return ZapNodeType_Import_StringHandle;
1220 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
1222 ZapImport::ComputePlacement(pImage, pfIsEager, pfNeedsSignature);
1225 if ((mdString)(size_t)GetHandle2() == mdtString)
1228 return ZapImportSectionType_Handle;
1231 return ZapImportSectionType_StringHandle;
1234 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1236 CORINFO_MODULE_HANDLE referencingModule = (CORINFO_MODULE_HANDLE)GetHandle();
1238 pTable->EncodeModule(ENCODE_STRING_HANDLE, referencingModule, pSigBuilder);
1240 mdString token = (mdString)(size_t)GetHandle2();
1241 pSigBuilder->AppendData(RidFromToken(token));
1245 ZapImport * ZapImportTable::GetStringHandleImport(CORINFO_MODULE_HANDLE tokenScope, mdString metaTok)
1247 return GetImport<ZapStringHandleImport, ZapNodeType_Import_StringHandle>(tokenScope, (PVOID)(size_t)metaTok);
1250 class ZapFunctionEntryImport : public ZapImport
1253 virtual ZapNodeType GetType()
1255 return ZapNodeType_Import_FunctionEntry;
1259 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
1261 ZapImport::ComputePlacement(pImage, pfIsEager, pfNeedsSignature);
1262 return ZapImportSectionType_PCode;
1266 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1268 CORINFO_METHOD_HANDLE handle = (CORINFO_METHOD_HANDLE)GetHandle();
1270 CORINFO_MODULE_HANDLE referencingModule;
1271 mdToken token = pTable->GetCompileInfo()->TryEncodeMethodAsToken(handle, NULL, &referencingModule);
1272 if (token != mdTokenNil)
1274 _ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
1276 // It's a NativeCallable method , then encode it as ENCODE_METHOD_NATIVE_ENTRY
1277 if (pTable->GetCompileInfo()->IsNativeCallableMethod(handle))
1279 pTable->EncodeModule(ENCODE_METHOD_NATIVE_ENTRY, referencingModule, pSigBuilder);
1283 pTable->EncodeModule(
1284 (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
1285 referencingModule, pSigBuilder);
1288 pSigBuilder->AppendData(RidFromToken(token));
1292 pTable->EncodeMethod(ENCODE_METHOD_ENTRY, handle, pSigBuilder);
1296 virtual void Save(ZapWriter * pZapWriter)
1298 SIZE_T token = CORCOMPILE_TAG_PCODE(GetBlob()->GetRVA());
1299 pZapWriter->Write(&token, sizeof(token));
1303 ZapImport * ZapImportTable::GetFunctionEntryImport(CORINFO_METHOD_HANDLE handle)
1305 return GetImport<ZapFunctionEntryImport, ZapNodeType_Import_FunctionEntry>(handle);
1308 class ZapStaticFieldAddressImport : public ZapImport
1311 virtual ZapNodeType GetType()
1313 return ZapNodeType_Import_StaticFieldAddress;
1316 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1318 pTable->EncodeField(ENCODE_STATIC_FIELD_ADDRESS, (CORINFO_FIELD_HANDLE)GetHandle(), pSigBuilder);
1321 virtual DWORD GetSize()
1323 return 2 * sizeof(TADDR);
1326 virtual void Save(ZapWriter * pZapWriter)
1328 ZapImport::Save(pZapWriter);
1331 pZapWriter->Write(&value, sizeof(value));
1335 ZapImport * ZapImportTable::GetStaticFieldAddressImport(CORINFO_FIELD_HANDLE handle)
1337 return GetImport<ZapStaticFieldAddressImport, ZapNodeType_Import_StaticFieldAddress>(handle);
1340 class ZapClassDomainIdImport : public ZapImport
1343 virtual ZapNodeType GetType()
1345 return ZapNodeType_Import_ClassDomainId;
1348 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1350 pTable->EncodeClass(ENCODE_CLASS_ID_FOR_STATICS, (CORINFO_CLASS_HANDLE)GetHandle(), pSigBuilder);
1354 ZapImport * ZapImportTable::GetClassDomainIdImport(CORINFO_CLASS_HANDLE handle)
1356 return GetImport<ZapClassDomainIdImport, ZapNodeType_Import_ClassDomainId>(handle);
1359 class ZapModuleDomainIdImport : public ZapImport
1362 virtual ZapNodeType GetType()
1364 return ZapNodeType_Import_ModuleDomainId;
1367 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1369 if (GetHandle() != NULL)
1371 pTable->EncodeModule(ENCODE_MODULE_ID_FOR_STATICS, (CORINFO_MODULE_HANDLE)GetHandle(), pSigBuilder);
1375 _ASSERTE(GetHandle2() != NULL);
1377 pTable->EncodeClass(ENCODE_MODULE_ID_FOR_GENERIC_STATICS, (CORINFO_CLASS_HANDLE)GetHandle2(), pSigBuilder);
1382 ZapImport * ZapImportTable::GetModuleDomainIdImport(CORINFO_MODULE_HANDLE handleToModule, CORINFO_CLASS_HANDLE handleToClass)
1384 _ASSERTE(((void *)handleToModule != (void *)handleToClass) && ((handleToModule == NULL) || (handleToClass == NULL)));
1386 return GetImport<ZapModuleDomainIdImport, ZapNodeType_Import_ModuleDomainId>(handleToModule, handleToClass);
1389 class ZapSyncLockImport : public ZapImport
1392 virtual ZapNodeType GetType()
1394 return ZapNodeType_Import_SyncLock;
1397 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1399 pTable->EncodeClass(ENCODE_SYNC_LOCK, (CORINFO_CLASS_HANDLE)GetHandle(), pSigBuilder);
1403 ZapImport * ZapImportTable::GetSyncLockImport(CORINFO_CLASS_HANDLE handle)
1405 return GetImport<ZapSyncLockImport, ZapNodeType_Import_SyncLock>(handle);
1408 class ZapIndirectPInvokeTargetImport : public ZapImport
1411 virtual ZapNodeType GetType()
1413 return ZapNodeType_Import_IndirectPInvokeTarget;
1416 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1418 pTable->EncodeMethod(ENCODE_INDIRECT_PINVOKE_TARGET, (CORINFO_METHOD_HANDLE)GetHandle(), pSigBuilder);
1422 ZapImport * ZapImportTable::GetIndirectPInvokeTargetImport(CORINFO_METHOD_HANDLE handle)
1424 return GetImport<ZapIndirectPInvokeTargetImport, ZapNodeType_Import_IndirectPInvokeTarget>(handle);
1427 class ZapProfilingHandleImport : public ZapImport
1430 virtual ZapNodeType GetType()
1432 return ZapNodeType_Import_ProfilingHandle;
1435 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1437 pTable->EncodeMethod(ENCODE_PROFILING_HANDLE, (CORINFO_METHOD_HANDLE)GetHandle(), pSigBuilder);
1440 virtual DWORD GetSize()
1442 // fixup cell, 3 pointers to interception method (Enter/Leave/Tailcall) and opaque handle
1443 return kZapProfilingHandleImportValueIndexCount * sizeof(TADDR);
1446 virtual void Save(ZapWriter * pZapWriter)
1449 ZapImport::Save(pZapWriter);
1451 // Save zeroes for the rest of the entries
1453 // If this assert fires, someone changed the
1454 // kZapProfilingHandleImportValueIndex... enum values without updating me!
1455 _ASSERTE(kZapProfilingHandleImportValueIndexCount == 5);
1458 pZapWriter->Write(&value, sizeof(value));
1459 pZapWriter->Write(&value, sizeof(value));
1460 pZapWriter->Write(&value, sizeof(value));
1461 pZapWriter->Write(&value, sizeof(value));
1465 ZapImport * ZapImportTable::GetProfilingHandleImport(CORINFO_METHOD_HANDLE handle)
1467 return GetImport<ZapProfilingHandleImport, ZapNodeType_Import_ProfilingHandle>(handle);
1470 class ZapVarArgImport : public ZapImport
1473 virtual ZapNodeType GetType()
1475 return ZapNodeType_Import_VarArg;
1478 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1480 _ASSERTE((CORINFO_MODULE_HANDLE)GetHandle() == pTable->GetImage()->GetModuleHandle());
1482 mdToken token = (mdToken)(size_t)GetHandle2();
1483 switch (TypeFromToken(token))
1486 pSigBuilder->AppendByte(ENCODE_VARARGS_SIG);
1490 pSigBuilder->AppendByte(ENCODE_VARARGS_METHODREF);
1494 pSigBuilder->AppendByte(ENCODE_VARARGS_METHODDEF);
1498 _ASSERTE(!"Bogus token for signature");
1501 pSigBuilder->AppendData(RidFromToken(token));
1505 ZapImport * ZapImportTable::GetVarArgImport(CORINFO_MODULE_HANDLE handle, mdToken sigOrMemberRefOrDef)
1507 return GetImport<ZapVarArgImport, ZapNodeType_Import_VarArg>(handle, (PVOID)(size_t)sigOrMemberRefOrDef);
1510 class ZapActiveDependencyImport : public ZapImport
1513 virtual ZapNodeType GetType()
1515 return ZapNodeType_Import_ActiveDependency;
1518 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1520 pTable->EncodeModule(ENCODE_ACTIVE_DEPENDENCY, (CORINFO_MODULE_HANDLE)GetHandle(), pSigBuilder);
1521 pSigBuilder->AppendData(pTable->GetIndexOfModule((CORINFO_MODULE_HANDLE)GetHandle2()));
1525 ZapImport * ZapImportTable::GetActiveDependencyImport(CORINFO_MODULE_HANDLE moduleFrom, CORINFO_MODULE_HANDLE moduleTo)
1527 return GetImport<ZapActiveDependencyImport, ZapNodeType_Import_ActiveDependency>(moduleFrom, moduleTo);
1530 ZapImport * ZapImportTable::GetClassImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken)
1532 CORINFO_CLASS_HANDLE handle = (CORINFO_CLASS_HANDLE) pResolvedToken->hClass;
1534 ZapImport * pImport = GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle, (PVOID)kind);
1536 if (!pImport->HasBlob())
1538 SigBuilder sigBuilder;
1540 EncodeClass(kind, handle, &sigBuilder);
1542 pImport->SetBlob(GetBlob(&sigBuilder));
1548 ZapImport * ZapImportTable::GetMethodImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle,
1549 CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken /*=NULL*/)
1551 SigBuilder sigBuilder;
1552 EncodeMethod(kind, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken);
1554 return GetImportForSignature<ZapMethodHandleImport, ZapNodeType_Import_MethodHandle>((PVOID)handle, &sigBuilder);
1557 ZapImport * ZapImportTable::GetFieldImport(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken)
1559 SigBuilder sigBuilder;
1560 EncodeField(kind, handle, &sigBuilder, pResolvedToken);
1562 return GetImportForSignature<ZapFieldHandleImport, ZapNodeType_Import_FieldHandle>((PVOID)handle, &sigBuilder);
1565 #ifdef FEATURE_READYTORUN_COMPILER
1566 ZapImport * ZapImportTable::GetCheckTypeLayoutImport(CORINFO_CLASS_HANDLE handle)
1568 ZapImport * pImport = GetImport<ZapClassHandleImport, ZapNodeType_Import_ClassHandle>(handle, (PVOID)ENCODE_CHECK_TYPE_LAYOUT);
1570 if (!pImport->HasBlob())
1572 SigBuilder sigBuilder;
1574 sigBuilder.AppendData(ENCODE_CHECK_TYPE_LAYOUT);
1576 GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), handle, &sigBuilder, NULL, NULL);
1578 GetCompileInfo()->EncodeTypeLayout(handle, &sigBuilder);
1580 pImport->SetBlob(GetBlob(&sigBuilder));
1586 ZapImport * ZapImportTable::GetCheckFieldOffsetImport(CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, DWORD offset)
1588 SigBuilder sigBuilder;
1590 sigBuilder.AppendData(ENCODE_CHECK_FIELD_OFFSET);
1592 sigBuilder.AppendData(offset);
1594 GetCompileInfo()->EncodeField(m_pImage->GetModuleHandle(), handle, &sigBuilder, NULL, NULL, pResolvedToken);
1596 EncodeField(ENCODE_CHECK_FIELD_OFFSET, handle, &sigBuilder, pResolvedToken);
1598 return GetImportForSignature<ZapFieldHandleImport, ZapNodeType_Import_FieldHandle>((PVOID)handle, &sigBuilder);
1600 #endif // FEATURE_READYTORUN_COMPILER
1602 ZapImport * ZapImportTable::GetStubDispatchCell(CORINFO_RESOLVED_TOKEN * pResolvedToken)
1604 CORINFO_METHOD_HANDLE handle = pResolvedToken->hMethod;
1606 SigBuilder sigBuilder;
1608 DWORD slot = GetCompileInfo()->TryEncodeMethodSlot(handle);
1609 if (slot != (DWORD) -1)
1611 CORINFO_CLASS_HANDLE clsHandle = pResolvedToken->hClass;
1613 CORINFO_MODULE_HANDLE referencingModule = GetJitInfo()->getClassModule(clsHandle);
1615 referencingModule = TryEncodeModule(ENCODE_VIRTUAL_ENTRY_SLOT, referencingModule, &sigBuilder);
1617 sigBuilder.AppendData(slot);
1619 EncodeClassInContext(referencingModule, clsHandle, &sigBuilder);
1623 CORINFO_MODULE_HANDLE referencingModule;
1624 mdToken token = GetCompileInfo()->TryEncodeMethodAsToken(handle, pResolvedToken, &referencingModule);
1625 if (token != mdTokenNil)
1627 _ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
1630 (TypeFromToken(token) == mdtMethodDef) ? ENCODE_VIRTUAL_ENTRY_DEF_TOKEN : ENCODE_VIRTUAL_ENTRY_REF_TOKEN,
1631 referencingModule, &sigBuilder);
1633 sigBuilder.AppendData(RidFromToken(token));
1637 EncodeMethod(ENCODE_VIRTUAL_ENTRY, handle, &sigBuilder, pResolvedToken);
1641 // For now, always optimize ready to run for size and startup performance - share cells between callsites
1642 return GetImportForSignature<ZapStubDispatchCell, ZapNodeType_StubDispatchCell>((PVOID)handle, &sigBuilder);
1645 ZapImport * ZapImportTable::GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken)
1647 SigBuilder sigBuilder;
1649 CORINFO_MODULE_HANDLE referencingModule;
1650 mdToken token = GetCompileInfo()->TryEncodeMethodAsToken(handle, pResolvedToken, &referencingModule);
1651 if (token != mdTokenNil)
1653 _ASSERTE(TypeFromToken(token) == mdtMethodDef || TypeFromToken(token) == mdtMemberRef);
1656 (TypeFromToken(token) == mdtMethodDef) ? ENCODE_METHOD_ENTRY_DEF_TOKEN : ENCODE_METHOD_ENTRY_REF_TOKEN,
1657 referencingModule, &sigBuilder);
1659 sigBuilder.AppendData(RidFromToken(token));
1663 EncodeMethod(ENCODE_METHOD_ENTRY, handle, &sigBuilder, pResolvedToken, pConstrainedResolvedToken);
1666 return GetImportForSignature<ZapExternalMethodCell, ZapNodeType_ExternalMethodCell>((PVOID)handle, &sigBuilder);
1670 #ifdef FEATURE_READYTORUN_COMPILER
1672 class ZapDynamicHelperCell : public ZapImport
1674 ZapNode * m_pDelayLoadHelper;
1677 void SetDelayLoadHelper(ZapNode * pDelayLoadHelper)
1679 _ASSERTE(m_pDelayLoadHelper == NULL);
1680 m_pDelayLoadHelper = pDelayLoadHelper;
1683 virtual DWORD GetSize()
1685 return sizeof(TADDR);
1688 virtual UINT GetAlignment()
1690 return sizeof(TADDR);
1693 virtual ZapNodeType GetType()
1695 return ZapNodeType_DynamicHelperCell;
1698 CORCOMPILE_FIXUP_BLOB_KIND GetKind()
1700 int kind = (int)GetHandle();
1702 if ((kind & 1) == 1)
1704 return (CORCOMPILE_FIXUP_BLOB_KIND)(kind >> 1);
1709 (GetBlob()->GetSize() > 0) && (
1710 GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_THISOBJ ||
1711 GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_METHOD ||
1712 GetBlob()->GetData()[0] == ENCODE_DICTIONARY_LOOKUP_TYPE));
1714 return (CORCOMPILE_FIXUP_BLOB_KIND)GetBlob()->GetData()[0];
1718 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1720 // Encode should be unreachable for ready-to-run cells
1724 virtual void Save(ZapWriter * pZapWriter)
1726 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1729 pImage->WriteReloc(&cell, 0, m_pDelayLoadHelper, 0, IMAGE_REL_BASED_PTR);
1730 pZapWriter->Write(&cell, sizeof(cell));
1734 static ReadyToRunHelper GetDelayLoadHelperForDynamicHelper(CORCOMPILE_FIXUP_BLOB_KIND kind)
1738 case ENCODE_NEW_HELPER:
1739 case ENCODE_NEW_ARRAY_HELPER:
1740 case ENCODE_STATIC_BASE_NONGC_HELPER:
1741 case ENCODE_STATIC_BASE_GC_HELPER:
1742 case ENCODE_THREAD_STATIC_BASE_NONGC_HELPER:
1743 case ENCODE_THREAD_STATIC_BASE_GC_HELPER:
1744 case ENCODE_CCTOR_TRIGGER:
1745 case ENCODE_FIELD_ADDRESS:
1746 case ENCODE_DICTIONARY_LOOKUP_THISOBJ:
1747 case ENCODE_DICTIONARY_LOOKUP_TYPE:
1748 case ENCODE_DICTIONARY_LOOKUP_METHOD:
1749 return READYTORUN_HELPER_DelayLoad_Helper;
1751 case ENCODE_CHKCAST_HELPER:
1752 case ENCODE_ISINSTANCEOF_HELPER:
1753 return READYTORUN_HELPER_DelayLoad_Helper_Obj;
1755 case ENCODE_VIRTUAL_ENTRY:
1756 // case ENCODE_VIRTUAL_ENTRY_DEF_TOKEN:
1757 // case ENCODE_VIRTUAL_ENTRY_REF_TOKEN:
1758 // case ENCODE_VIRTUAL_ENTRY_SLOT:
1759 return READYTORUN_HELPER_DelayLoad_Helper_Obj;
1761 case ENCODE_DELEGATE_CTOR:
1762 return READYTORUN_HELPER_DelayLoad_Helper_ObjObj;
1769 void ZapImportSectionSignatures::PlaceDynamicHelperCell(ZapImport * pImport)
1771 ZapDynamicHelperCell * pCell = (ZapDynamicHelperCell *)pImport;
1773 if (m_pImportSection->GetNodeCount() == 0)
1775 m_dwIndex = m_pImage->GetImportSectionsTable()->Append(CORCOMPILE_IMPORT_TYPE_UNKNOWN, CORCOMPILE_IMPORT_FLAGS_PCODE,
1776 sizeof(TADDR), m_pImportSection, this, m_pGCRefMapTable);
1779 // Create the delay load helper
1780 ReadyToRunHelper helperNum = GetDelayLoadHelperForDynamicHelper(
1781 (CORCOMPILE_FIXUP_BLOB_KIND)(pCell->GetKind() & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE));
1783 ZapNode * pDelayLoadHelper = m_pImage->GetImportTable()->GetPlacedIndirectHelperThunk(helperNum, (PVOID)(SIZE_T)m_dwIndex,
1784 (pCell->GetKind() & CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) ? pCell : NULL);
1786 pCell->SetDelayLoadHelper(pDelayLoadHelper);
1788 // Add entry to both the the cell and data sections
1789 m_pImportSection->Place(pCell);
1791 m_pImage->GetImportTable()->PlaceImportBlob(pCell);
1794 ZapImport * ZapImportTable::GetDictionaryLookupCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_LOOKUP_KIND * pLookup)
1796 _ASSERTE(pLookup->needsRuntimeLookup);
1798 SigBuilder sigBuilder;
1800 sigBuilder.AppendData(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE);
1802 if ((kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DICTIONARY_LOOKUP_THISOBJ)
1804 CORINFO_CLASS_HANDLE hClassContext = GetJitInfo()->getMethodClass(pResolvedToken->tokenContext);
1805 GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), hClassContext, &sigBuilder, NULL, NULL);
1808 switch (pLookup->runtimeLookupFlags)
1810 case READYTORUN_FIXUP_TypeHandle:
1811 case READYTORUN_FIXUP_DeclaringTypeHandle:
1813 if (pResolvedToken->pTypeSpec == NULL)
1815 _ASSERTE(!"Invalid IL that directly references __Canon");
1819 if (pLookup->runtimeLookupFlags == READYTORUN_FIXUP_DeclaringTypeHandle)
1821 _ASSERTE(pLookup->runtimeLookupArgs != NULL);
1822 sigBuilder.AppendData(ENCODE_DECLARINGTYPE_HANDLE);
1823 GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), (CORINFO_CLASS_HANDLE)pLookup->runtimeLookupArgs, &sigBuilder, NULL, NULL);
1827 sigBuilder.AppendData(ENCODE_TYPE_HANDLE);
1830 if (pResolvedToken->tokenType == CORINFO_TOKENKIND_Newarr)
1831 sigBuilder.AppendElementType(ELEMENT_TYPE_SZARRAY);
1832 sigBuilder.AppendBlob((PVOID)pResolvedToken->pTypeSpec, pResolvedToken->cbTypeSpec);
1836 case READYTORUN_FIXUP_MethodHandle:
1837 EncodeMethod(ENCODE_METHOD_HANDLE, pResolvedToken->hMethod, &sigBuilder, pResolvedToken, NULL, TRUE);
1840 case READYTORUN_FIXUP_MethodEntry:
1841 EncodeMethod(ENCODE_METHOD_ENTRY, pResolvedToken->hMethod, &sigBuilder, pResolvedToken, (CORINFO_RESOLVED_TOKEN*)pLookup->runtimeLookupArgs, TRUE);
1844 case READYTORUN_FIXUP_VirtualEntry:
1845 EncodeMethod(ENCODE_VIRTUAL_ENTRY, pResolvedToken->hMethod, &sigBuilder, pResolvedToken, NULL, TRUE);
1848 case READYTORUN_FIXUP_FieldHandle:
1849 EncodeField(ENCODE_FIELD_HANDLE, pResolvedToken->hField, &sigBuilder, pResolvedToken, TRUE);
1853 _ASSERTE(!"Invalid R2R fixup kind!");
1857 _ASSERTE(((DWORD)pResolvedToken->tokenContext & 1) == 0);
1859 return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void*)pResolvedToken->tokenContext, &sigBuilder);
1862 ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle)
1864 ZapImport * pImport = GetImport<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), handle);
1866 if (!pImport->HasBlob())
1868 SigBuilder sigBuilder;
1870 sigBuilder.AppendData(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE);
1872 GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), handle, &sigBuilder, NULL, NULL);
1874 pImport->SetBlob(GetBlob(&sigBuilder));
1880 ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken,
1881 CORINFO_CLASS_HANDLE delegateType /*=NULL*/)
1883 SigBuilder sigBuilder;
1885 EncodeMethod((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE),
1886 handle, &sigBuilder, pResolvedToken);
1888 if (delegateType != NULL)
1890 _ASSERTE((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DELEGATE_CTOR);
1891 GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), delegateType, &sigBuilder, NULL, NULL);
1894 return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), &sigBuilder);
1897 ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken)
1899 SigBuilder sigBuilder;
1901 EncodeField((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE),
1902 handle, &sigBuilder, pResolvedToken);
1904 return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)(uintptr_t)((kind << 1) | 1), &sigBuilder);
1907 class ZapIndirectHelperThunk : public ZapImport
1909 DWORD SaveWorker(ZapWriter * pZapWriter);
1914 void SetCell(ZapNode * pCell)
1919 ReadyToRunHelper GetReadyToRunHelper()
1921 return (ReadyToRunHelper)((DWORD)GetHandle() & ~READYTORUN_HELPER_FLAG_VSD);
1924 DWORD GetSectionIndex()
1926 return (DWORD)GetHandle2();
1929 BOOL IsDelayLoadHelper()
1931 ReadyToRunHelper helper = GetReadyToRunHelper();
1932 return (helper == READYTORUN_HELPER_DelayLoad_MethodCall) ||
1933 (helper == READYTORUN_HELPER_DelayLoad_Helper) ||
1934 (helper == READYTORUN_HELPER_DelayLoad_Helper_Obj) ||
1935 (helper == READYTORUN_HELPER_DelayLoad_Helper_ObjObj);
1938 BOOL IsDelayLoadMethodCallHelper()
1940 ReadyToRunHelper helper = GetReadyToRunHelper();
1941 return (helper == READYTORUN_HELPER_DelayLoad_MethodCall);
1946 return ((DWORD)GetHandle() & READYTORUN_HELPER_FLAG_VSD) != 0;
1951 ReadyToRunHelper helper = GetReadyToRunHelper();
1952 return (helper == READYTORUN_HELPER_GetString);
1957 return SaveWorker(NULL);
1960 void Save(ZapWriter * pZapWriter)
1962 SaveWorker(pZapWriter);
1965 virtual UINT GetAlignment()
1967 return MINIMUM_CODE_ALIGN;
1970 virtual ZapNodeType GetType()
1972 return ZapNodeType_IndirectHelperThunk;
1975 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
1977 // Encode should be unreachable for ready-to-run cells
1983 static void MovRegImm(BYTE* p, int reg)
1985 *(WORD *)(p + 0) = 0xF240;
1986 *(WORD *)(p + 2) = (UINT16)(reg << 8);
1987 *(WORD *)(p + 4) = 0xF2C0;
1988 *(WORD *)(p + 6) = (UINT16)(reg << 8);
1990 #endif // _TARGET_ARM_
1992 DWORD ZapIndirectHelperThunk::SaveWorker(ZapWriter * pZapWriter)
1994 ZapImage * pImage = ZapImage::GetImage(pZapWriter);
1999 #if defined(_TARGET_X86_)
2000 if (IsDelayLoadHelper())
2008 _ASSERTE(GetSectionIndex() <= 0x7F);
2009 *p++ = (BYTE)GetSectionIndex();
2015 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_PTR);
2021 // mov edx, [module]
2025 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_PTR);
2033 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_PTR);
2035 #elif defined(_TARGET_AMD64_)
2036 if (IsDelayLoadHelper())
2038 if (m_pCell != NULL)
2045 pImage->WriteReloc(buffer, (int)(p - buffer), m_pCell, 0, IMAGE_REL_BASED_REL32);
2065 _ASSERTE(GetSectionIndex() <= 0x7F);
2066 *p++ = (BYTE)GetSectionIndex();
2072 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_REL32);
2080 #ifdef UNIX_AMD64_ABI
2081 // mov rsi, [module]
2084 // mov rdx, [module]
2088 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_REL32);
2096 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_REL32);
2098 #elif defined(_TARGET_ARM_)
2099 if (IsDelayLoadHelper())
2101 // r4 contains indirection cell
2103 *(WORD *)(p + 0) = 0xB410;
2107 _ASSERTE(GetSectionIndex() <= 0x7F);
2108 *(WORD *)(p + 0) = 0x2400 | (BYTE)GetSectionIndex();
2112 *(WORD *)(p + 0) = 0xB410;
2118 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_THUMB_MOV32);
2122 *(WORD *)p = 0x6824;
2126 *(WORD *)(p + 0) = 0xB410;
2132 pImage->WriteReloc(buffer, (int)(p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_THUMB_MOV32);
2136 *(WORD *)p = 0x6824;
2140 *(WORD *)p = 0x4720;
2150 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_THUMB_MOV32);
2154 *(WORD *)p = 0x6809;
2158 // mov r12, [helper]
2161 pImage->WriteReloc(buffer, (int) (p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_THUMB_MOV32);
2165 *(DWORD *)p = 0xC000F8DC;
2169 *(WORD *)p = 0x4760;
2172 #elif defined(_TARGET_ARM64_)
2173 if (IsDelayLoadHelper())
2175 // x11 contains indirection cell
2176 // Do nothing x11 contains our first param
2179 DWORD index = GetSectionIndex();
2180 _ASSERTE(index <= 0x7F);
2181 *(DWORD*)p = 0xd2800009 | (index << 5);
2184 // move Module* -> x10
2185 // ldr x10, [PC+0x14]
2186 *(DWORD*)p = 0x580000AA;
2190 *(DWORD*)p = 0xf940014A;
2196 // Move Module* -> x1
2197 // ldr x1, [PC+0x14]
2198 *(DWORD*)p = 0x580000A1;
2202 *(DWORD*)p = 0xf9400021;
2207 // ldr x12, [PC+0x14]
2208 *(DWORD*)p = 0x580000AC;
2212 *(DWORD *)p = 0xf940018c;
2216 *(DWORD *)p = 0xd61f0180;
2221 pImage->WriteReloc(buffer, (int)(p - buffer), pImage->GetImportTable()->GetHelperImport(READYTORUN_HELPER_Module), 0, IMAGE_REL_BASED_PTR);
2226 pImage->WriteReloc(buffer, (int)(p - buffer), pImage->GetImportTable()->GetHelperImport(GetReadyToRunHelper()), 0, IMAGE_REL_BASED_PTR);
2229 PORTABILITY_ASSERT("ZapIndirectHelperThunk::SaveWorker");
2232 _ASSERTE(p - buffer <= sizeof(buffer));
2234 if (pZapWriter != NULL)
2235 pZapWriter->Write(&buffer, (int)(p - buffer));
2237 return (DWORD)(p - buffer);
2240 void ZapImportTable::PlaceIndirectHelperThunk(ZapNode * pImport)
2242 ZapIndirectHelperThunk * pThunk = (ZapIndirectHelperThunk *)pImport;
2244 if (pThunk->IsDelayLoadMethodCallHelper())
2245 m_pImage->m_pLazyMethodCallHelperSection->Place(pThunk);
2247 m_pImage->m_pLazyHelperSection->Place(pThunk);
2249 if (pThunk->IsDelayLoadHelper() || pThunk->IsLazyHelper())
2250 GetPlacedHelperImport(READYTORUN_HELPER_Module);
2252 GetPlacedHelperImport(pThunk->GetReadyToRunHelper());
2255 ZapNode * ZapImportTable::GetIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg)
2257 ZapNode * pImport = GetImport<ZapIndirectHelperThunk, ZapNodeType_IndirectHelperThunk>((void *)helperNum, pArg);
2258 #if defined(_TARGET_ARM_)
2259 pImport = m_pImage->GetInnerPtr(pImport, THUMB_CODE);
2264 ZapNode * ZapImportTable::GetPlacedIndirectHelperThunk(ReadyToRunHelper helperNum, PVOID pArg, ZapNode * pCell)
2269 ZapIndirectHelperThunk * pIndirectHelperThunk = new (m_pImage->GetHeap()) ZapIndirectHelperThunk();
2270 pIndirectHelperThunk->SetHandle((void *)helperNum);
2271 pIndirectHelperThunk->SetHandle2(pArg);
2272 pIndirectHelperThunk->SetCell(pCell);
2273 pImport = pIndirectHelperThunk;
2277 pImport = GetImport<ZapIndirectHelperThunk, ZapNodeType_IndirectHelperThunk>((void *)helperNum, pArg);
2279 if (!pImport->IsPlaced())
2280 PlaceIndirectHelperThunk(pImport);
2281 #if defined(_TARGET_ARM_)
2282 pImport = m_pImage->GetInnerPtr(pImport, THUMB_CODE);
2287 class ZapHelperImport : public ZapImport
2290 virtual ZapImportSectionType ComputePlacement(ZapImage * pImage, BOOL * pfIsEager, BOOL * pfNeedsSignature)
2293 *pfNeedsSignature = TRUE;
2294 return ZapImportSectionType_Handle;
2297 virtual ZapNodeType GetType()
2299 return ZapNodeType_Import_Helper;
2302 virtual void EncodeSignature(ZapImportTable * pTable, SigBuilder * pSigBuilder)
2304 // Encode should be unreachable for ready-to-run cells
2309 ZapImport * ZapImportTable::GetHelperImport(ReadyToRunHelper helperNum)
2311 ZapImport * pImport = GetImport<ZapHelperImport, ZapNodeType_Import_Helper>((void *)helperNum);
2313 if (!pImport->HasBlob())
2315 SigBuilder sigBuilder;
2317 sigBuilder.AppendData(ENCODE_READYTORUN_HELPER);
2318 sigBuilder.AppendData(helperNum);
2320 pImport->SetBlob(GetBlob(&sigBuilder));
2326 ZapImport * ZapImportTable::GetPlacedHelperImport(ReadyToRunHelper helperNum)
2328 ZapImport * pImport = GetHelperImport(helperNum);
2329 if (!pImport->IsPlaced())
2330 PlaceImport(pImport);
2334 #endif // FEATURE_READYTORUN_COMPILER