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(); }
protected override void Read(DwarfReader reader) { Offset = reader.Offset; while (TryReadNext(reader)) { } Size = (ulong)reader.Offset - Offset; }
protected override void Read(DwarfReader reader) { while (reader.Offset < reader.Length) { var programTable = new DwarfLineProgramTable(); programTable.Offset = reader.Offset; programTable.ReadInternal(reader); AddLineProgramTable(programTable); } }
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); }
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; }
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; }
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; }
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}"); } }
protected override void Read(DwarfReader reader) { // This is implemented in DwarfLineSection }
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; }
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; }
protected override void Read(DwarfReader reader) { }