private bool TryReadInternal(DwarfReaderWriter reader, ulong abbreviationOffset, DiagnosticBag diagnostics)
        {
            reader.Offset = abbreviationOffset;
            while (TryReadNext(reader, diagnostics))
            {
            }

            return(!diagnostics.HasErrors);
        }
 public static bool TryRead(DwarfReaderWriter reader, ulong abbreviationOffset, out DwarfAbbreviation abbrev, out DiagnosticBag diagnostics)
 {
     if (reader == null)
     {
         throw new ArgumentNullException(nameof(reader));
     }
     abbrev      = new DwarfAbbreviation();
     diagnostics = new DiagnosticBag();
     return(abbrev.TryReadInternal(reader, abbreviationOffset, diagnostics));
 }
 public static DwarfAbbreviation Read(DwarfReaderWriter reader, ulong abbreviationOffset)
 {
     if (reader == null)
     {
         throw new ArgumentNullException(nameof(reader));
     }
     if (TryRead(reader, abbreviationOffset, out var abbrev, out var diagnostics))
     {
         return(abbrev);
     }
     throw new ObjectFileException($"Unexpected error while trying to read abbreviation at offset {abbreviationOffset}", diagnostics);
 }
示例#4
0
        public DwarfAbbreviation Read(ulong abbreviationOffset)
        {
            var reader = new DwarfReaderWriter(Stream, true);

            return(DwarfAbbreviation.Read(reader, abbreviationOffset));
        }
        private bool TryReadNext(DwarfReaderWriter reader, DiagnosticBag diagnostics)
        {
            var code = reader.ReadLEB128();

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

            var item = new DwarfAbbreviationItem();

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

            item.Tag = reader.ReadLEB128As <DwarfTag>();
            var  hasChildrenRaw = reader.ReadU8();
            bool hasChildren    = false;

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

            item.Code = code;

            item.HasChildren = hasChildren;

            if (canAddToList)
            {
                _items.Add(item);
            }
            else
            {
                if (_mapItems == null)
                {
                    _mapItems = new Dictionary <ulong, DwarfAbbreviationItem>();
                    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))
                {
                    diagnostics.Error(DiagnosticId.DWARF_ERR_InvalidData, $"Invalid code {code} found while another code already exists in this abbreviation.");
                    return(false);
                }
                _mapItems.Add(code, item);
            }

            List <DwarfAttributeDescriptor> descriptors = null;

            while (true)
            {
                var attributeName = reader.ReadLEB128As <DwarfAttributeName>();
                var attributeForm = reader.ReadLEB128As <DwarfAttributeForm>();

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

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

            if (descriptors != null)
            {
                item.Descriptors = descriptors;
            }

            return(true);
        }