Welcome to mirror list, hosted at ThFree Co, Russian Federation.

nativeimage.h « vm « coreclr « src - github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 447e600297ae3e3a3bb7fd0cc8e764fe18865c5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#ifndef _NATIVEIMAGE_H
#define _NATIVEIMAGE_H

#include "readytoruninfo.h"

// This structure is used in NativeImage to map simple names of component assemblies
// to their indices within the component assembly header table.
struct AssemblyNameIndex
{
    LPCUTF8 Name;
    int32_t Index;
    
    AssemblyNameIndex() : Name(NULL), Index(-1) {}
    AssemblyNameIndex(LPCUTF8 name, int32_t index) : Name(name), Index(index) {}
    
    static AssemblyNameIndex GetNull() { return AssemblyNameIndex(); }
    bool IsNull() const { return Index < 0; }
};

class AssemblyNameIndexHashTraits : public NoRemoveSHashTraits< DefaultSHashTraits<AssemblyNameIndex> >
{
public:
    // Similar to BaseAssemblySpec::CompareStrings, we're using temporary SStrings that throw
    // for case-insensitive UTF8 assembly name comparisons.
    static const bool s_NoThrow = false;

    typedef LPCUTF8 key_t;

    static AssemblyNameIndex Null() { return AssemblyNameIndex::GetNull(); }
    static bool IsNull(const AssemblyNameIndex& e) { return e.IsNull(); }

    static LPCUTF8 GetKey(const AssemblyNameIndex& assemblyNameIndex) { return assemblyNameIndex.Name; }
    static BOOL Equals(LPCUTF8 a, LPCUTF8 b);
    static count_t Hash(LPCUTF8 a);
};

typedef DPTR(class NativeImage) PTR_NativeImage;

class NativeImageIndexTraits : public NoRemoveSHashTraits<MapSHashTraits<LPCUTF8, PTR_NativeImage>>
{
public:
    // Similar to BaseAssemblySpec::CompareStrings, we're using temporary SStrings that throw
    // for case-insensitive UTF8 assembly name comparisons.
    static const bool s_NoThrow = false;

    static LPCUTF8 GetKey(const KeyValuePair<LPCUTF8, PTR_NativeImage>& e) { return e.Key(); }
    static BOOL Equals(LPCUTF8 a, LPCUTF8 b);
    static count_t Hash(LPCUTF8 a);

    static KeyValuePair<LPCUTF8, PTR_NativeImage> Null() { LIMITED_METHOD_CONTRACT; return KeyValuePair<LPCUTF8, PTR_NativeImage>(nullptr, PTR_NativeImage(nullptr)); }
    static KeyValuePair<LPCUTF8, PTR_NativeImage> Deleted() { LIMITED_METHOD_CONTRACT; return KeyValuePair<LPCUTF8, PTR_NativeImage>(nullptr, PTR_NativeImage(nullptr)); }
    static bool IsNull(const KeyValuePair<LPCUTF8, PTR_NativeImage>& e) { LIMITED_METHOD_CONTRACT; return e.Key() == nullptr; }
    static bool IsDeleted(const KeyValuePair<LPCUTF8, PTR_NativeImage>& e) { return e.Key() == nullptr; }
};

class AssemblyLoadContext;
class ReadyToRunInfo;
class PEFile;
class PEImage;

// This class represents a  ReadyToRun image with native OS-specific envelope. As of today,
// this file format is used as the compiled native code cache in composite R2R Crossgen2
// build mode. Moving forward we plan to add support for OS-specific native executables
// (ELF on Linux, MachO on OSX).
//
// The native image is identified by a well-known public export 'RTR_HEADER' pointing to the
// master READYTORUN_HEADER structure for the entire file. For composite R2R executables
// built by crossgenning a larger number of input MSIL assemblies the READYTORUN_HEADER
// contains a section named ComponentAssemblies that points to READYTORUN_CORE_HEADER
// structures representing the individual component assemblies and per-assembly sections.
class NativeImage
{
private:
    // Points to the OwnerCompositeExecutable section content within the component MSIL module
    LPCUTF8 m_fileName;

    AssemblyLoadContext *m_pAssemblyLoadContext;
    ReadyToRunInfo *m_pReadyToRunInfo;
    IMDInternalImport *m_pManifestMetadata;
    PEImageLayout *m_pImageLayout;
    PTR_Assembly *m_pNativeMetadataAssemblyRefMap;
    
    IMAGE_DATA_DIRECTORY *m_pComponentAssemblies;
    IMAGE_DATA_DIRECTORY *m_pComponentAssemblyMvids;
    uint32_t m_componentAssemblyCount;
    uint32_t m_manifestAssemblyCount;
    SHash<AssemblyNameIndexHashTraits> m_assemblySimpleNameToIndexMap;
    
    Crst m_eagerFixupsLock;
    bool m_eagerFixupsHaveRun;

private:
    NativeImage(AssemblyLoadContext *pAssemblyLoadContext, PEImageLayout *peImageLayout, LPCUTF8 imageFileName);

protected:
    void Initialize(READYTORUN_HEADER *header, LoaderAllocator *loaderAllocator, AllocMemTracker *pamTracker);

public:
    ~NativeImage();

    static NativeImage *Open(
        Module *componentModule,
        LPCUTF8 nativeImageFileName,
        AssemblyLoadContext *pAssemblyLoadContext,
        LoaderAllocator *pLoaderAllocator,
        /* out */ bool *isNewNativeImage);

    Crst *EagerFixupsLock() { return &m_eagerFixupsLock; }
    bool EagerFixupsHaveRun() const { return m_eagerFixupsHaveRun; }
    void SetEagerFixupsHaveRun() { m_eagerFixupsHaveRun = true; }
    LPCUTF8 GetFileName() const { return m_fileName; }

    uint32_t GetComponentAssemblyCount() const { return m_componentAssemblyCount; }
    ReadyToRunInfo *GetReadyToRunInfo() const { return m_pReadyToRunInfo; }
    IMDInternalImport *GetManifestMetadata() const { return m_pManifestMetadata; }
    uint32_t GetManifestAssemblyCount() const { return m_manifestAssemblyCount; }
    PTR_Assembly *GetManifestMetadataAssemblyRefMap() { return m_pNativeMetadataAssemblyRefMap; }
    AssemblyLoadContext *GetAssemblyLoadContext() const { return m_pAssemblyLoadContext; }

    Assembly *LoadManifestAssembly(uint32_t rowid, DomainAssembly *pParentAssembly);
    
    PTR_READYTORUN_CORE_HEADER GetComponentAssemblyHeader(LPCUTF8 assemblySimpleName);

    void CheckAssemblyMvid(Assembly *assembly) const;

private:
    IMDInternalImport *LoadManifestMetadata();
};

#endif