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

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/coreclr/utilcode/corimage.cpp')
-rw-r--r--src/coreclr/utilcode/corimage.cpp259
1 files changed, 259 insertions, 0 deletions
diff --git a/src/coreclr/utilcode/corimage.cpp b/src/coreclr/utilcode/corimage.cpp
new file mode 100644
index 00000000000..a1aff8fe82d
--- /dev/null
+++ b/src/coreclr/utilcode/corimage.cpp
@@ -0,0 +1,259 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+//
+
+/*============================================================
+**
+** CorImage.cpp
+**
+** IMAGEHLP routines so we can avoid early binding to that DLL.
+**
+===========================================================*/
+
+#include "stdafx.h"
+#include "contract.h"
+#include <daccess.h>
+#include "corimage.h"
+#include "safemath.h"
+
+#define RTL_MEG (1024UL * 1024UL)
+#define RTLP_IMAGE_MAX_DOS_HEADER ( 256UL * RTL_MEG)
+
+// IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is
+// the same either way.
+
+#define PTR_IMAGE_FIRST_SECTION( ntheader ) \
+ PTR_IMAGE_SECTION_HEADER \
+ (dac_cast<TADDR>(ntheader) + \
+ FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + \
+ VAL16((ntheader)->FileHeader.SizeOfOptionalHeader) \
+ )
+
+#ifndef DACCESS_COMPILE
+
+IMAGE_NT_HEADERS *Cor_RtlImageNtHeader(VOID *pvBase, ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ IMAGE_NT_HEADERS *pNtHeaders = NULL;
+ if (pvBase && (pvBase != (VOID*)-1)) {
+ struct Param
+ {
+ IMAGE_DOS_HEADER *pDos;
+ ULONG FileLength;
+ IMAGE_NT_HEADERS *pNtHeaders;
+ } param;
+ param.pDos = (IMAGE_DOS_HEADER*)pvBase;
+ param.FileLength = FileLength;
+ param.pNtHeaders = pNtHeaders;
+
+ PAL_TRY(Param *, pParam, &param) {
+ if ( (pParam->pDos->e_magic == VAL16(IMAGE_DOS_SIGNATURE))
+ && ((DWORD)VAL32(pParam->pDos->e_lfanew) < RTLP_IMAGE_MAX_DOS_HEADER)
+ && ovadd_lt((DWORD)VAL32(pParam->pDos->e_lfanew), sizeof(IMAGE_FILE_HEADER) + sizeof(DWORD), pParam->FileLength)) {
+ pParam->pNtHeaders = (IMAGE_NT_HEADERS*)((BYTE*)pParam->pDos + VAL32(pParam->pDos->e_lfanew));
+ if (pParam->pNtHeaders->Signature != VAL32(IMAGE_NT_SIGNATURE))
+ pParam->pNtHeaders = NULL;
+ }
+ }
+ PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
+ param.pNtHeaders = NULL;
+ }
+ PAL_ENDTRY
+
+ pNtHeaders = param.pNtHeaders;
+ }
+ return pNtHeaders;
+}
+
+#endif // #ifndef DACCESS_COMPILE
+
+EXTERN_C PIMAGE_SECTION_HEADER
+Cor_RtlImageRvaToSection32(PTR_IMAGE_NT_HEADERS32 NtHeaders,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ ULONG i;
+ PTR_IMAGE_SECTION_HEADER NtSection;
+
+ NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
+ for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
+ if (FileLength &&
+ (((VAL32(NtSection->PointerToRawData) > FileLength)) ||
+ (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
+ return NULL;
+ if (Rva >= VAL32(NtSection->VirtualAddress) &&
+ Rva < VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
+ return NtSection;
+
+ ++NtSection;
+ }
+
+ return NULL;
+}
+
+EXTERN_C PIMAGE_SECTION_HEADER
+Cor_RtlImageRvaToSection64(PTR_IMAGE_NT_HEADERS64 NtHeaders,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ ULONG i;
+ PTR_IMAGE_SECTION_HEADER NtSection;
+
+ NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
+ for (i=0; i<VAL16(NtHeaders->FileHeader.NumberOfSections); i++) {
+ if (FileLength &&
+ (((VAL32(NtSection->PointerToRawData) > FileLength)) ||
+ (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
+ return NULL;
+ if (Rva >= VAL32(NtSection->VirtualAddress) &&
+ Rva < VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
+ return NtSection;
+
+ ++NtSection;
+ }
+
+ return NULL;
+}
+
+EXTERN_C PIMAGE_SECTION_HEADER
+Cor_RtlImageRvaToSection(PTR_IMAGE_NT_HEADERS NtHeaders,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
+ return Cor_RtlImageRvaToSection32((PTR_IMAGE_NT_HEADERS32)NtHeaders,
+ Rva, FileLength);
+ else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
+ return Cor_RtlImageRvaToSection64((PTR_IMAGE_NT_HEADERS64)NtHeaders,
+ Rva, FileLength);
+ else {
+ _ASSERTE(!"Invalid File Type");
+ return NULL;
+ }
+}
+
+EXTERN_C PBYTE Cor_RtlImageRvaToVa32(PTR_IMAGE_NT_HEADERS32 NtHeaders,
+ PBYTE Base,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ PIMAGE_SECTION_HEADER NtSection =
+ Cor_RtlImageRvaToSection32(NtHeaders,
+ Rva,
+ FileLength);
+
+ if (NtSection != NULL)
+ return (Base +
+ (Rva - VAL32(NtSection->VirtualAddress)) +
+ VAL32(NtSection->PointerToRawData));
+ else
+ return NULL;
+}
+
+EXTERN_C PBYTE Cor_RtlImageRvaToVa64(PTR_IMAGE_NT_HEADERS64 NtHeaders,
+ PBYTE Base,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ PIMAGE_SECTION_HEADER NtSection =
+ Cor_RtlImageRvaToSection64(NtHeaders,
+ Rva,
+ FileLength);
+
+ if (NtSection != NULL)
+ return (Base +
+ (Rva - VAL32(NtSection->VirtualAddress)) +
+ VAL32(NtSection->PointerToRawData));
+ else
+ return NULL;
+}
+
+EXTERN_C PBYTE Cor_RtlImageRvaToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
+ PBYTE Base,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
+ return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders,
+ Base, Rva, FileLength);
+ else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
+ return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders,
+ Base, Rva, FileLength);
+ else {
+ _ASSERTE(!"Invalid File Type");
+ return NULL;
+ }
+}
+
+EXTERN_C PBYTE Cor_RtlImageDirToVa(PTR_IMAGE_NT_HEADERS NtHeaders,
+ PBYTE Base,
+ UINT DirIndex,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ if (NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC))
+ return Cor_RtlImageRvaToVa32((PTR_IMAGE_NT_HEADERS32)NtHeaders, Base,
+ VAL32(((PTR_IMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress),
+ FileLength);
+ else if(NtHeaders->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR64_MAGIC))
+ return Cor_RtlImageRvaToVa64((PTR_IMAGE_NT_HEADERS64)NtHeaders, Base,
+ VAL32(((PTR_IMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.DataDirectory[DirIndex].VirtualAddress),
+ FileLength);
+ else {
+ _ASSERTE(!"Invalid File Type");
+ return NULL;
+ }
+}
+
+EXTERN_C PIMAGE_SECTION_HEADER
+Cor_RtlImageRvaRangeToSection(PTR_IMAGE_NT_HEADERS NtHeaders,
+ ULONG Rva,
+ ULONG Range,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ ULONG i;
+ PTR_IMAGE_SECTION_HEADER NtSection;
+
+ if (!Range)
+ return Cor_RtlImageRvaToSection(NtHeaders, Rva, FileLength);
+
+ NtSection = PTR_IMAGE_FIRST_SECTION( NtHeaders );
+ for (i=0; i<VAL16(NtHeaders->FileHeader.NumberOfSections); i++) {
+ if (FileLength &&
+ ((VAL32(NtSection->PointerToRawData) > FileLength) ||
+ (VAL32(NtSection->SizeOfRawData) > FileLength - VAL32(NtSection->PointerToRawData))))
+ return NULL;
+ if (Rva >= VAL32(NtSection->VirtualAddress) &&
+ Rva + Range <= VAL32(NtSection->VirtualAddress) + VAL32(NtSection->SizeOfRawData))
+ return NtSection;
+
+ ++NtSection;
+ }
+
+ return NULL;
+}
+
+EXTERN_C DWORD Cor_RtlImageRvaToOffset(PTR_IMAGE_NT_HEADERS NtHeaders,
+ ULONG Rva,
+ ULONG FileLength)
+{
+ LIMITED_METHOD_CONTRACT;
+ PIMAGE_SECTION_HEADER NtSection =
+ Cor_RtlImageRvaToSection(NtHeaders,
+ Rva,
+ FileLength);
+
+ if (NtSection)
+ return ((Rva - VAL32(NtSection->VirtualAddress)) +
+ VAL32(NtSection->PointerToRawData));
+ else
+ return NULL;
+}