示例#1
0
        /// <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);
        }