Beispiel #1
0
 public void ResolveTypedefs(ObjectFile objectFile)
 {
     foreach (var member in _members)
     {
         member.ResolveTypedef(objectFile);
     }
 }
Beispiel #2
0
 public void ResolveTypedef(ObjectFile objectFile)
 {
     MemberType.ResolveTypedef(objectFile);
 }
Beispiel #3
0
        public Block(BinaryReader reader, uint startOffset, uint startLine, ObjectFile objectFile)
        {
            StartOffset = startOffset;
            _startLine  = startLine;

            while (true)
            {
                var typedValue = new TypedValue(reader);

                if (reader.SkipSld(typedValue))
                {
                    continue;
                }

                // FIXME: fake type resolution
                switch (typedValue.Type & 0x7f)
                {
                case TypedValue.Block:
                    _subBlocks.Add(new Block(reader, (uint)typedValue.Value, reader.ReadUInt32(),
                                             objectFile));
                    break;

                case TypedValue.BlockEnd:
                    EndOffset = (uint)typedValue.Value;
                    _endLine  = reader.ReadUInt32();
                    return;

                case TypedValue.Definition:
                {
                    var taggedSymbol = reader.ReadTaggedSymbol(false);
                    var memberName   = reader.ReadPascalString();
                    Debug.Assert(!string.IsNullOrEmpty(memberName));
                    taggedSymbol.ResolveTypedef(objectFile);
                    switch (taggedSymbol.Type)
                    {
                    case SymbolType.AutoVar:
                        _vars.Add($"{taggedSymbol.AsCode(memberName)}; // stack offset {typedValue.Value}");
                        break;

                    case SymbolType.Register:
                        _vars.Add($"{taggedSymbol.AsCode(memberName)}; // ${(Register) typedValue.Value}");
                        break;

                    case SymbolType.Static:
                        _vars.Add(
                            $"static {taggedSymbol.AsCode(memberName)}; // offset 0x{typedValue.Value:x}");
                        break;

                    case SymbolType.Typedef:
                        _typedefs.Add(memberName, taggedSymbol);
                        break;

                    case SymbolType.Label:
                        _labels.Add(new Label(typedValue, memberName));
                        break;

                    default:
                        throw new Exception($"Unexpected {nameof(TaggedSymbol)} {taggedSymbol.Type}");
                    }

                    break;
                }

                case TypedValue.ArrayDefinition:
                {
                    var taggedSymbol = reader.ReadTaggedSymbol(true);
                    var memberName   = reader.ReadPascalString();
                    Debug.Assert(!string.IsNullOrEmpty(memberName));
                    taggedSymbol.ResolveTypedef(objectFile);
                    switch (taggedSymbol.Type)
                    {
                    case SymbolType.AutoVar:
                        _vars.Add($"{taggedSymbol.AsCode(memberName)}; // stack offset {typedValue.Value}");
                        break;

                    case SymbolType.Register:
                        _vars.Add($"{taggedSymbol.AsCode(memberName)}; // ${(Register) typedValue.Value}");
                        break;

                    case SymbolType.Static:
                        _vars.Add(
                            $"static {taggedSymbol.AsCode(memberName)}; // offset 0x{typedValue.Value:x}");
                        break;

                    case SymbolType.Typedef:
                        _typedefs.Add(memberName, taggedSymbol);
                        break;

                    case SymbolType.Label:
                        _labels.Add(new Label(typedValue, memberName));
                        break;

                    default:
                        throw new Exception($"Unexpected {nameof(TaggedSymbol)} {taggedSymbol.Type}");
                    }

                    break;
                }
                }
            }
        }
Beispiel #4
0
        public void ResolveTypedef(ObjectFile objectFile)
        {
            if (string.IsNullOrEmpty(Tag) || IsResolvedTypedef)
            {
                return;
            }

            var resolved = objectFile.ReverseTypedef(this, out var droppedDerived);

            if (resolved == null)
            {
                if (!IsFake)
                {
                    return;
                }

                var complexType = objectFile.ComplexTypes[Tag];
                if (complexType.Inlined)
                {
                    throw new Exception($"Complex type {Tag} is already inlined");
                }

                complexType.ResolveTypedefs(objectFile);

                switch (Type)
                {
                case SymbolType.EndFunction:
                case SymbolType.Null:
                case SymbolType.External:
                case SymbolType.ExternalDefinition:
                case SymbolType.Label:
                case SymbolType.UndefinedLabel:
                case SymbolType.Argument:
                case SymbolType.Struct:
                case SymbolType.Union:
                case SymbolType.Enum:
                case SymbolType.EnumMember:
                case SymbolType.RegParam:
                case SymbolType.Bitfield:
                case SymbolType.AutoArgument:
                case SymbolType.LastEntry:
                case SymbolType.MangledName:
                case SymbolType.Block:
                case SymbolType.Function:
                case SymbolType.EndOfStruct:
                case SymbolType.FileName:
                case SymbolType.Line:
                case SymbolType.Alias:
                case SymbolType.Hidden:
                    // throw new Exception($"Attempting to inline complex type into a symbol of type {Type}");
                    logger.Warn($"Attempting to inline complex type {Tag} into a symbol of type {Type}");
                    break;

                case SymbolType.AutoVar:
                case SymbolType.Static:
                case SymbolType.Register:
                case SymbolType.StructMember:
                case SymbolType.UnionMember:
                case SymbolType.Typedef:
                case SymbolType.UndefinedStatic:
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(Type));
                }

                var sb     = new StringWriter();
                var writer = new IndentedTextWriter(sb);
                complexType.Dump(writer, true);
                complexType.Inlined = true;

                InnerCode         = sb.ToString();
                IsResolvedTypedef = true;
                Tag += "/* INLINED */";
                return;
            }

            Tag = resolved;
            IsResolvedTypedef = true;

            if (IsFake)
            {
                throw new Exception("Typedef resolution led to a fake name");
            }

            if (droppedDerived == 0)
            {
                return;
            }

            var droppedArrays = DerivedTypeDef.RetainDerived(droppedDerived);

            if (droppedArrays > 0)
            {
                Extents = Extents.SkipLast(droppedArrays).ToArray();
            }
        }
Beispiel #5
0
        public Function(BinaryReader reader, uint ofs, ObjectFile objectFile)
        {
            void InitMinMax()
            {
                _minCodeAddress =
                    Math.Min(
                        _blocks.SelectMany(_ => _.AllBlocks()).Select(_ => _.StartOffset).DefaultIfEmpty(Address).Min(),
                        Address);
                _maxCodeAddress =
                    Math.Max(
                        _blocks.SelectMany(_ => _.AllBlocks()).Select(_ => _.EndOffset).DefaultIfEmpty(Address).Max(),
                        Address);
            }

            Address = ofs;

            _stackBase      = (Register)reader.ReadUInt16();
            _stackFrameSize = reader.ReadUInt32();
            _register       = (Register)reader.ReadUInt16();
            _mask           = reader.ReadUInt32();
            _maskOffs       = reader.ReadInt32();

            _line = reader.ReadUInt32();
            _file = reader.ReadPascalString();
            Name  = reader.ReadPascalString();

            if (!objectFile.FuncTypes.TryGetValue(Name, out var fnType))
            {
                _returnType = "__UNKNOWN__";
            }
            else
            {
                fnType.ResolveTypedef(objectFile);
                _returnType = fnType.AsCode("").Trim();
                if (!_returnType.EndsWith("()"))
                {
                    throw new Exception($"Expected function return type to end with '()', got {_returnType}");
                }

                _returnType = _returnType.Substring(0, _returnType.Length - 2).Trim();
            }

            while (true)
            {
                var typedValue = new TypedValue(reader);

                if (reader.SkipSld(typedValue))
                {
                    continue;
                }

                TaggedSymbol taggedSymbol;
                string       symbolName;
                switch (typedValue.Type & 0x7f)
                {
                case TypedValue.FunctionEnd:
                    _lastLine = reader.ReadUInt32();
                    InitMinMax();
                    return;

                case TypedValue.Block:
                    _blocks.Add(new Block(reader, (uint)typedValue.Value, reader.ReadUInt32(), objectFile));
                    continue;

                case TypedValue.Definition:
                    taggedSymbol = reader.ReadTaggedSymbol(false);
                    symbolName   = reader.ReadPascalString();
                    break;

                case TypedValue.ArrayDefinition:
                    taggedSymbol = reader.ReadTaggedSymbol(true);
                    symbolName   = reader.ReadPascalString();
                    break;

                default:
                    throw new Exception($"Unexpected function definition type {typedValue.Type}");
                }

                if (taggedSymbol == null || symbolName == null)
                {
                    break;
                }

                taggedSymbol.ResolveTypedef(objectFile);

                switch (taggedSymbol.Type)
                {
                case SymbolType.AutoVar:
                case SymbolType.Argument:
                    _parameters.Add($"{taggedSymbol.AsCode(symbolName)} /*stack {typedValue.Value}*/");
                    break;

                case SymbolType.RegParam:
                case SymbolType.Register:
                    _parameters.Add($"{taggedSymbol.AsCode(symbolName)} /*${(Register) typedValue.Value}*/");
                    break;

                default:
                    throw new Exception($"Unexpected parameter type {taggedSymbol.Type}");
                }
            }

            InitMinMax();
        }
Beispiel #6
0
 public void ResolveTypedefs(ObjectFile objectFile)
 {
 }
Beispiel #7
0
 public void ResolveTypedef(ObjectFile objectFile)
 {
     _taggedSymbol.ResolveTypedef(objectFile);
 }