/// <summary>
        /// Parses the data for this instance.
        /// </summary>
        /// <param name="data">The data memory reader.</param>
        /// <param name="endPosition">The end position.</param>
        /// <param name="input">The input data for parsing configuration.</param>
        private void ParseData(DwarfMemoryReader data, int endPosition, DwarfExceptionHandlingFrameParsingInput input)
        {
            Version             = data.ReadByte();
            Augmentation        = data.ReadString();
            CodeAlignmentFactor = data.LEB128();
            DataAlignmentFactor = data.SLEB128();
            if (Version == 1)
            {
                ReturnAddressRegister = data.ReadByte();
            }
            else
            {
                ReturnAddressRegister = data.LEB128();
            }
            AddressSize         = input.DefaultAddressSize;
            SegmentSelectorSize = 0;
            int instructionsStart = -1;

            for (int i = 0; i < Augmentation.Length; i++)
            {
                if (Augmentation[i] == 'z')
                {
                    uint length = data.LEB128();

                    instructionsStart = data.Position + (int)length;
                }
                else if (Augmentation[i] == 'L')
                {
                    LanguageSpecificDataAreaEncoding = (DwarfExceptionHandlingEncoding)data.ReadByte();
                }
                else if (Augmentation[i] == 'R')
                {
                    FrameDescriptionAddressEncoding = (DwarfExceptionHandlingEncoding)data.ReadByte();
                }
                else if (Augmentation[i] == 'S')
                {
                    StackFrame = true;
                }
                else if (Augmentation[i] == 'P')
                {
                    PersonalityEncoding = (DwarfExceptionHandlingEncoding)data.ReadByte();
                    PersonalityLocation = ReadEncodedAddress(data, PersonalityEncoding, input);
                }
                else
                {
                    break;
                }
            }
            if (instructionsStart >= 0)
            {
                data.Position = instructionsStart;
            }
            InitialInstructions = data.ReadBlock((uint)(endPosition - data.Position));
        }
Exemplo n.º 2
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 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>
        /// Reads encoded address from the specified data memory reader.
        /// </summary>
        /// <param name="data">The data memory reader.</param>
        /// <param name="encoding">Encoding used for storing address value.</param>
        /// <param name="input">The input data for parsing configuration.</param>
        /// <returns>Decoded address value.</returns>
        private static ulong ReadEncodedAddress(DwarfMemoryReader data, DwarfExceptionHandlingEncoding encoding, DwarfExceptionHandlingFrameParsingInput input)
        {
            bool  signExtendValue = false;
            ulong baseAddress     = 0;

            switch (encoding & DwarfExceptionHandlingEncoding.Modifiers)
            {
            case DwarfExceptionHandlingEncoding.PcRelative:
                signExtendValue = true;
                baseAddress     = (ulong)data.Position;
                if (input.PcRelativeAddress != ulong.MaxValue)
                {
                    baseAddress += input.PcRelativeAddress;
                }
                break;

            case DwarfExceptionHandlingEncoding.TextRelative:
                signExtendValue = true;
                if (input.TextAddress != ulong.MaxValue)
                {
                    baseAddress = input.TextAddress;
                }
                break;

            case DwarfExceptionHandlingEncoding.DataRelative:
                signExtendValue = true;
                if (input.DataAddress != ulong.MaxValue)
                {
                    baseAddress = input.DataAddress;
                }
                break;

            case DwarfExceptionHandlingEncoding.FunctionRelative:
                signExtendValue = true;
                break;

            case DwarfExceptionHandlingEncoding.Aligned:
            {
                int alignment = data.Position % input.DefaultAddressSize;

                if (alignment > 0)
                {
                    data.Position += input.DefaultAddressSize - alignment;
                }
            }
            break;
            }

            ulong address = 0;

            switch (encoding & DwarfExceptionHandlingEncoding.Mask)
            {
            case DwarfExceptionHandlingEncoding.Signed:
            case DwarfExceptionHandlingEncoding.AbsolutePointer:
                address = data.ReadUlong(input.DefaultAddressSize);
                break;

            case DwarfExceptionHandlingEncoding.UnsignedData2:
                address = data.ReadUshort();
                break;

            case DwarfExceptionHandlingEncoding.UnsignedData4:
                address = data.ReadUint();
                break;

            case DwarfExceptionHandlingEncoding.SignedData8:
            case DwarfExceptionHandlingEncoding.UnsignedData8:
                address = data.ReadUlong();
                break;

            case DwarfExceptionHandlingEncoding.Uleb128:
                address = data.LEB128();
                break;

            case DwarfExceptionHandlingEncoding.Sleb128:
                address = data.SLEB128();
                break;

            case DwarfExceptionHandlingEncoding.SignedData2:
                address = (ulong)(long)(short)data.ReadUshort();
                break;

            case DwarfExceptionHandlingEncoding.SignedData4:
                address = (ulong)(long)(int)data.ReadUint();
                break;
            }

            if (signExtendValue && input.DefaultAddressSize < System.Runtime.InteropServices.Marshal.SizeOf(address.GetType()))
            {
                ulong sign_bit = 1UL << ((input.DefaultAddressSize * 8) - 1);

                if ((sign_bit & address) != 0)
                {
                    ulong mask = ~sign_bit + 1;

                    address |= mask;
                }
            }

            return(baseAddress + address);
        }
        /// <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);
        }
        /// <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>
 /// Initializes a new instance of the <see cref="DwarfExceptionHandlingCommonInformationEntry"/> class.
 /// </summary>
 /// <param name="data">The data memory reader.</param>
 /// <param name="endPosition">The end position in the memory stream.</param>
 /// <param name="input">The input data for parsing configuration.</param>
 public DwarfExceptionHandlingCommonInformationEntry(DwarfMemoryReader data, int endPosition, DwarfExceptionHandlingFrameParsingInput input)
 {
     ParseData(data, endPosition, input);
 }