Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

[Single-Exe] Run from bundle #26504

Merged
merged 6 commits into from
Sep 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 78 additions & 19 deletions src/binder/assemblybinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

#include "assemblybinder.hpp"
#include "assemblyname.hpp"

#include "assembly.hpp"
#include "applicationcontext.hpp"
#include "loadcontext.hpp"
Expand Down Expand Up @@ -645,19 +644,23 @@ namespace BINDER_SPACE

_ASSERTE(ppSystemAssembly != NULL);

StackSString sCoreLibDir(systemDirectory);
ReleaseHolder<Assembly> pSystemAssembly;
StackSString sCoreLib;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - it seems this move was not necessary. It is better to keep the variable definition close to its first usage.


// For normal runs, corelib is expected to be found in systemDirectory.
// For self-contained single-file bundles, corelib is expected within the bundle
// (systemDirectory is set accordingly)

StackSString sCoreLibDir(systemDirectory);
if (!sCoreLibDir.EndsWith(DIRECTORY_SEPARATOR_CHAR_W))
{
sCoreLibDir.Append(DIRECTORY_SEPARATOR_CHAR_W);
}

StackSString sCoreLib;

// At run-time, System.Private.CoreLib.dll is expected to be the NI image.
sCoreLib = sCoreLibDir;
sCoreLib.Append(CoreLibName_IL_W);

// At run-time, System.Private.CoreLib.dll is expected to be the NI image.
BOOL fExplicitBindToNativeImage = (fBindToNativeImage == true)? TRUE:FALSE;
#ifdef FEATURE_NI_BIND_FALLBACK
// Some non-Windows platforms do not automatically generate the NI image as CoreLib.dll.
Expand All @@ -667,7 +670,9 @@ namespace BINDER_SPACE
IF_FAIL_GO(AssemblyBinder::GetAssembly(sCoreLib,
TRUE /* fIsInGAC */,
fExplicitBindToNativeImage,
&pSystemAssembly));
&pSystemAssembly,
NULL /* szMDAssemblyPath */,
Bundle::ProbeAppBundle(CoreLibName_IL_W, /* pathIsBundleRelative */ true)));

*ppSystemAssembly = pSystemAssembly.Extract();

Expand Down Expand Up @@ -708,7 +713,9 @@ namespace BINDER_SPACE
IF_FAIL_GO(AssemblyBinder::GetAssembly(sMscorlibSatellite,
TRUE /* fIsInGAC */,
FALSE /* fExplicitBindToNativeImage */,
&pSystemAssembly));
&pSystemAssembly,
NULL /* szMDAssemblyPath */,
Bundle::ProbeAppBundle(sMscorlibSatellite)));

*ppSystemAssembly = pSystemAssembly.Extract();

Expand Down Expand Up @@ -873,7 +880,9 @@ namespace BINDER_SPACE
// specified. Generally only NGEN PDB generation has
// this TRUE.
fExplicitBindToNativeImage,
&pAssembly));
&pAssembly,
NULL /* szMDAssemblyPath */,
Bundle::ProbeAppBundle(assemblyPath)));
#ifdef FEATURE_VERSIONING_LOG
IF_FAIL_GO(LogAssemblyNameWhereRef(pApplicationContext, pAssembly));
#endif // FEATURE_VERSIONING_LOG
Expand Down Expand Up @@ -1106,6 +1115,13 @@ namespace BINDER_SPACE

/*
* BindByTpaList is the entry-point for the custom binding algorithm in CoreCLR.
*
* The search for assemblies will proceed in the following order:
*
* If this application is a single-file bundle, the meta-data contained in the bundle
* will be probed to find the requested assembly. If the assembly is not found,
* The list of platform assemblies (TPAs) are considered next.
*
* Platform assemblies are specified as a list of files. This list is the only set of
* assemblies that we will load as platform. They can be specified as IL or NIs.
*
Expand Down Expand Up @@ -1158,13 +1174,55 @@ namespace BINDER_SPACE
pBindResult));
}
}
else
else
{
// Is assembly on TPA list?
ReleaseHolder<Assembly> pTPAAssembly;
SString &simpleName = pRequestedAssemblyName->GetSimpleName();

// Is assembly in the bundle?
// Single-file bundle contents take precedence over TPA.
// The list of bundled assemblies is contained in the bundle manifest, and NOT in the TPA.
// Therefore the bundle is first probed using the assembly's simple name.
// If found, the assembly is loaded from the bundle.
if (Bundle::AppIsBundle())
{
SString candidates[] = { W(".dll"), W(".ni.dll") };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need the .ni.dll support - for .NET Core I don't think we use that suffix anymore...
I'm fine including it for consistency - but since we're making "larger" changes, maybe we can clean things up as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the .ni.dll stuff is still needed for managed c++ R2R at this time.


// Loop through the binding paths looking for a matching assembly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is not looping through paths, just candidate extensions - the comment is just confusing.

for (int i = 0; i < 2; i++)
{
SString assemblyFileName(simpleName);
assemblyFileName.Append(candidates[i]);

SString assemblyFilePath(Bundle::AppBundle->BasePath());
assemblyFilePath.Append(assemblyFileName);

hr = GetAssembly(assemblyFilePath,
TRUE, // fIsInGAC
FALSE, // fExplicitBindToNativeImage
&pTPAAssembly,
NULL, // szMDAssemblyPath
Bundle::ProbeAppBundle(assemblyFileName, /* pathIsBundleRelative */ true));

if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
// Any other error is fatal
IF_FAIL_GO(hr);

if (TestCandidateRefMatchesDef(pRequestedAssemblyName, pTPAAssembly->GetAssemblyName(), true /*tpaListAssembly*/))
{
// We have found the requested assembly match in the bundle with validation of the full-qualified name.
// Bind to it.
pBindResult->SetResult(pTPAAssembly);
GO_WITH_HRESULT(S_OK);
}
}
}
}

// Is assembly on TPA list?
SimpleNameToFileNameMap * tpaMap = pApplicationContext->GetTpaList();
const SimpleNameToFileNameMapEntry *pTpaEntry = tpaMap->LookupPtr(simpleName.GetUnicode());
ReleaseHolder<Assembly> pTPAAssembly;
if (pTpaEntry != nullptr)
{
if (pTpaEntry->m_wszNIFileName != nullptr)
Expand Down Expand Up @@ -1350,20 +1408,21 @@ namespace BINDER_SPACE
}

/* static */
HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath,
BOOL fIsInGAC,
HRESULT AssemblyBinder::GetAssembly(SString &assemblyPath,
BOOL fIsInGAC,

// When binding to the native image, should we
// assume assemblyPath explicitly specifies that
// NI? (If not, infer the path to the NI
// implicitly.)
BOOL fExplicitBindToNativeImage,
BOOL fExplicitBindToNativeImage,

Assembly **ppAssembly,
Assembly **ppAssembly,

// If assemblyPath refers to a native image without metadata,
// szMDAssemblyPath gives the alternative file to get metadata.
LPCTSTR szMDAssemblyPath)
LPCTSTR szMDAssemblyPath,
BundleFileLocation bundleFileLocation)
{
HRESULT hr = S_OK;

Expand All @@ -1387,7 +1446,7 @@ namespace BINDER_SPACE
LPCTSTR szAssemblyPath = const_cast<LPCTSTR>(assemblyPath.GetUnicode());

BINDER_LOG_ENTER(W("BinderAcquirePEImage"));
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage);
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, fExplicitBindToNativeImage, bundleFileLocation);
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImage"), hr);
IF_FAIL_GO(hr);

Expand All @@ -1404,7 +1463,7 @@ namespace BINDER_SPACE
BinderReleasePEImage(pNativePEImage);

BINDER_LOG_ENTER(W("BinderAcquirePEImageIL"));
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false);
hr = BinderAcquirePEImage(szAssemblyPath, &pPEImage, &pNativePEImage, false, bundleFileLocation);
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImageIL"), hr);
IF_FAIL_GO(hr);
}
Expand Down Expand Up @@ -1434,7 +1493,7 @@ namespace BINDER_SPACE
else
{
BINDER_LOG_ENTER(W("BinderAcquirePEImage"));
hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE);
hr = BinderAcquirePEImage(szMDAssemblyPath, &pPEImage, NULL, FALSE, bundleFileLocation);
BINDER_LOG_LEAVE_HR(W("BinderAcquirePEImage"), hr);
IF_FAIL_GO(hr);

Expand Down
5 changes: 4 additions & 1 deletion src/binder/coreclrbindercommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "coreclrbindercommon.h"
#include "clrprivbindercoreclr.h"
#include "clrprivbinderutil.h"
#include "bundle.h"

using namespace BINDER_SPACE;

Expand Down Expand Up @@ -177,5 +178,7 @@ HRESULT CCoreCLRBinderHelper::GetAssembly(/* in */ SString &assemblyPath,
return AssemblyBinder::GetAssembly(assemblyPath,
fIsInGAC,
fExplicitBindToNativeImage,
ppAssembly);
ppAssembly,
NULL /* szMDAssemblyPath */,
Bundle::ProbeAppBundle(assemblyPath));
}
22 changes: 12 additions & 10 deletions src/binder/inc/assembly.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@
#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
#include "clrprivbinderassemblyloadcontext.h"
#endif // !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)

STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath,
PEImage **ppPEImage,
PEImage **ppNativeImage,
BOOL fExplicitBindToNativeImage);

STDAPI BinderAcquireImport(PEImage *pPEImage,
IMDInternalImport **pIMetaDataAssemblyImport,
DWORD *pdwPAFlags,
BOOL bNativeImage);
#include "bundle.h"

STDAPI BinderAcquirePEImage(LPCTSTR szAssemblyPath,
PEImage **ppPEImage,
PEImage **ppNativeImage,
BOOL fExplicitBindToNativeImage,
BundleFileLocation bundleFileLocation);

STDAPI BinderAcquireImport(PEImage *pPEImage,
IMDInternalImport **pIMetaDataAssemblyImport,
DWORD *pdwPAFlags,
BOOL bNativeImage);

STDAPI BinderHasNativeHeader(PEImage *pPEImage,
BOOL *result);
Expand Down
12 changes: 7 additions & 5 deletions src/binder/inc/assemblybinder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "bindertypes.hpp"
#include "bindresult.hpp"
#include "coreclrbindercommon.h"
#include "bundle.h"

class CLRPrivBinderAssemblyLoadContext;
class CLRPrivBinderCoreCLR;
Expand Down Expand Up @@ -62,11 +63,12 @@ namespace BINDER_SPACE
/* in */ PEImage *pNativePEImage,
/* out */ Assembly **ppAssembly);

static HRESULT GetAssembly(/* in */ SString &assemblyPath,
/* in */ BOOL fIsInGAC,
/* in */ BOOL fExplicitBindToNativeImage,
/* out */ Assembly **ppAssembly,
/* in */ LPCTSTR szMDAssemblyPath = NULL);
static HRESULT GetAssembly(/* in */ SString &assemblyPath,
/* in */ BOOL fIsInGAC,
/* in */ BOOL fExplicitBindToNativeImage,
/* out */ Assembly **ppAssembly,
/* in */ LPCTSTR szMDAssemblyPath = NULL,
/* in */ BundleFileLocation bundleFileLocation = BundleFileLocation::Invalid());

#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
static HRESULT BindUsingHostAssemblyResolver (/* in */ INT_PTR pManagedAssemblyLoadContextToBindWithin,
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/hosts/osxbundlerun/osxbundlerun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ int corerun(const int argc, const char* argv[])
argv0AbsolutePath.c_str(),
clrFilesAbsolutePath.c_str(),
managedAssemblyAbsolutePath.c_str(),
nullptr,
managedAssemblyArgc,
managedAssemblyArgv);

Expand Down
16 changes: 14 additions & 2 deletions src/coreclr/hosts/unixcorebundle/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")

set(COREBUNDLE_SOURCES
corebundle.cpp
./bundle/dir_utils.cpp
./bundle/extractor.cpp
./bundle/file_entry.cpp
./bundle/header.cpp
./bundle/manifest.cpp
Expand Down Expand Up @@ -44,6 +42,20 @@ set(HEADERS
../unixcoreruncommon/coreruncommon.h
)

set(HEADERS
./bundle/error_codes.h
./bundle/file_entry.h
./bundle/file_type.h
./bundle/header.h
./bundle/manifest.h
./bundle/marker.h
./bundle/pal.h
./bundle/reader.h
./bundle/runner.h
./bundle/trace.h
./bundle/utils.h
)

_add_executable(corebundle
${COREBUNDLE_SOURCES}
)
Expand Down
Loading