From b72d5f0d6a86677095faf86e7f316f722f0606a8 Mon Sep 17 00:00:00 2001 From: Amy Yu Date: Wed, 20 Jun 2018 10:12:39 -0700 Subject: [PATCH] Make sections optional, throw more descriptive error when rva can't be converted to offset Commit migrated from https://github.com/dotnet/coreclr/commit/7aff2b734c82422c23a6a19208998abca7ddddb8 --- src/coreclr/src/tools/r2rdump/R2RReader.cs | 47 +++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/coreclr/src/tools/r2rdump/R2RReader.cs b/src/coreclr/src/tools/r2rdump/R2RReader.cs index eeced9e..aa28b78 100644 --- a/src/coreclr/src/tools/r2rdump/R2RReader.cs +++ b/src/coreclr/src/tools/r2rdump/R2RReader.cs @@ -122,17 +122,20 @@ namespace R2RDump { _mdReader = _peReader.GetMetadataReader(); - int runtimeFunctionSize = CalculateRuntimeFunctionSize(); - R2RSection runtimeFunctionSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS]; - uint nRuntimeFunctions = (uint)(runtimeFunctionSection.Size / runtimeFunctionSize); - int runtimeFunctionOffset = GetOffset(runtimeFunctionSection.RelativeVirtualAddress); - bool[] isEntryPoint = new bool[nRuntimeFunctions]; - - // initialize R2RMethods R2RMethods = new List(); - ParseMethodDefEntrypoints(isEntryPoint); - ParseInstanceMethodEntrypoints(isEntryPoint); - ParseRuntimeFunctions(isEntryPoint, runtimeFunctionOffset, runtimeFunctionSize); + if (R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS)) + { + int runtimeFunctionSize = CalculateRuntimeFunctionSize(); + R2RSection runtimeFunctionSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_RUNTIME_FUNCTIONS]; + uint nRuntimeFunctions = (uint)(runtimeFunctionSection.Size / runtimeFunctionSize); + int runtimeFunctionOffset = GetOffset(runtimeFunctionSection.RelativeVirtualAddress); + bool[] isEntryPoint = new bool[nRuntimeFunctions]; + + // initialize R2RMethods + ParseMethodDefEntrypoints(isEntryPoint); + ParseInstanceMethodEntrypoints(isEntryPoint); + ParseRuntimeFunctions(isEntryPoint, runtimeFunctionOffset, runtimeFunctionSize); + } AvailableTypes = new List(); ParseAvailableTypes(); @@ -162,6 +165,10 @@ namespace R2RDump /// private void ParseMethodDefEntrypoints(bool[] isEntryPoint) { + if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS)) + { + return; + } int methodDefEntryPointsRVA = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_METHODDEF_ENTRYPOINTS].RelativeVirtualAddress; int methodDefEntryPointsOffset = GetOffset(methodDefEntryPointsRVA); NativeArray methodEntryPoints = new NativeArray(Image, (uint)methodDefEntryPointsOffset); @@ -189,6 +196,10 @@ namespace R2RDump /// private void ParseInstanceMethodEntrypoints(bool[] isEntryPoint) { + if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS)) + { + return; + } R2RSection instMethodEntryPointSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_INSTANCE_METHOD_ENTRYPOINTS]; int instMethodEntryPointsOffset = GetOffset(instMethodEntryPointSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)instMethodEntryPointsOffset); @@ -268,6 +279,10 @@ namespace R2RDump private void ParseAvailableTypes() { + if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES)) + { + return; + } R2RSection availableTypesSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_AVAILABLE_TYPES]; int availableTypesOffset = GetOffset(availableTypesSection.RelativeVirtualAddress); NativeParser parser = new NativeParser(Image, (uint)availableTypesOffset); @@ -286,6 +301,10 @@ namespace R2RDump private string ParseCompilerIdentifier() { + if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER)) + { + return ""; + } R2RSection compilerIdentifierSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_COMPILER_IDENTIFIER]; byte[] identifier = new byte[compilerIdentifierSection.Size]; int identifierOffset = GetOffset(compilerIdentifierSection.RelativeVirtualAddress); @@ -295,6 +314,10 @@ namespace R2RDump private void ParseImportSections() { + if (!R2RHeader.Sections.ContainsKey(R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS)) + { + return; + } R2RSection importSectionsSection = R2RHeader.Sections[R2RSection.SectionType.READYTORUN_SECTION_IMPORT_SECTIONS]; int offset = GetOffset(importSectionsSection.RelativeVirtualAddress); int endOffset = offset + importSectionsSection.Size; @@ -366,6 +389,10 @@ namespace R2RDump public int GetOffset(int rva) { int index = _peReader.PEHeaders.GetContainingSectionIndex(rva); + if (index == -1) + { + throw new BadImageFormatException("Failed to convert invalid RVA to offset: " + rva); + } SectionHeader containingSection = _peReader.PEHeaders.SectionHeaders[index]; return rva - containingSection.VirtualAddress + containingSection.PointerToRawData; } -- 2.7.4