Ejemplo n.º 1
0
        public DwarfAbbreviationItem GetOrCreate(DwarfAbbreviationItemKey itemKey)
        {
            if (!_mapKeyToItem.TryGetValue(itemKey, out var item))
            {
                item = new DwarfAbbreviationItem(_nextCode, itemKey.Tag, itemKey.HasChildren, itemKey.Descriptors)
                {
                    Parent = this
                };

                if (_mapItems.Count > 0)
                {
                    _mapItems[_nextCode] = item;
                }
                else
                {
                    _items.Add(item);
                }

                _mapKeyToItem[itemKey] = item;

                _nextCode++;
            }

            return(item);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
0
        public bool TryFindByCode(ulong code, out DwarfAbbreviationItem item)
        {
            item = null;
            if (code == 0)
            {
                return(false);
            }

            code--;

            if (_mapItems.Count > 0)
            {
                return(_mapItems.TryGetValue(code, out item));
            }

            if (code < int.MaxValue && (int)code < _items.Count)
            {
                item = _items[(int)code];
                return(true);
            }

            item = null;
            return(false);
        }
Ejemplo n.º 4
0
        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);
        }