/// <summary> /// Parses the common information entries. /// </summary> /// <param name="debugFrame">The debug frame.</param> /// <param name="ehFrame">The exception handling frames.</param> /// <param name="input">The input data for parsing configuration.</param> private static DwarfCommonInformationEntry[] ParseCommonInformationEntries(byte[] debugFrame, byte[] ehFrame, DwarfExceptionHandlingFrameParsingInput input) { List <DwarfCommonInformationEntry> entries = new List <DwarfCommonInformationEntry>(); using (DwarfMemoryReader debugFrameReader = new DwarfMemoryReader(debugFrame)) { entries.AddRange(DwarfCommonInformationEntry.ParseAll(debugFrameReader, input.DefaultAddressSize)); } using (DwarfMemoryReader ehFrameReader = new DwarfMemoryReader(ehFrame)) { entries.AddRange(DwarfExceptionHandlingCommonInformationEntry.ParseAll(ehFrameReader, input)); } return(entries.ToArray()); }
/// <summary> /// Parses the specified data for all common information entries and frame description entries. /// </summary> /// <param name="data">The data memory reader.</param> /// <param name="input">The input data for parsing configuration.</param> /// <returns>All the parsed common information entries</returns> public static DwarfExceptionHandlingCommonInformationEntry[] ParseAll(DwarfMemoryReader data, DwarfExceptionHandlingFrameParsingInput input) { Dictionary <int, DwarfExceptionHandlingCommonInformationEntry> entries = new Dictionary <int, DwarfExceptionHandlingCommonInformationEntry>(); while (!data.IsEnd) { bool is64bit; int startPosition = data.Position; ulong length = data.ReadLength(out is64bit); int endPosition = data.Position + (int)length; if (length == 0 || endPosition >= data.Data.Length) { break; } int offsetBase = data.Position; int offset = data.ReadOffset(is64bit); DwarfExceptionHandlingCommonInformationEntry entry; if (offset == 0) { entry = new DwarfExceptionHandlingCommonInformationEntry(data, endPosition, input); entries.Add(startPosition, entry); } else { int entryOffset = offsetBase - offset; if (!entries.TryGetValue(entryOffset, out entry)) { entry = ParseEntry(data, entryOffset, input); entries.Add(entryOffset, entry); } DwarfFrameDescriptionEntry description = ParseDescription(data, entry, endPosition, input); entry.FrameDescriptionEntries.Add(description); } } return(entries.Values.ToArray()); }
/// <summary> /// Parses the single entry from the specified data. /// </summary> /// <param name="data">The data memory reader.</param> /// <param name="startPosition">The start position.</param> /// <param name="input">The input data for parsing configuration.</param> /// <returns>Parsed common information entry.</returns> private static DwarfExceptionHandlingCommonInformationEntry ParseEntry(DwarfMemoryReader data, int startPosition, DwarfExceptionHandlingFrameParsingInput input) { int position = data.Position; data.Position = startPosition; bool is64bit; ulong length = data.ReadLength(out is64bit); int endPosition = data.Position + (int)length; int offset = data.ReadOffset(is64bit); if (offset != 0) { throw new Exception("Expected CommonInformationEntry"); } DwarfExceptionHandlingCommonInformationEntry entry = new DwarfExceptionHandlingCommonInformationEntry(data, endPosition, input); data.Position = position; return(entry); }
/// <summary> /// Parses frame description from the specified data memory reader. /// </summary> /// <param name="data">The data memory reader.</param> /// <param name="entry">Common information entry for parsed frame description.</param> /// <param name="endPosition">Position in the data reader where parsed frame description ends.</param> /// <param name="input">The input data for parsing configuration.</param> /// <returns>Parsed frame description.</returns> private static DwarfFrameDescriptionEntry ParseDescription(DwarfMemoryReader data, DwarfExceptionHandlingCommonInformationEntry entry, int endPosition, DwarfExceptionHandlingFrameParsingInput input) { DwarfFrameDescriptionEntry description = new DwarfFrameDescriptionEntry(); description.InitialLocation = ReadEncodedAddress(data, entry.FrameDescriptionAddressEncoding, input); description.AddressRange = ReadEncodedAddress(data, entry.FrameDescriptionAddressEncoding & DwarfExceptionHandlingEncoding.Mask, input); description.CommonInformationEntry = entry; int instructionsStart = -1; if (entry.Augmentation.Length >= 1 && entry.Augmentation[0] == 'z') { uint length = data.LEB128(); instructionsStart = data.Position + (int)length; if (entry.LanguageSpecificDataAreaEncoding != DwarfExceptionHandlingEncoding.Omit) { ulong lsdaDataFileAddress = ReadEncodedAddress(data, entry.LanguageSpecificDataAreaEncoding, input); } } if (instructionsStart >= 0) { data.Position = instructionsStart; } description.Instructions = data.ReadBlock((uint)(endPosition - data.Position)); return(description); }