public void ResolveTypedefs(ObjectFile objectFile) { foreach (var member in _members) { member.ResolveTypedef(objectFile); } }
public void ResolveTypedef(ObjectFile objectFile) { MemberType.ResolveTypedef(objectFile); }
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; } } } }
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(); } }
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(); }
public void ResolveTypedefs(ObjectFile objectFile) { }
public void ResolveTypedef(ObjectFile objectFile) { _taggedSymbol.ResolveTypedef(objectFile); }