Пример #1
0
        protected override void Read(DwarfReader reader)
        {
            var addressRangeTable = reader.File.AddressRangeTable;

            while (reader.Offset < reader.Length)
            {
                // 7.5 Format of Debugging Information
                // - Each such contribution consists of a compilation unit header

                var startOffset = Offset;

                reader.ClearResolveAttributeReferenceWithinCompilationUnit();

                var cu = DwarfUnit.ReadInstance(reader, out var offsetEndOfUnit);
                if (cu == null)
                {
                    reader.Offset = offsetEndOfUnit;
                    continue;
                }

                reader.CurrentUnit = cu;

                // Link AddressRangeTable to Unit
                if (addressRangeTable.DebugInfoOffset == cu.Offset)
                {
                    addressRangeTable.Unit = cu;
                }

                AddUnit(cu);
            }

            reader.ResolveAttributeReferenceWithinSection();
        }
Пример #2
0
        protected override void Read(DwarfReader reader)
        {
            Offset = reader.Offset;
            while (TryReadNext(reader))
            {
            }

            Size = (ulong)reader.Offset - Offset;
        }
Пример #3
0
 protected override void Read(DwarfReader reader)
 {
     while (reader.Offset < reader.Length)
     {
         var programTable = new DwarfLineProgramTable();
         programTable.Offset = reader.Offset;
         programTable.ReadInternal(reader);
         AddLineProgramTable(programTable);
     }
 }
Пример #4
0
        private bool TryReadNext(DwarfReader reader)
        {
            var startOffset = (ulong)reader.Offset;
            var code        = reader.ReadULEB128();

            if (code == 0)
            {
                return(false);
            }

            var item = new DwarfAbbreviationItem
            {
                Offset = startOffset,
                Code   = code
            };

            var  index        = code - 1;
            bool canAddToList = _mapItems.Count == 0 && index < int.MaxValue && _items.Count == (int)index;

            item.ReadInternal(reader);

            if (canAddToList)
            {
                _items.Add(item);
                _nextCode++;
            }
            else
            {
                if (_mapItems.Count == 0)
                {
                    for (var i = 0; i < _items.Count; i++)
                    {
                        var previousItem = _items[i];
                        _mapItems.Add((ulong)i + 1, previousItem);
                    }
                    _items.Clear();
                }

                // TODO: check collisions
                if (_mapItems.ContainsKey(code))
                {
                    reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
                    return(false);
                }
                _mapItems.Add(code, item);

                _nextCode = Math.Max(code, _nextCode) + 1;
            }

            var key = new DwarfAbbreviationItemKey(item.Tag, item.HasChildren, item.Descriptors);

            _mapKeyToItem.Add(key, item);

            return(true);
        }
Пример #5
0
        protected override void Read(DwarfReader reader)
        {
            var endOffset = reader.Offset;

            while (reader.Offset < reader.Length)
            {
                var abbreviation = new DwarfAbbreviation
                {
                    Offset = endOffset
                };
                abbreviation.ReadInternal(reader);
                endOffset += abbreviation.Size;
                AddAbbreviation(abbreviation);
            }

            Size = endOffset - Offset;
        }
Пример #6
0
        protected override void Read(DwarfReader reader)
        {
            var itemTag = new DwarfTagEx(reader.ReadULEB128AsU32());

            Tag = itemTag;
            var  hasChildrenRaw = reader.ReadU8();
            bool hasChildren    = false;

            if (hasChildrenRaw == DwarfNative.DW_CHILDREN_yes)
            {
                hasChildren = true;
            }
            else if (hasChildrenRaw != DwarfNative.DW_CHILDREN_no)
            {
                reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid children {hasChildrenRaw}. Must be either {DwarfNative.DW_CHILDREN_yes} or {DwarfNative.DW_CHILDREN_no}");
                return;
            }

            HasChildren = hasChildren;

            List <DwarfAttributeDescriptor> descriptors = null;

            while (true)
            {
                var attributeName = new DwarfAttributeKindEx(reader.ReadULEB128AsU32());
                var attributeForm = new DwarfAttributeFormEx(reader.ReadULEB128AsU32());

                if (attributeForm.Value == 0 && attributeForm.Value == 0)
                {
                    break;
                }

                if (descriptors == null)
                {
                    descriptors = new List <DwarfAttributeDescriptor>(1);
                }
                descriptors.Add(new DwarfAttributeDescriptor(attributeName, attributeForm));
            }

            Descriptors = descriptors != null ? new DwarfAttributeDescriptors(descriptors.ToArray()) : new DwarfAttributeDescriptors();

            Size = reader.Offset - Offset;
        }
Пример #7
0
        protected override void Read(DwarfReader reader)
        {
            Offset = reader.Offset;
            var size = reader.ReadULEB128();

            OperationLengthInBytes = size;
            var endPosition = reader.Offset + size;

            while (reader.Offset < endPosition)
            {
                var op = new DwarfOperation()
                {
                    Offset = reader.Offset
                };
                op.ReadInternal(reader);
                AddOperation(op);
            }

            Size = reader.Offset - Offset;
        }
Пример #8
0
        private static ulong ReadEncodedValue(DwarfReader reader, DwarfOperationKind kind, out byte size)
        {
            size = reader.ReadU8();
            switch (size)
            {
            case 0:
                return(reader.ReadUInt());

            case 1:
                return(reader.ReadU8());

            case 2:
                return(reader.ReadU16());

            case 4:
                return(reader.ReadU32());

            case 8:
                return(reader.ReadU64());

            default:
                throw new InvalidOperationException($"Invalid Encoded address size {size} for {kind}");
            }
        }
Пример #9
0
 protected override void Read(DwarfReader reader)
 {
     // This is implemented in DwarfLineSection
 }
Пример #10
0
        protected override void Read(DwarfReader reader)
        {
            Offset = reader.Offset;
            var unitLength = reader.ReadUnitLength();

            Is64BitEncoding = reader.Is64BitEncoding;
            Version         = reader.ReadU16();

            if (Version != 2)
            {
                reader.Diagnostics.Error(DiagnosticId.DWARF_ERR_VersionNotSupported, $"Version {Version} for .debug_aranges not supported");
                return;
            }

            DebugInfoOffset = reader.ReadUIntFromEncoding();

            AddressSize = reader.ReadAddressSize();

            var segment_selector_size = (DwarfAddressSize)reader.ReadU8();

            SegmentSelectorSize = segment_selector_size;

            var align = (ulong)segment_selector_size + (ulong)AddressSize * 2;

            // SPECS 7.21: The first tuple following the header in each set begins at an offset that is a multiple of the size of a single tuple
            reader.Offset = AlignHelper.AlignToUpper(reader.Offset, align);

            while (true)
            {
                ulong segment = 0;
                switch (segment_selector_size)
                {
                case DwarfAddressSize.Bit8:
                    segment = reader.ReadU8();
                    break;

                case DwarfAddressSize.Bit16:
                    segment = reader.ReadU16();
                    break;

                case DwarfAddressSize.Bit32:
                    segment = reader.ReadU32();
                    break;

                case DwarfAddressSize.Bit64:
                    segment = reader.ReadU64();
                    break;

                case DwarfAddressSize.None:
                    break;
                }

                ulong address = 0;
                ulong length  = 0;
                switch (AddressSize)
                {
                case DwarfAddressSize.Bit8:
                    address = reader.ReadU8();
                    length  = reader.ReadU8();
                    break;

                case DwarfAddressSize.Bit16:
                    address = reader.ReadU16();
                    length  = reader.ReadU16();
                    break;

                case DwarfAddressSize.Bit32:
                    address = reader.ReadU32();
                    length  = reader.ReadU32();
                    break;

                case DwarfAddressSize.Bit64:
                    address = reader.ReadU64();
                    length  = reader.ReadU64();
                    break;
                }

                if (segment == 0 && address == 0 && length == 0)
                {
                    break;
                }

                Ranges.Add(new DwarfAddressRange(segment, address, length));
            }

            Size = reader.Offset - Offset;
        }
Пример #11
0
        protected override void Read(DwarfReader reader)
        {
            Offset = reader.Offset;
            var kind = new DwarfOperationKindEx(reader.ReadU8());

            Kind = kind;

            switch (kind.Value)
            {
            case DwarfOperationKind.Addr:
                Operand1.U64 = reader.ReadUInt();
                break;

            case DwarfOperationKind.Const1u:
                Operand1.U64 = reader.ReadU8();
                break;

            case DwarfOperationKind.Const1s:
                Operand1.I64 = reader.ReadI8();
                break;

            case DwarfOperationKind.Const2u:
                Operand1.U64 = reader.ReadU16();
                break;

            case DwarfOperationKind.Const2s:
                Operand1.I64 = reader.ReadI16();
                break;

            case DwarfOperationKind.Const4u:
                Operand1.U64 = reader.ReadU32();
                break;

            case DwarfOperationKind.Const4s:
                Operand1.I64 = reader.ReadU32();
                break;

            case DwarfOperationKind.Const8u:
                Operand1.U64 = reader.ReadU64();
                break;

            case DwarfOperationKind.Const8s:
                Operand1.I64 = reader.ReadI64();
                break;

            case DwarfOperationKind.Constu:
                Operand1.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.Consts:
                Operand1.I64 = reader.ReadILEB128();
                break;

            case DwarfOperationKind.Deref:
            case DwarfOperationKind.Dup:
            case DwarfOperationKind.Drop:
            case DwarfOperationKind.Over:
            case DwarfOperationKind.Swap:
            case DwarfOperationKind.Rot:
            case DwarfOperationKind.Xderef:
            case DwarfOperationKind.Abs:
            case DwarfOperationKind.And:
            case DwarfOperationKind.Div:
            case DwarfOperationKind.Minus:
            case DwarfOperationKind.Mod:
            case DwarfOperationKind.Mul:
            case DwarfOperationKind.Neg:
            case DwarfOperationKind.Not:
            case DwarfOperationKind.Or:
            case DwarfOperationKind.Plus:
            case DwarfOperationKind.Shl:
            case DwarfOperationKind.Shr:
            case DwarfOperationKind.Shra:
            case DwarfOperationKind.Xor:
            case DwarfOperationKind.Eq:
            case DwarfOperationKind.Ge:
            case DwarfOperationKind.Gt:
            case DwarfOperationKind.Le:
            case DwarfOperationKind.Lt:
            case DwarfOperationKind.Ne:
            case DwarfOperationKind.Nop:
            case DwarfOperationKind.PushObjectAddress:
            case DwarfOperationKind.FormTlsAddress:
            case DwarfOperationKind.CallFrameCfa:
                break;

            case DwarfOperationKind.Pick:
                Operand1.U64 = reader.ReadU8();
                break;

            case DwarfOperationKind.PlusUconst:
                Operand1.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.Bra:
            case DwarfOperationKind.Skip:
                // TODO: resolve branches to DwarfOperation
                Operand1.I64 = reader.ReadI16();
                break;

            case DwarfOperationKind.Lit0:
            case DwarfOperationKind.Lit1:
            case DwarfOperationKind.Lit2:
            case DwarfOperationKind.Lit3:
            case DwarfOperationKind.Lit4:
            case DwarfOperationKind.Lit5:
            case DwarfOperationKind.Lit6:
            case DwarfOperationKind.Lit7:
            case DwarfOperationKind.Lit8:
            case DwarfOperationKind.Lit9:
            case DwarfOperationKind.Lit10:
            case DwarfOperationKind.Lit11:
            case DwarfOperationKind.Lit12:
            case DwarfOperationKind.Lit13:
            case DwarfOperationKind.Lit14:
            case DwarfOperationKind.Lit15:
            case DwarfOperationKind.Lit16:
            case DwarfOperationKind.Lit17:
            case DwarfOperationKind.Lit18:
            case DwarfOperationKind.Lit19:
            case DwarfOperationKind.Lit20:
            case DwarfOperationKind.Lit21:
            case DwarfOperationKind.Lit22:
            case DwarfOperationKind.Lit23:
            case DwarfOperationKind.Lit24:
            case DwarfOperationKind.Lit25:
            case DwarfOperationKind.Lit26:
            case DwarfOperationKind.Lit27:
            case DwarfOperationKind.Lit28:
            case DwarfOperationKind.Lit29:
            case DwarfOperationKind.Lit30:
            case DwarfOperationKind.Lit31:
                Operand1.U64 = (ulong)((byte)kind.Value - (byte)DwarfOperationKind.Lit0);
                break;

            case DwarfOperationKind.Reg0:
            case DwarfOperationKind.Reg1:
            case DwarfOperationKind.Reg2:
            case DwarfOperationKind.Reg3:
            case DwarfOperationKind.Reg4:
            case DwarfOperationKind.Reg5:
            case DwarfOperationKind.Reg6:
            case DwarfOperationKind.Reg7:
            case DwarfOperationKind.Reg8:
            case DwarfOperationKind.Reg9:
            case DwarfOperationKind.Reg10:
            case DwarfOperationKind.Reg11:
            case DwarfOperationKind.Reg12:
            case DwarfOperationKind.Reg13:
            case DwarfOperationKind.Reg14:
            case DwarfOperationKind.Reg15:
            case DwarfOperationKind.Reg16:
            case DwarfOperationKind.Reg17:
            case DwarfOperationKind.Reg18:
            case DwarfOperationKind.Reg19:
            case DwarfOperationKind.Reg20:
            case DwarfOperationKind.Reg21:
            case DwarfOperationKind.Reg22:
            case DwarfOperationKind.Reg23:
            case DwarfOperationKind.Reg24:
            case DwarfOperationKind.Reg25:
            case DwarfOperationKind.Reg26:
            case DwarfOperationKind.Reg27:
            case DwarfOperationKind.Reg28:
            case DwarfOperationKind.Reg29:
            case DwarfOperationKind.Reg30:
            case DwarfOperationKind.Reg31:
                Operand1.U64 = (ulong)kind.Value - (ulong)DwarfOperationKind.Reg0;
                break;

            case DwarfOperationKind.Breg0:
            case DwarfOperationKind.Breg1:
            case DwarfOperationKind.Breg2:
            case DwarfOperationKind.Breg3:
            case DwarfOperationKind.Breg4:
            case DwarfOperationKind.Breg5:
            case DwarfOperationKind.Breg6:
            case DwarfOperationKind.Breg7:
            case DwarfOperationKind.Breg8:
            case DwarfOperationKind.Breg9:
            case DwarfOperationKind.Breg10:
            case DwarfOperationKind.Breg11:
            case DwarfOperationKind.Breg12:
            case DwarfOperationKind.Breg13:
            case DwarfOperationKind.Breg14:
            case DwarfOperationKind.Breg15:
            case DwarfOperationKind.Breg16:
            case DwarfOperationKind.Breg17:
            case DwarfOperationKind.Breg18:
            case DwarfOperationKind.Breg19:
            case DwarfOperationKind.Breg20:
            case DwarfOperationKind.Breg21:
            case DwarfOperationKind.Breg22:
            case DwarfOperationKind.Breg23:
            case DwarfOperationKind.Breg24:
            case DwarfOperationKind.Breg25:
            case DwarfOperationKind.Breg26:
            case DwarfOperationKind.Breg27:
            case DwarfOperationKind.Breg28:
            case DwarfOperationKind.Breg29:
            case DwarfOperationKind.Breg30:
            case DwarfOperationKind.Breg31:
                Operand1.U64 = (ulong)kind.Value - (ulong)DwarfOperationKind.Breg0;
                Operand2.I64 = reader.ReadILEB128();
                break;

            case DwarfOperationKind.Regx:
                Operand1.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.Fbreg:
                Operand1.I64 = reader.ReadILEB128();
                break;

            case DwarfOperationKind.Bregx:
                Operand1.U64 = reader.ReadULEB128();
                Operand2.I64 = reader.ReadILEB128();
                break;

            case DwarfOperationKind.Piece:
                Operand1.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.DerefSize:
                Operand1.U64 = reader.ReadU8();
                break;

            case DwarfOperationKind.XderefSize:
                Operand1.U64 = reader.ReadU8();
                break;

            case DwarfOperationKind.Call2:
            {
                var offset = reader.ReadU16();
                var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                reader.ResolveAttributeReferenceWithinSection(dieRef, false);
                break;
            }

            case DwarfOperationKind.Call4:
            {
                var offset = reader.ReadU32();
                var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                reader.ResolveAttributeReferenceWithinSection(dieRef, false);
                break;
            }

            case DwarfOperationKind.CallRef:
            {
                var offset = reader.ReadUIntFromEncoding();
                var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                reader.ResolveAttributeReferenceWithinSection(dieRef, false);
                break;
            }

            case DwarfOperationKind.BitPiece:
                Operand1.U64 = reader.ReadULEB128();
                Operand2.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.ImplicitValue:
            {
                var length = reader.ReadULEB128();
                Operand0 = reader.ReadAsStream(length);
                break;
            }

            case DwarfOperationKind.StackValue:
                break;

            case DwarfOperationKind.ImplicitPointer:
            case DwarfOperationKind.GNUImplicitPointer:
            {
                ulong offset;
                //  a reference to a debugging information entry that describes the dereferenced object’s value
                if (reader.CurrentUnit.Version == 2)
                {
                    offset = reader.ReadUInt();
                }
                else
                {
                    offset = reader.ReadUIntFromEncoding();
                }
                //  a signed number that is treated as a byte offset from the start of that value
                Operand1.I64 = reader.ReadILEB128();

                if (offset != 0)
                {
                    var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                    reader.ResolveAttributeReferenceWithinSection(dieRef, false);
                }
                break;
            }

            case DwarfOperationKind.Addrx:
            case DwarfOperationKind.GNUAddrIndex:
            case DwarfOperationKind.Constx:
            case DwarfOperationKind.GNUConstIndex:
                Operand1.U64 = reader.ReadULEB128();
                break;

            case DwarfOperationKind.EntryValue:
            case DwarfOperationKind.GNUEntryValue:
            {
                var subExpression = new DwarfExpression();
                subExpression.ReadInternal(reader);
                Operand0 = subExpression;
                break;
            }

            case DwarfOperationKind.ConstType:
            case DwarfOperationKind.GNUConstType:
            {
                // The DW_OP_const_type operation takes three operands

                // The first operand is an unsigned LEB128 integer that represents the offset
                // of a debugging information entry in the current compilation unit, which
                // must be a DW_TAG_base_type entry that provides the type of the constant provided
                var offset = reader.ReadULEB128();
                if (offset != 0)
                {
                    var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                    reader.ResolveAttributeReferenceWithinCompilationUnit(dieRef, false);
                }
                Operand1.U64 = ReadEncodedValue(reader, kind, out var sizeOfEncodedValue);
                // Encode size of encoded value in Operand1
                Operand2.U64 = sizeOfEncodedValue;
                break;
            }

            case DwarfOperationKind.RegvalType:
            case DwarfOperationKind.GNURegvalType:
            {
                // The DW_OP_regval_type operation provides the contents of a given register
                // interpreted as a value of a given type

                // The first operand is an unsigned LEB128 number, which identifies a register
                // whose contents is to be pushed onto the stack
                Operand1.U64 = reader.ReadULEB128();

                // The second operand is an unsigned LEB128 number that represents the offset
                // of a debugging information entry in the current compilation unit
                var offset = reader.ReadULEB128();
                if (offset != 0)
                {
                    var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                    reader.ResolveAttributeReferenceWithinCompilationUnit(dieRef, false);
                }
                break;
            }

            case DwarfOperationKind.DerefType:
            case DwarfOperationKind.GNUDerefType:
            case DwarfOperationKind.XderefType:
            {
                // The DW_OP_deref_type operation behaves like the DW_OP_deref_size operation:
                // it pops the top stack entry and treats it as an address.

                // This operand is a 1-byte unsigned integral constant whose value which is the
                // same as the size of the base type referenced by the second operand
                Operand1.U64 = reader.ReadU8();

                // The second operand is an unsigned LEB128 number that represents the offset
                // of a debugging information entry in the current compilation unit
                var offset = reader.ReadULEB128();
                if (offset != 0)
                {
                    var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                    reader.ResolveAttributeReferenceWithinCompilationUnit(dieRef, false);
                }
                break;
            }

            case DwarfOperationKind.Convert:
            case DwarfOperationKind.GNUConvert:
            case DwarfOperationKind.Reinterpret:
            case DwarfOperationKind.GNUReinterpret:
            {
                ulong offset = reader.ReadULEB128();
                if (offset != 0)
                {
                    var dieRef = new DwarfReader.DwarfDIEReference(offset, this, DwarfExpressionLocationDIEReferenceResolverInstance);
                    reader.ResolveAttributeReferenceWithinCompilationUnit(dieRef, false);
                }
                break;
            }

            case DwarfOperationKind.GNUPushTlsAddress:
            case DwarfOperationKind.GNUUninit:
                break;

            case DwarfOperationKind.GNUEncodedAddr:
            {
                Operand1.U64 = ReadEncodedValue(reader, kind, out var sizeOfEncodedValue);
                Operand2.U64 = sizeOfEncodedValue;
                break;
            }

            case DwarfOperationKind.GNUParameterRef:
                Operand1.U64 = reader.ReadU32();
                break;

            default:
                throw new NotSupportedException($"The {nameof(DwarfOperationKind)} {kind} is not supported");
            }

            // Store the size of the current op
            Size = reader.Offset - Offset;
        }
Пример #12
0
 protected override void Read(DwarfReader reader)
 {
 }