summaryrefslogtreecommitdiff
path: root/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch
diff options
context:
space:
mode:
Diffstat (limited to 'packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch')
-rw-r--r--packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch1017
1 files changed, 1017 insertions, 0 deletions
diff --git a/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch b/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch
new file mode 100644
index 0000000000..f7511ef78a
--- /dev/null
+++ b/packaging/0006-Remove-relocations-from-SECTION_MethodDesc-for-ngene.patch
@@ -0,0 +1,1017 @@
+From 38dd83da084cd357b9bce97a2a096b55232b57fc Mon Sep 17 00:00:00 2001
+From: gbalykov <g.balykov@samsung.com>
+Date: Wed, 31 May 2017 04:25:04 +0300
+Subject: [PATCH 06/32] Remove relocations from SECTION_MethodDesc for ngened
+ images (#11394)
+
+---
+ src/debug/daccess/nidump.cpp | 51 +++++++++++------------
+ src/vm/dllimport.cpp | 4 +-
+ src/vm/dynamicmethod.cpp | 14 +++----
+ src/vm/genmeth.cpp | 4 +-
+ src/vm/ilstubcache.cpp | 12 +++---
+ src/vm/method.cpp | 33 +++++++--------
+ src/vm/method.hpp | 94 ++++++++++++++++++++++++++++---------------
+ src/vm/methodimpl.cpp | 69 ++++++++++++++++++-------------
+ src/vm/methodimpl.h | 45 +++++++++++++--------
+ src/vm/methodtablebuilder.cpp | 24 +++++------
+ src/vm/methodtablebuilder.h | 8 ++--
+ 11 files changed, 205 insertions(+), 153 deletions(-)
+
+diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
+index 77c05b5..5e8302f 100644
+--- a/src/debug/daccess/nidump.cpp
++++ b/src/debug/daccess/nidump.cpp
+@@ -7829,20 +7829,20 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ MethodImpl, METHODDESCS);
+
+ }
+- _ASSERTE(impl->pImplementedMD == NULL
+- || isInRange(PTR_TO_TADDR(impl->pImplementedMD)));
+- if ((impl->pImplementedMD != NULL) &&
+- isInRange(PTR_TO_TADDR(impl->pImplementedMD)))
++ _ASSERTE(impl->pImplementedMD.IsNull()
++ || isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull())));
++ if (!impl->pImplementedMD.IsNull() &&
++ isInRange(PTR_TO_TADDR(impl->GetImpMDsNonNull())))
+ {
+ DisplayWriteFieldAddress( pImplementedMD,
+- DataPtrToDisplay(dac_cast<TADDR>(impl->pImplementedMD)),
+- numSlots * sizeof(MethodDesc*),
++ DataPtrToDisplay(dac_cast<TADDR>(impl->GetImpMDsNonNull())),
++ numSlots * sizeof(RelativePointer <MethodDesc*>),
+ MethodImpl, METHODDESCS );
+ }
+ else
+ {
+ DisplayWriteFieldPointer( pImplementedMD,
+- DataPtrToDisplay(dac_cast<TADDR>(impl->pImplementedMD)),
++ DataPtrToDisplay(dac_cast<TADDR>(impl->GetImpMDs())),
+ MethodImpl, METHODDESCS );
+ }
+ DisplayEndVStructure( METHODDESCS );
+@@ -7852,19 +7852,19 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ DisplayStartVStructure( "StoredSigMethodDesc", METHODDESCS );
+ PTR_StoredSigMethodDesc ssmd(md);
+ //display signature information.
+- if( isInRange(ssmd->m_pSig) )
++ if( isInRange(ssmd->GetSigRVA()) )
+ {
+- DisplayWriteFieldAddress(m_pSig, DataPtrToDisplay(ssmd->m_pSig),
++ DisplayWriteFieldAddress(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()),
+ ssmd->m_cSig, StoredSigMethodDesc,
+ METHODDESCS);
+ }
+ else
+ {
+- DisplayWriteFieldPointer(m_pSig, DataPtrToDisplay(ssmd->m_pSig),
++ DisplayWriteFieldPointer(m_pSig, DataPtrToDisplay(ssmd->GetSigRVA()),
+ StoredSigMethodDesc, METHODDESCS);
+
+ }
+- CoverageRead(TO_TADDR(ssmd->m_pSig), ssmd->m_cSig);
++ CoverageRead(TO_TADDR(ssmd->GetSigRVA()), ssmd->m_cSig);
+ DisplayWriteFieldInt( m_cSig, ssmd->m_cSig,
+ StoredSigMethodDesc, METHODDESCS );
+ #ifdef _WIN64
+@@ -7880,10 +7880,10 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ {
+ PTR_DynamicMethodDesc dmd(md);
+ DisplayStartVStructure( "DynamicMethodDesc", METHODDESCS );
+- WriteFieldStr( m_pszMethodName, PTR_BYTE(dmd->m_pszMethodName),
++ WriteFieldStr( m_pszMethodName, PTR_BYTE(dmd->GetMethodName()),
+ DynamicMethodDesc, METHODDESCS );
+ if( !CHECK_OPT(METHODDESCS) )
+- CoverageReadString( PTR_TO_TADDR(dmd->m_pszMethodName) );
++ CoverageReadString( PTR_TO_TADDR(dmd->GetMethodName()) );
+ DisplayWriteFieldPointer( m_pResolver,
+ DPtrToPreferredAddr(dmd->m_pResolver),
+ DynamicMethodDesc, METHODDESCS );
+@@ -7927,10 +7927,10 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ METHODDESCS );
+
+ WriteFieldStr( m_pszEntrypointName,
+- PTR_BYTE(TO_TADDR(nd->m_pszEntrypointName)),
++ PTR_BYTE(dac_cast<TADDR>(ndmd->GetEntrypointName())),
+ NDirectMethodDesc::temp1, METHODDESCS );
+ if( !CHECK_OPT(METHODDESCS) )
+- CoverageReadString(TO_TADDR(nd->m_pszEntrypointName));
++ CoverageReadString(dac_cast<TADDR>(ndmd->GetEntrypointName()));
+ if (md->IsQCall())
+ {
+ DisplayWriteFieldInt( m_dwECallID,
+@@ -7941,11 +7941,11 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ else
+ {
+ WriteFieldStr( m_pszLibName,
+- PTR_BYTE(TO_TADDR(nd->m_pszLibName)),
++ PTR_BYTE(dac_cast<TADDR>(ndmd->GetLibNameRaw())),
+ NDirectMethodDesc::temp1, METHODDESCS );
+ }
+ if( !CHECK_OPT(METHODDESCS) )
+- CoverageReadString( TO_TADDR(nd->m_pszLibName) );
++ CoverageReadString( dac_cast<TADDR>(ndmd->GetLibNameRaw()) );
+
+ PTR_NDirectWriteableData wnd( nd->m_pWriteableData );
+ DisplayStartStructureWithOffset( m_pWriteableData,
+@@ -7959,12 +7959,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ CoverageRead( PTR_TO_TADDR(wnd), sizeof(*wnd) );
+ DisplayEndStructure( METHODDESCS ); //m_pWriteableData
+
+-
+-#ifdef HAS_NDIRECT_IMPORT_PRECODE
+- PTR_NDirectImportThunkGlue glue(nd->m_pImportThunkGlue);
+-#else
+- PTR_NDirectImportThunkGlue glue(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc::temp1, nd, m_ImportThunkGlue));
+-#endif
++ PTR_NDirectImportThunkGlue glue(ndmd->GetNDirectImportThunkGlue());
+
+ #ifdef HAS_NDIRECT_IMPORT_PRECODE
+ if (glue == NULL)
+@@ -8065,7 +8060,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ & InstantiatedMethodDesc::KindMask;
+ if( kind == InstantiatedMethodDesc::SharedMethodInstantiation )
+ {
+- PTR_DictionaryLayout layout(TO_TADDR(imd->m_pDictLayout));
++ PTR_DictionaryLayout layout(dac_cast<TADDR>(imd->GetDictLayoutRaw()));
+ IF_OPT(METHODDESCS)
+ {
+ WriteFieldDictionaryLayout( "m_pDictLayout",
+@@ -8089,7 +8084,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ else if( kind ==
+ InstantiatedMethodDesc::WrapperStubWithInstantiations )
+ {
+- PTR_MethodDesc wimd(imd->m_pWrappedMethodDesc.GetValue());
++ PTR_MethodDesc wimd(imd->IMD_GetWrappedMethodDesc());
+ if( wimd == NULL || !DoWriteFieldAsFixup( "m_pWrappedMethodDesc",
+ offsetof(InstantiatedMethodDesc, m_pWrappedMethodDesc),
+ fieldsize(InstantiatedMethodDesc, m_pWrappedMethodDesc),
+@@ -8101,7 +8096,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ }
+ else
+ {
+- _ASSERTE(imd->m_pDictLayout == NULL);
++ _ASSERTE(imd->m_pDictLayout.IsNull());
+ DisplayWriteFieldPointer( m_pDictLayout, NULL,
+ InstantiatedMethodDesc,
+ METHODDESCS );
+@@ -8117,7 +8112,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ else if( kind == InstantiatedMethodDesc::WrapperStubWithInstantiations )
+ {
+ PTR_InstantiatedMethodDesc wrapped =
+- PTR_InstantiatedMethodDesc(imd->m_pWrappedMethodDesc.GetValue());
++ PTR_InstantiatedMethodDesc(imd->IMD_GetWrappedMethodDesc());
+ if( CORCOMPILE_IS_POINTER_TAGGED(PTR_TO_TADDR(wrapped)) )
+ {
+ /* XXX Mon 03/27/2006
+@@ -8131,7 +8126,7 @@ void NativeImageDumper::DumpMethodDesc( PTR_MethodDesc md, PTR_Module module )
+ else
+ {
+ PTR_DictionaryLayout layout(wrapped->IsSharedByGenericMethodInstantiations()
+- ? TO_TADDR(wrapped->m_pDictLayout) : NULL );
++ ? dac_cast<TADDR>(wrapped->GetDictLayoutRaw()) : NULL );
+ dictSize = DictionaryLayout::GetFirstDictionaryBucketSize(imd->GetNumGenericMethodArgs(),
+ layout);
+ }
+diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp
+index b58ac56..cf546cd 100644
+--- a/src/vm/dllimport.cpp
++++ b/src/vm/dllimport.cpp
+@@ -4368,8 +4368,8 @@ void NDirect::PopulateNDirectMethodDesc(NDirectMethodDesc* pNMD, PInvokeStaticSi
+ else
+ {
+ EnsureWritablePages(&pNMD->ndirect);
+- pNMD->ndirect.m_pszLibName = szLibName;
+- pNMD->ndirect.m_pszEntrypointName = szEntryPointName;
++ pNMD->ndirect.m_pszLibName.SetValueMaybeNull(szLibName);
++ pNMD->ndirect.m_pszEntrypointName.SetValueMaybeNull(szEntryPointName);
+ }
+
+ #ifdef _TARGET_X86_
+diff --git a/src/vm/dynamicmethod.cpp b/src/vm/dynamicmethod.cpp
+index 2a61f97..43f4c69 100644
+--- a/src/vm/dynamicmethod.cpp
++++ b/src/vm/dynamicmethod.cpp
+@@ -272,7 +272,7 @@ DynamicMethodDesc* DynamicMethodTable::GetDynamicMethod(BYTE *psig, DWORD sigSiz
+ // the store sig part of the method desc
+ pNewMD->SetStoredMethodSig((PCCOR_SIGNATURE)psig, sigSize);
+ // the dynamic part of the method desc
+- pNewMD->m_pszMethodName = name;
++ pNewMD->m_pszMethodName.SetValueMaybeNull(name);
+
+ pNewMD->m_dwExtendedFlags = mdPublic | mdStatic | DynamicMethodDesc::nomdLCGMethod;
+
+@@ -884,16 +884,16 @@ void DynamicMethodDesc::Destroy(BOOL fDomainUnload)
+ LoaderAllocator *pLoaderAllocator = GetLoaderAllocatorForCode();
+
+ LOG((LF_BCL, LL_INFO1000, "Level3 - Destroying DynamicMethod {0x%p}\n", this));
+- if (m_pSig)
++ if (!m_pSig.IsNull())
+ {
+- delete[] (BYTE*)m_pSig;
+- m_pSig = NULL;
++ delete[] (BYTE*)m_pSig.GetValue();
++ m_pSig.SetValueMaybeNull(NULL);
+ }
+ m_cSig = 0;
+- if (m_pszMethodName)
++ if (!m_pszMethodName.IsNull())
+ {
+- delete[] m_pszMethodName;
+- m_pszMethodName = NULL;
++ delete[] m_pszMethodName.GetValue();
++ m_pszMethodName.SetValueMaybeNull(NULL);
+ }
+
+ GetLCGMethodResolver()->Destroy(fDomainUnload);
+diff --git a/src/vm/genmeth.cpp b/src/vm/genmeth.cpp
+index c50f806..d5b435b 100644
+--- a/src/vm/genmeth.cpp
++++ b/src/vm/genmeth.cpp
+@@ -465,7 +465,7 @@ InstantiatedMethodDesc::NewInstantiatedMethodDesc(MethodTable *pExactMT,
+ {
+ if (pWrappedMD->IsSharedByGenericMethodInstantiations())
+ {
+- pDL = pWrappedMD->AsInstantiatedMethodDesc()->m_pDictLayout;
++ pDL = pWrappedMD->AsInstantiatedMethodDesc()->GetDictLayoutRaw();
+ }
+ }
+ else if (getWrappedCode)
+@@ -1576,7 +1576,7 @@ void InstantiatedMethodDesc::SetupSharedMethodInstantiation(DWORD numGenericArgs
+ _ASSERTE(FitsIn<WORD>(numGenericArgs));
+ m_wNumGenericArgs = static_cast<WORD>(numGenericArgs);
+
+- m_pDictLayout = pDL;
++ m_pDictLayout.SetValueMaybeNull(pDL);
+
+
+ _ASSERTE(IMD_IsSharedByGenericMethodInstantiations());
+diff --git a/src/vm/ilstubcache.cpp b/src/vm/ilstubcache.cpp
+index ff6bdc0..3651715 100644
+--- a/src/vm/ilstubcache.cpp
++++ b/src/vm/ilstubcache.cpp
+@@ -167,7 +167,7 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
+ pMD->SetMemberDef(0);
+ pMD->SetSlot(MethodTable::NO_SLOT); // we can't ever use the slot for dynamic methods
+ // the no metadata part of the method desc
+- pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB";
++ pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB");
+ pMD->m_dwExtendedFlags = mdPublic | DynamicMethodDesc::nomdILStub;
+
+ pMD->SetTemporaryEntryPoint(pMT->GetLoaderAllocator(), pamTracker);
+@@ -292,11 +292,11 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
+ {
+ switch(dwStubFlags)
+ {
+- case ILSTUB_ARRAYOP_GET: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Get";
++ case ILSTUB_ARRAYOP_GET: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Get");
+ break;
+- case ILSTUB_ARRAYOP_SET: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Set";
++ case ILSTUB_ARRAYOP_SET: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Set");
+ break;
+- case ILSTUB_ARRAYOP_ADDRESS: pMD->m_pszMethodName = (PTR_CUTF8)"IL_STUB_Array_Address";
++ case ILSTUB_ARRAYOP_ADDRESS: pMD->m_pszMethodName.SetValue((PTR_CUTF8)"IL_STUB_Array_Address");
+ break;
+ default: _ASSERTE(!"Unknown array il stub");
+ }
+@@ -304,12 +304,12 @@ MethodDesc* ILStubCache::CreateNewMethodDesc(LoaderHeap* pCreationHeap, MethodTa
+ else
+ #endif
+ {
+- pMD->m_pszMethodName = pMD->GetILStubResolver()->GetStubMethodName();
++ pMD->m_pszMethodName.SetValue(pMD->GetILStubResolver()->GetStubMethodName());
+ }
+
+
+ #ifdef _DEBUG
+- pMD->m_pszDebugMethodName = pMD->m_pszMethodName;
++ pMD->m_pszDebugMethodName = RelativePointer<PTR_CUTF8>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(DynamicMethodDesc, pMD, m_pszMethodName));
+ pMD->m_pszDebugClassName = ILStubResolver::GetStubClassName(pMD); // must be called after type is set
+ pMD->m_pszDebugMethodSignature = FormatSig(pMD, pCreationHeap, pamTracker);
+ pMD->m_pDebugMethodTable.SetValue(pMT);
+diff --git a/src/vm/method.cpp b/src/vm/method.cpp
+index 751ceac..c8c1b9f 100644
+--- a/src/vm/method.cpp
++++ b/src/vm/method.cpp
+@@ -2919,7 +2919,7 @@ void MethodDesc::Save(DataImage *image)
+
+ if (pNewSMD->HasStoredMethodSig())
+ {
+- if (!image->IsStored((void *) pNewSMD->m_pSig))
++ if (!image->IsStored((void *) pNewSMD->m_pSig.GetValueMaybeNull()))
+ {
+ // Store signatures that doesn't need restore into a read only section.
+ DataImage::ItemKind sigItemKind = DataImage::ITEM_STORED_METHOD_SIG_READONLY;
+@@ -2935,7 +2935,7 @@ void MethodDesc::Save(DataImage *image)
+ }
+
+ if (FixupSignatureContainingInternalTypes(image,
+- (PCCOR_SIGNATURE)pNewSMD->m_pSig,
++ (PCCOR_SIGNATURE) pNewSMD->m_pSig.GetValueMaybeNull(),
+ pNewSMD->m_cSig,
+ true /*checkOnly if we will need to restore the signature without doing fixup*/))
+ {
+@@ -2943,7 +2943,7 @@ void MethodDesc::Save(DataImage *image)
+ }
+ }
+
+- image->StoreInternedStructure((void *) pNewSMD->m_pSig,
++ image->StoreInternedStructure((void *) pNewSMD->m_pSig.GetValueMaybeNull(),
+ pNewSMD->m_cSig,
+ sigItemKind,
+ 1);
+@@ -2964,9 +2964,9 @@ void MethodDesc::Save(DataImage *image)
+ if (HasMethodInstantiation())
+ {
+ InstantiatedMethodDesc* pIMD = AsInstantiatedMethodDesc();
+- if (pIMD->IMD_IsSharedByGenericMethodInstantiations() && pIMD->m_pDictLayout != NULL)
++ if (pIMD->IMD_IsSharedByGenericMethodInstantiations() && !pIMD->m_pDictLayout.IsNull())
+ {
+- pIMD->m_pDictLayout->Save(image);
++ pIMD->m_pDictLayout.GetValue()->Save(image);
+ }
+ }
+ if (IsNDirect())
+@@ -3042,9 +3042,10 @@ void MethodDesc::Save(DataImage *image)
+ if (IsDynamicMethod())
+ {
+ DynamicMethodDesc *pDynMeth = AsDynamicMethodDesc();
+- if (pDynMeth->m_pszMethodName && !image->IsStored(pDynMeth->m_pszMethodName))
+- image->StoreStructure((void *) pDynMeth->m_pszMethodName,
+- (ULONG)(strlen(pDynMeth->m_pszMethodName) + 1),
++ if (!pDynMeth->m_pszMethodName.IsNull()
++ && !image->IsStored(pDynMeth->m_pszMethodName.GetValue()))
++ image->StoreStructure((void *) pDynMeth->m_pszMethodName.GetValue(),
++ (ULONG)(strlen(pDynMeth->m_pszMethodName.GetValue()) + 1),
+ DataImage::ITEM_STORED_METHOD_NAME,
+ 1);
+ }
+@@ -3629,7 +3630,7 @@ MethodDesc::Fixup(
+ if (IsDynamicMethod())
+ {
+ image->ZeroPointerField(this, offsetof(DynamicMethodDesc, m_pResolver));
+- image->FixupPointerField(this, offsetof(DynamicMethodDesc, m_pszMethodName));
++ image->FixupRelativePointerField(this, offsetof(DynamicMethodDesc, m_pszMethodName));
+ }
+
+ if (GetClassification() == mcInstantiated)
+@@ -3645,8 +3646,8 @@ MethodDesc::Fixup(
+ {
+ if (pIMD->IMD_IsSharedByGenericMethodInstantiations())
+ {
+- pIMD->m_pDictLayout->Fixup(image, TRUE);
+- image->FixupPointerField(this, offsetof(InstantiatedMethodDesc, m_pDictLayout));
++ pIMD->m_pDictLayout.GetValue()->Fixup(image, TRUE);
++ image->FixupRelativePointerField(this, offsetof(InstantiatedMethodDesc, m_pDictLayout));
+ }
+ }
+
+@@ -3754,7 +3755,7 @@ MethodDesc::Fixup(
+ if (!pNMD->MarshalingRequired())
+ {
+ // import thunk is only needed if the P/Invoke is inlinable
+- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pImportThunkGlue));
++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pImportThunkGlue));
+ ((Precode*)pImportThunkGlue)->Fixup(image, this);
+ }
+ else
+@@ -3767,8 +3768,8 @@ MethodDesc::Fixup(
+
+ if (!IsQCall())
+ {
+- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszLibName));
+- image->FixupPointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszEntrypointName));
++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszLibName));
++ image->FixupRelativePointerField(this, offsetof(NDirectMethodDesc, ndirect.m_pszEntrypointName));
+ }
+
+ if (image->IsStored(pNMD->ndirect.m_pStubMD.GetValueMaybeNull()))
+@@ -3779,7 +3780,7 @@ MethodDesc::Fixup(
+
+ if (HasStoredSig())
+ {
+- image->FixupPointerField(this, offsetof(StoredSigMethodDesc, m_pSig));
++ image->FixupRelativePointerField(this, offsetof(StoredSigMethodDesc, m_pSig));
+
+ // The DynamicMethodDescs used for IL stubs may have a signature that refers to
+ // runtime types using ELEMENT_TYPE_INTERNAL. We need to fixup these types here.
+@@ -5512,7 +5513,7 @@ StoredSigMethodDesc::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+ {
+ SUPPORTS_DAC;
+ // 'this' already done, see below.
+- DacEnumMemoryRegion(m_pSig, m_cSig);
++ DacEnumMemoryRegion(GetSigRVA(), m_cSig);
+ }
+
+ //*******************************************************************************
+diff --git a/src/vm/method.hpp b/src/vm/method.hpp
+index 4ef6db0..41695df 100644
+--- a/src/vm/method.hpp
++++ b/src/vm/method.hpp
+@@ -2215,7 +2215,7 @@ class StoredSigMethodDesc : public MethodDesc
+ // Put the sig RVA in here - this allows us to avoid
+ // touching the method desc table when mscorlib is prejitted.
+
+- TADDR m_pSig;
++ RelativePointer<TADDR> m_pSig;
+ DWORD m_cSig;
+ #ifdef _WIN64
+ // m_dwExtendedFlags is not used by StoredSigMethodDesc itself.
+@@ -2224,10 +2224,16 @@ class StoredSigMethodDesc : public MethodDesc
+ DWORD m_dwExtendedFlags;
+ #endif
+
++ TADDR GetSigRVA()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<TADDR>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(StoredSigMethodDesc, this, m_pSig));
++ }
++
+ bool HasStoredMethodSig(void)
+ {
+ LIMITED_METHOD_DAC_CONTRACT;
+- return m_pSig != 0;
++ return !m_pSig.IsNull();
+ }
+ PCCOR_SIGNATURE GetStoredMethodSig(DWORD* sigLen = NULL)
+ {
+@@ -2238,16 +2244,16 @@ class StoredSigMethodDesc : public MethodDesc
+ }
+ #ifdef DACCESS_COMPILE
+ return (PCCOR_SIGNATURE)
+- DacInstantiateTypeByAddress(m_pSig, m_cSig, true);
++ DacInstantiateTypeByAddress(GetSigRVA(), m_cSig, true);
+ #else // !DACCESS_COMPILE
+ g_IBCLogger.LogNDirectCodeAccess(this);
+- return (PCCOR_SIGNATURE)m_pSig;
++ return (PCCOR_SIGNATURE) m_pSig.GetValueMaybeNull();
+ #endif // !DACCESS_COMPILE
+ }
+ void SetStoredMethodSig(PCCOR_SIGNATURE sig, DWORD sigBytes)
+ {
+ #ifndef DACCESS_COMPILE
+- m_pSig = (TADDR)sig;
++ m_pSig.SetValueMaybeNull((TADDR)sig);
+ m_cSig = sigBytes;
+ #endif // !DACCESS_COMPILE
+ }
+@@ -2307,7 +2313,7 @@ class DynamicMethodDesc : public StoredSigMethodDesc
+ #endif
+
+ protected:
+- PTR_CUTF8 m_pszMethodName;
++ RelativePointer<PTR_CUTF8> m_pszMethodName;
+ PTR_DynamicResolver m_pResolver;
+
+ #ifndef _WIN64
+@@ -2348,7 +2354,11 @@ public:
+ inline PTR_LCGMethodResolver GetLCGMethodResolver();
+ inline PTR_ILStubResolver GetILStubResolver();
+
+- PTR_CUTF8 GetMethodName() { LIMITED_METHOD_DAC_CONTRACT; return m_pszMethodName; }
++ PTR_CUTF8 GetMethodName()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(DynamicMethodDesc, this, m_pszMethodName));
++ }
+
+ WORD GetAttrs()
+ {
+@@ -2571,11 +2581,11 @@ public:
+ LPVOID m_pNativeNDirectTarget;
+
+ // Information about the entrypoint
+- LPCUTF8 m_pszEntrypointName;
++ RelativePointer<PTR_CUTF8> m_pszEntrypointName;
+
+ union
+ {
+- LPCUTF8 m_pszLibName;
++ RelativePointer<PTR_CUTF8> m_pszLibName;
+ DWORD m_dwECallID; // ECallID for QCalls
+ };
+
+@@ -2583,7 +2593,7 @@ public:
+ PTR_NDirectWriteableData m_pWriteableData;
+
+ #ifdef HAS_NDIRECT_IMPORT_PRECODE
+- PTR_NDirectImportThunkGlue m_pImportThunkGlue;
++ RelativePointer<PTR_NDirectImportThunkGlue> m_pImportThunkGlue;
+ #else // HAS_NDIRECT_IMPORT_PRECODE
+ NDirectImportThunkGlue m_ImportThunkGlue;
+ #endif // HAS_NDIRECT_IMPORT_PRECODE
+@@ -2706,18 +2716,27 @@ public:
+ ndirect.m_dwECallID = dwID;
+ }
+
++ PTR_CUTF8 GetLibNameRaw()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++
++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pszLibName));
++ }
++
++#ifndef DACCESS_COMPILE
+ LPCUTF8 GetLibName() const
+ {
+ LIMITED_METHOD_CONTRACT;
+
+- return IsQCall() ? "QCall" : ndirect.m_pszLibName;
++ return IsQCall() ? "QCall" : ndirect.m_pszLibName.GetValueMaybeNull();
+ }
++#endif // !DACCESS_COMPILE
+
+- LPCUTF8 GetEntrypointName() const
++ PTR_CUTF8 GetEntrypointName() const
+ {
+- LIMITED_METHOD_CONTRACT;
++ LIMITED_METHOD_DAC_CONTRACT;
+
+- return ndirect.m_pszEntrypointName;
++ return RelativePointer<PTR_CUTF8>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pszEntrypointName));
+ }
+
+ BOOL IsVarArgs() const
+@@ -2800,14 +2819,16 @@ public:
+ return ndirect.m_pWriteableData;
+ }
+
+- NDirectImportThunkGlue* GetNDirectImportThunkGlue()
++ PTR_NDirectImportThunkGlue GetNDirectImportThunkGlue()
+ {
+- LIMITED_METHOD_CONTRACT;
++ LIMITED_METHOD_DAC_CONTRACT;
++
++ TADDR base = PTR_HOST_MEMBER_TADDR(NDirectMethodDesc, this, ndirect.m_pImportThunkGlue);
+
+ #ifdef HAS_NDIRECT_IMPORT_PRECODE
+- return ndirect.m_pImportThunkGlue;
++ return RelativePointer<PTR_NDirectImportThunkGlue>::GetValueAtPtr(base);
+ #else
+- return &ndirect.m_ImportThunkGlue;
++ return dac_cast<PTR_NDirectImportThunkGlue>(base);
+ #endif
+ }
+
+@@ -3281,28 +3302,37 @@ public:
+ }
+ #endif // FEATURE_COMINTEROP
+
++ PTR_DictionaryLayout GetDictLayoutRaw()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<PTR_DictionaryLayout>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(InstantiatedMethodDesc, this, m_pDictLayout));
++ }
++
++ PTR_MethodDesc IMD_GetWrappedMethodDesc()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++
++ _ASSERTE(IMD_IsWrapperStubWithInstantiations());
++ return RelativePointer<PTR_MethodDesc>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(InstantiatedMethodDesc, this, m_pWrappedMethodDesc));
++ }
++
++#ifndef DACCESS_COMPILE
+ // Get the dictionary layout, if there is one
+ DictionaryLayout* IMD_GetDictionaryLayout()
+ {
+ WRAPPER_NO_CONTRACT;
+ if (IMD_IsWrapperStubWithInstantiations() && IMD_HasMethodInstantiation())
+- return IMD_GetWrappedMethodDesc()->AsInstantiatedMethodDesc()->m_pDictLayout;
++ {
++ InstantiatedMethodDesc* pIMD = IMD_GetWrappedMethodDesc()->AsInstantiatedMethodDesc();
++ return pIMD->m_pDictLayout.GetValueMaybeNull();
++ }
+ else
+ if (IMD_IsSharedByGenericMethodInstantiations())
+- return m_pDictLayout;
++ return m_pDictLayout.GetValueMaybeNull();
+ else
+ return NULL;
+ }
+-
+- MethodDesc* IMD_GetWrappedMethodDesc()
+- {
+- LIMITED_METHOD_CONTRACT;
+-
+- _ASSERTE(IMD_IsWrapperStubWithInstantiations());
+- return m_pWrappedMethodDesc.GetValue();
+- }
+-
+-
++#endif // !DACCESS_COMPILE
+
+ // Setup the IMD as shared code
+ void SetupSharedMethodInstantiation(DWORD numGenericArgs, TypeHandle *pPerInstInfo, DictionaryLayout *pDL);
+@@ -3349,9 +3379,9 @@ private:
+
+ friend class MethodDesc; // this fields are currently accessed by MethodDesc::Save/Restore etc.
+ union {
+- DictionaryLayout * m_pDictLayout; //SharedMethodInstantiation
++ RelativePointer<PTR_DictionaryLayout> m_pDictLayout; //SharedMethodInstantiation
+
+- FixupPointer<PTR_MethodDesc> m_pWrappedMethodDesc; // For WrapperStubWithInstantiations
++ RelativeFixupPointer<PTR_MethodDesc> m_pWrappedMethodDesc; // For WrapperStubWithInstantiations
+ };
+
+ public: // <TODO>make private: JITinterface.cpp accesses through this </TODO>
+diff --git a/src/vm/methodimpl.cpp b/src/vm/methodimpl.cpp
+index 1779c2d..c685e1c 100644
+--- a/src/vm/methodimpl.cpp
++++ b/src/vm/methodimpl.cpp
+@@ -72,7 +72,10 @@ PTR_MethodDesc MethodImpl::FindMethodDesc(DWORD slot, PTR_MethodDesc defaultRetu
+ return defaultReturn;
+ }
+
+- PTR_MethodDesc result = pImplementedMD[slotIndex]; // The method descs are not offset by one
++ DPTR(RelativePointer<PTR_MethodDesc>) pRelPtrForSlot = GetImpMDsNonNull();
++ // The method descs are not offset by one
++ TADDR base = dac_cast<TADDR>(pRelPtrForSlot) + slotIndex * sizeof(RelativePointer<MethodDesc *>);
++ PTR_MethodDesc result = RelativePointer<PTR_MethodDesc>::GetValueMaybeNullAtPtr(base);
+
+ // Prejitted images may leave NULL in this table if
+ // the methoddesc is declared in another module.
+@@ -98,13 +101,13 @@ MethodDesc *MethodImpl::RestoreSlot(DWORD index, MethodTable *pMT)
+ NOTHROW;
+ GC_NOTRIGGER;
+ FORBID_FAULT;
+- PRECONDITION(CheckPointer(pdwSlots));
++ PRECONDITION(!pdwSlots.IsNull());
+ }
+ CONTRACTL_END
+
+ MethodDesc *result;
+
+- PREFIX_ASSUME(pdwSlots != NULL);
++ PREFIX_ASSUME(!pdwSlots.IsNull());
+ DWORD slot = GetSlots()[index];
+
+ // Since the overridden method is in a different module, we
+@@ -126,8 +129,9 @@ MethodDesc *MethodImpl::RestoreSlot(DWORD index, MethodTable *pMT)
+ _ASSERTE(result != NULL);
+
+ // Don't worry about races since we would all be setting the same result
+- if (EnsureWritableExecutablePagesNoThrow(&pImplementedMD[index], sizeof(pImplementedMD[index])))
+- pImplementedMD[index] = result;
++ if (EnsureWritableExecutablePagesNoThrow(&pImplementedMD.GetValue()[index],
++ sizeof(pImplementedMD.GetValue()[index])))
++ pImplementedMD.GetValue()[index].SetValue(result);
+
+ return result;
+ }
+@@ -139,7 +143,7 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s
+ THROWS;
+ GC_NOTRIGGER;
+ PRECONDITION(CheckPointer(this));
+- PRECONDITION(pdwSlots==NULL && pImplementedMD==NULL);
++ PRECONDITION(pdwSlots.GetValueMaybeNull()==NULL && pImplementedMD.GetValueMaybeNull()==NULL);
+ INJECT_FAULT(ThrowOutOfMemory());
+ } CONTRACTL_END;
+
+@@ -149,7 +153,7 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s
+ S_SIZE_T(size) * S_SIZE_T(sizeof(DWORD)); // DWORD each for the slot numbers
+
+ // MethodDesc* for each of the implemented methods
+- S_SIZE_T cbMethodDescs = S_SIZE_T(size) * S_SIZE_T(sizeof(MethodDesc *));
++ S_SIZE_T cbMethodDescs = S_SIZE_T(size) * S_SIZE_T(sizeof(RelativePointer<MethodDesc *>));
+
+ // Need to align-up the slot entries so that the MethodDesc* array starts on a pointer boundary.
+ cbCountAndSlots.AlignUp(sizeof(MethodDesc*));
+@@ -161,29 +165,36 @@ void MethodImpl::SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD s
+ LPBYTE pAllocData = (BYTE*)pamTracker->Track(pHeap->AllocMem(cbTotal));
+
+ // Set the count and slot array
+- pdwSlots = (DWORD*)pAllocData;
++ pdwSlots.SetValue((DWORD*)pAllocData);
+
+ // Set the MethodDesc* array. Make sure to adjust for alignment.
+- pImplementedMD = (MethodDesc**)ALIGN_UP(pAllocData + cbCountAndSlots.Value(), sizeof(MethodDesc*));
++ pImplementedMD.SetValue((RelativePointer<MethodDesc*> *)ALIGN_UP(pAllocData + cbCountAndSlots.Value(), sizeof(RelativePointer <MethodDesc*>)));
+
+ // Store the count in the first entry
+- *pdwSlots = size;
++ *pdwSlots.GetValue() = size;
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+-void MethodImpl::SetData(DWORD* slots, MethodDesc** md)
++void MethodImpl::SetData(DWORD* slots, RelativePointer<MethodDesc*>* md)
+ {
+ CONTRACTL {
+ NOTHROW;
+ GC_NOTRIGGER;
+ PRECONDITION(CheckPointer(this));
+- PRECONDITION(CheckPointer(pdwSlots));
++ PRECONDITION(!pdwSlots.IsNull());
+ } CONTRACTL_END;
+
+- DWORD dwSize = *pdwSlots;
+- memcpy(&(pdwSlots[1]), slots, dwSize*sizeof(DWORD));
+- memcpy(pImplementedMD, md, dwSize*sizeof(MethodDesc*));
++ DWORD *pdwSize = pdwSlots.GetValue();
++ DWORD dwSize = *pdwSize;
++ memcpy(&(pdwSize[1]), slots, dwSize*sizeof(DWORD));
++
++ RelativePointer<MethodDesc *> *pImplMD = pImplementedMD.GetValue();
++
++ for (uint32_t i = 0; i < dwSize; ++i)
++ {
++ pImplMD[i].SetValue(md[i].GetValue());
++ }
+ }
+
+ #ifdef FEATURE_NATIVE_IMAGE_GENERATION
+@@ -194,10 +205,10 @@ void MethodImpl::Save(DataImage *image)
+ DWORD size = GetSize();
+ _ASSERTE(size > 0);
+
+- image->StoreStructure(pdwSlots, (size+1)*sizeof(DWORD),
++ image->StoreStructure(pdwSlots.GetValue(), (size+1)*sizeof(DWORD),
+ DataImage::ITEM_METHOD_DESC_COLD,
+ sizeof(DWORD));
+- image->StoreStructure(pImplementedMD, size*sizeof(MethodDesc*),
++ image->StoreStructure(pImplementedMD.GetValue(), size*sizeof(RelativePointer<MethodDesc*>),
+ DataImage::ITEM_METHOD_DESC_COLD,
+ sizeof(MethodDesc*));
+ }
+@@ -214,21 +225,22 @@ void MethodImpl::Fixup(DataImage *image, PVOID p, SSIZE_T offset)
+ // <TODO> Why not use FixupMethodDescPointer? </TODO>
+ // <TODO> Does it matter if the MethodDesc needs a restore? </TODO>
+
+- MethodDesc * pMD = pImplementedMD[iMD];
++ RelativePointer<MethodDesc *> *pRelPtr = pImplementedMD.GetValue();
++ MethodDesc * pMD = pRelPtr[iMD].GetValueMaybeNull();
+
+ if (image->CanEagerBindToMethodDesc(pMD) &&
+ image->CanHardBindToZapModule(pMD->GetLoaderModule()))
+ {
+- image->FixupPointerField(pImplementedMD, iMD * sizeof(MethodDesc *));
++ image->FixupRelativePointerField(pImplementedMD.GetValue(), iMD * sizeof(RelativePointer<MethodDesc *>));
+ }
+ else
+ {
+- image->ZeroPointerField(pImplementedMD, iMD * sizeof(MethodDesc *));
++ image->ZeroPointerField(pImplementedMD.GetValue(), iMD * sizeof(RelativePointer<MethodDesc *>));
+ }
+ }
+
+- image->FixupPointerField(p, offset + offsetof(MethodImpl, pdwSlots));
+- image->FixupPointerField(p, offset + offsetof(MethodImpl, pImplementedMD));
++ image->FixupRelativePointerField(p, offset + offsetof(MethodImpl, pdwSlots));
++ image->FixupRelativePointerField(p, offset + offsetof(MethodImpl, pImplementedMD));
+ }
+
+ #endif // FEATURE_NATIVE_IMAGE_GENERATION
+@@ -247,19 +259,20 @@ MethodImpl::EnumMemoryRegions(CLRDataEnumMemoryFlags flags)
+ // 'this' memory should already be enumerated as
+ // part of the base MethodDesc.
+
+- if (pdwSlots.IsValid() && GetSize())
++ if (GetSlotsRaw().IsValid() && GetSize())
+ {
+ ULONG32 numSlots = GetSize();
+- DacEnumMemoryRegion(dac_cast<TADDR>(pdwSlots),
++ DacEnumMemoryRegion(dac_cast<TADDR>(GetSlotsRawNonNull()),
+ (numSlots + 1) * sizeof(DWORD));
+
+- if (pImplementedMD.IsValid())
++ if (GetImpMDs().IsValid())
+ {
+- DacEnumMemoryRegion(dac_cast<TADDR>(pImplementedMD),
+- numSlots * sizeof(PTR_MethodDesc));
++ DacEnumMemoryRegion(dac_cast<TADDR>(GetImpMDsNonNull()),
++ numSlots * sizeof(RelativePointer<MethodDesc *>));
+ for (DWORD i = 0; i < numSlots; i++)
+ {
+- PTR_MethodDesc methodDesc = pImplementedMD[i];
++ DPTR(RelativePointer<PTR_MethodDesc>) pRelPtr = GetImpMDsNonNull();
++ PTR_MethodDesc methodDesc = pRelPtr[i].GetValueMaybeNull();
+ if (methodDesc.IsValid())
+ {
+ methodDesc->EnumMemoryRegions(flags);
+diff --git a/src/vm/methodimpl.h b/src/vm/methodimpl.h
+index 0646367..453f4cc 100644
+--- a/src/vm/methodimpl.h
++++ b/src/vm/methodimpl.h
+@@ -24,8 +24,8 @@ class MethodImpl
+ friend class NativeImageDumper;
+ #endif
+
+- PTR_DWORD pdwSlots; // Maintains the slots in sorted order, the first entry is the size
+- DPTR(PTR_MethodDesc) pImplementedMD;
++ RelativePointer<PTR_DWORD> pdwSlots; // Maintains the slots in sorted order, the first entry is the size
++ RelativePointer<DPTR( RelativePointer<PTR_MethodDesc> )> pImplementedMD;
+
+ public:
+
+@@ -49,18 +49,19 @@ public:
+ inline MethodDesc *GetMethodDesc()
+ { WRAPPER_NO_CONTRACT; return m_pImpl->FindMethodDesc(GetSlot(), (PTR_MethodDesc) m_pMD); }
+ };
++#endif // !DACCESS_COMPILE
+
+- ///////////////////////////////////////////////////////////////////////////////////////
+- inline MethodDesc** GetImplementedMDs()
++ inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDs()
+ {
+- CONTRACTL {
+- NOTHROW;
+- GC_NOTRIGGER;
+- PRECONDITION(CheckPointer(this));
+- } CONTRACTL_END;
+- return pImplementedMD;
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD));
++ }
++
++ inline DPTR(RelativePointer<PTR_MethodDesc>) GetImpMDsNonNull()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<DPTR(RelativePointer<PTR_MethodDesc>)>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pImplementedMD));
+ }
+-#endif // !DACCESS_COMPILE
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+ inline DWORD GetSize()
+@@ -71,10 +72,10 @@ public:
+ PRECONDITION(CheckPointer(this));
+ } CONTRACTL_END;
+
+- if(pdwSlots == NULL)
++ if(pdwSlots.IsNull())
+ return 0;
+ else
+- return *pdwSlots;
++ return *GetSlotsRawNonNull();
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+@@ -87,10 +88,22 @@ public:
+ SUPPORTS_DAC;
+ } CONTRACTL_END;
+
+- if(pdwSlots == NULL)
++ if(pdwSlots.IsNull())
+ return NULL;
+ else
+- return pdwSlots + 1;
++ return GetSlotsRawNonNull() + 1;
++ }
++
++ inline PTR_DWORD GetSlotsRaw()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<PTR_DWORD>::GetValueMaybeNullAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots));
++ }
++
++ inline PTR_DWORD GetSlotsRawNonNull()
++ {
++ LIMITED_METHOD_DAC_CONTRACT;
++ return RelativePointer<PTR_DWORD>::GetValueAtPtr(PTR_HOST_MEMBER_TADDR(MethodImpl, this, pdwSlots));
+ }
+
+ #ifndef DACCESS_COMPILE
+@@ -99,7 +112,7 @@ public:
+ void SetSize(LoaderHeap *pHeap, AllocMemTracker *pamTracker, DWORD size);
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+- void SetData(DWORD* slots, MethodDesc** md);
++ void SetData(DWORD* slots, RelativePointer<MethodDesc*> * md);
+
+ #endif // !DACCESS_COMPILE
+
+diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
+index 503c13a..df31c4a 100644
+--- a/src/vm/methodtablebuilder.cpp
++++ b/src/vm/methodtablebuilder.cpp
+@@ -6125,8 +6125,8 @@ MethodTableBuilder::InitMethodDesc(
+ AllocateFromHighFrequencyHeap(S_SIZE_T(sizeof(NDirectWriteableData)));
+
+ #ifdef HAS_NDIRECT_IMPORT_PRECODE
+- pNewNMD->ndirect.m_pImportThunkGlue = Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD,
+- GetLoaderAllocator(), GetMemTracker())->AsNDirectImportPrecode();
++ pNewNMD->ndirect.m_pImportThunkGlue.SetValue(Precode::Allocate(PRECODE_NDIRECT_IMPORT, pNewMD,
++ GetLoaderAllocator(), GetMemTracker())->AsNDirectImportPrecode());
+ #else // !HAS_NDIRECT_IMPORT_PRECODE
+ pNewNMD->GetNDirectImportThunkGlue()->Init(pNewNMD);
+ #endif // !HAS_NDIRECT_IMPORT_PRECODE
+@@ -6371,7 +6371,7 @@ MethodTableBuilder::PlaceMethodImpls()
+ // Allocate some temporary storage. The number of overrides for a single method impl
+ // cannot be greater then the number of vtable slots.
+ DWORD * slots = new (&GetThread()->m_MarshalAlloc) DWORD[bmtVT->cVirtualSlots];
+- MethodDesc ** replaced = new (&GetThread()->m_MarshalAlloc) MethodDesc*[bmtVT->cVirtualSlots];
++ RelativePointer<MethodDesc *> * replaced = new (&GetThread()->m_MarshalAlloc) RelativePointer<MethodDesc*>[bmtVT->cVirtualSlots];
+
+ DWORD iEntry = 0;
+ bmtMDMethod * pCurImplMethod = bmtMethodImpl->GetImplementationMethod(iEntry);
+@@ -6458,7 +6458,7 @@ MethodTableBuilder::WriteMethodImplData(
+ bmtMDMethod * pImplMethod,
+ DWORD cSlots,
+ DWORD * rgSlots,
+- MethodDesc ** rgDeclMD)
++ RelativePointer<MethodDesc *> * rgDeclMD)
+ {
+ STANDARD_VM_CONTRACT;
+
+@@ -6488,9 +6488,9 @@ MethodTableBuilder::WriteMethodImplData(
+ {
+ if (rgSlots[j] < rgSlots[i])
+ {
+- MethodDesc * mTmp = rgDeclMD[i];
+- rgDeclMD[i] = rgDeclMD[j];
+- rgDeclMD[j] = mTmp;
++ MethodDesc * mTmp = rgDeclMD[i].GetValue();
++ rgDeclMD[i].SetValue(rgDeclMD[j].GetValue());
++ rgDeclMD[j].SetValue(mTmp);
+
+ DWORD sTmp = rgSlots[i];
+ rgSlots[i] = rgSlots[j];
+@@ -6512,7 +6512,7 @@ MethodTableBuilder::PlaceLocalDeclaration(
+ bmtMDMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD * slots,
+- MethodDesc ** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD * pSlotIndex)
+ {
+ CONTRACTL
+@@ -6569,7 +6569,7 @@ MethodTableBuilder::PlaceLocalDeclaration(
+
+ // We implement this slot, record it
+ slots[*pSlotIndex] = pDecl->GetSlotIndex();
+- replaced[*pSlotIndex] = pDecl->GetMethodDesc();
++ replaced[*pSlotIndex].SetValue(pDecl->GetMethodDesc());
+
+ // increment the counter
+ (*pSlotIndex)++;
+@@ -6580,7 +6580,7 @@ VOID MethodTableBuilder::PlaceInterfaceDeclaration(
+ bmtRTMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD* slots,
+- MethodDesc** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD* pSlotIndex)
+ {
+ CONTRACTL {
+@@ -6685,7 +6685,7 @@ MethodTableBuilder::PlaceParentDeclaration(
+ bmtRTMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD * slots,
+- MethodDesc ** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD * pSlotIndex)
+ {
+ CONTRACTL {
+@@ -6730,7 +6730,7 @@ MethodTableBuilder::PlaceParentDeclaration(
+
+ // We implement this slot, record it
+ slots[*pSlotIndex] = pDeclMD->GetSlot();
+- replaced[*pSlotIndex] = pDeclMD;
++ replaced[*pSlotIndex].SetValue(pDeclMD);
+
+ // increment the counter
+ (*pSlotIndex)++;
+diff --git a/src/vm/methodtablebuilder.h b/src/vm/methodtablebuilder.h
+index 2aa3683..6c82e54 100644
+--- a/src/vm/methodtablebuilder.h
++++ b/src/vm/methodtablebuilder.h
+@@ -2749,7 +2749,7 @@ private:
+ bmtMDMethod * pImplMethod,
+ DWORD cSlots,
+ DWORD * rgSlots,
+- MethodDesc ** rgDeclMD);
++ RelativePointer<MethodDesc *> * rgDeclMD);
+
+ // --------------------------------------------------------------------------------------------
+ // Places a methodImpl pair where the decl is declared by the type being built.
+@@ -2758,7 +2758,7 @@ private:
+ bmtMDMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD* slots,
+- MethodDesc** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD* pSlotIndex);
+
+ // --------------------------------------------------------------------------------------------
+@@ -2768,7 +2768,7 @@ private:
+ bmtRTMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD* slots,
+- MethodDesc** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD* pSlotIndex);
+
+ // --------------------------------------------------------------------------------------------
+@@ -2778,7 +2778,7 @@ private:
+ bmtRTMethod * pDecl,
+ bmtMDMethod * pImpl,
+ DWORD* slots,
+- MethodDesc** replaced,
++ RelativePointer<MethodDesc *> * replaced,
+ DWORD* pSlotIndex);
+
+ // --------------------------------------------------------------------------------------------
+--
+2.7.4
+