X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Ftools%2Fmono-symbolicate%2FLocationProvider.cs;h=f03adfdee58e7b86d9292f53eb28e1bcfdf4ee6f;hb=379436fcf5258ac83c27c0dc469eb6cfc80e0b7b;hp=c3a97993c6a75da170fc7363ef3d888cdbd834f2;hpb=53c4a18a9f2de8865864052321a469e2ae89e806;p=mono.git diff --git a/mcs/tools/mono-symbolicate/LocationProvider.cs b/mcs/tools/mono-symbolicate/LocationProvider.cs index c3a97993c6a..f03adfdee58 100644 --- a/mcs/tools/mono-symbolicate/LocationProvider.cs +++ b/mcs/tools/mono-symbolicate/LocationProvider.cs @@ -32,7 +32,12 @@ namespace Mono return false; TypeDefinition type = null; - var nested = sfData.TypeFullName.Split ('+'); + string[] nested; + if (sfData.TypeFullName.IndexOf ('/') >= 0) + nested = sfData.TypeFullName.Split ('/'); + else + nested = sfData.TypeFullName.Split ('+'); + var types = assembly.MainModule.Types; foreach (var ntype in nested) { if (type == null) { @@ -53,11 +58,16 @@ namespace Mono var parensStart = sfData.MethodSignature.IndexOf ('('); var methodName = sfData.MethodSignature.Substring (0, parensStart).TrimEnd (); var methodParameters = sfData.MethodSignature.Substring (parensStart); - var method = type.Methods.FirstOrDefault (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters)); - if (method == null) { + var methods = type.Methods.Where (m => CompareName (m, methodName) && CompareParameters (m.Parameters, methodParameters)).ToArray (); + if (methods.Length == 0) { logger.LogWarning ("Could not find method: {0}", methodName); return false; } + if (methods.Length > 1) { + logger.LogWarning ("Ambiguous match for method: {0}", sfData.MethodSignature); + return false; + } + var method = methods [0]; int ilOffset; if (sfData.IsILOffset) { @@ -72,15 +82,22 @@ namespace Mono if (ilOffset < 0) return false; - SequencePoint sp = null; - foreach (var instr in method.Body.Instructions) { - if (instr.SequencePoint != null) - sp = instr.SequencePoint; - - if (instr.Offset >= ilOffset) { + if (!method.DebugInformation.HasSequencePoints) + return false; + + SequencePoint prev = null; + foreach (var sp in method.DebugInformation.SequencePoints.OrderBy (l => l.Offset)) { + if (sp.Offset >= ilOffset) { sfData.SetLocation (sp.Document.Url, sp.StartLine); return true; } + + prev = sp; + } + + if (prev != null) { + sfData.SetLocation (prev.Document.Url, prev.StartLine); + return true; } return false; @@ -93,8 +110,11 @@ namespace Mono if (!candidate.HasGenericParameters) return false; - + var genStart = expected.IndexOf ('['); + if (genStart < 0) + genStart = expected.IndexOf ('<'); + if (genStart < 0) return false; @@ -110,6 +130,36 @@ namespace Mono return candidate.GenericParameters.Count == arity; } + static string RemoveGenerics (string expected, char open, char close) + { + if (expected.IndexOf (open) < 0) + return expected; + + var sb = new StringBuilder (); + for (int i = 0; i < expected.Length;) { + int start = expected.IndexOf (open, i); + int end = expected.IndexOf (close, i); + if (start < 0 || end < 0) { + sb.Append (expected, i, expected.Length - i); + break; + } + + bool is_ginst = false; + for (int j = start + 1; j < end; ++j) { + if (expected [j] != ',') + is_ginst = true; + } + + if (is_ginst) //discard the the generic args + sb.Append (expected, i, start - i); + else //include array arity + sb.Append (expected, i, end + 1 - i); + i = end + 1; + + } + return sb.ToString (); + } + static bool CompareParameters (Collection candidate, string expected) { var builder = new StringBuilder (); @@ -124,11 +174,6 @@ namespace Mono builder.Append ("...,"); var pt = parameter.ParameterType; - if (!string.IsNullOrEmpty (pt.Namespace)) { - builder.Append (pt.Namespace); - builder.Append ("."); - } - FormatElementType (pt, builder); builder.Append (" "); @@ -137,7 +182,150 @@ namespace Mono builder.Append (")"); - return builder.ToString () == expected; + if (builder.ToString () == RemoveGenerics (expected, '[', ']')) + return true; + + //now try the compact runtime format. + + builder.Clear (); + + builder.Append ("("); + + for (int i = 0; i < candidate.Count; i++) { + var parameter = candidate [i]; + if (i > 0) + builder.Append (","); + + if (parameter.ParameterType.IsSentinel) + builder.Append ("...,"); + + var pt = parameter.ParameterType; + + RuntimeFormatElementType (pt, builder); + } + + builder.Append (")"); + + if (builder.ToString () == RemoveGenerics (expected, '<', '>')) + return true; + return false; + + } + + static void RuntimeFormatElementType (TypeReference tr, StringBuilder builder) + { + var ts = tr as TypeSpecification; + if (ts != null) { + if (ts.IsByReference) { + RuntimeFormatElementType (ts.ElementType, builder); + builder.Append ("&"); + return; + } + } + + switch (tr.MetadataType) { + case MetadataType.Void: + builder.Append ("void"); + break; + case MetadataType.Boolean: + builder.Append ("bool"); + break; + case MetadataType.Char: + builder.Append ("char"); + break; + case MetadataType.SByte: + builder.Append ("sbyte"); + break; + case MetadataType.Byte: + builder.Append ("byte"); + break; + case MetadataType.Int16: + builder.Append ("int16"); + break; + case MetadataType.UInt16: + builder.Append ("uint16"); + break; + case MetadataType.Int32: + builder.Append ("int"); + break; + case MetadataType.UInt32: + builder.Append ("uint"); + break; + case MetadataType.Int64: + builder.Append ("long"); + break; + case MetadataType.UInt64: + builder.Append ("ulong"); + break; + case MetadataType.Single: + builder.Append ("single"); + break; + case MetadataType.Double: + builder.Append ("double"); + break; + case MetadataType.String: + builder.Append ("string"); + break; + case MetadataType.Pointer: + builder.Append (((TypeSpecification)tr).ElementType); + builder.Append ("*"); + break; + case MetadataType.ValueType: + case MetadataType.Class: + case MetadataType.GenericInstance: { + FormatName (tr, builder, '/'); + break; + } + case MetadataType.Var: + case MetadataType.MVar: + builder.Append (tr.Name); + builder.Append ("_REF"); + break; + case MetadataType.Array: { + var array = (ArrayType)tr; + RuntimeFormatElementType (array.ElementType, builder); + builder.Append ("["); + + for (int i = 0; i < array.Rank - 1; ++i) + builder.Append (","); + + builder.Append ("]"); + break; + } + + case MetadataType.TypedByReference: + builder.Append ("typedbyref"); + break; + case MetadataType.IntPtr: + builder.Append ("intptr"); + break; + case MetadataType.UIntPtr: + builder.Append ("uintptr"); + break; + case MetadataType.FunctionPointer: + builder.Append ("*()"); + break; + case MetadataType.Object: + builder.Append ("object"); + break; + default: + builder.Append ("-unknown-"); + break; + } + } + + static void FormatName (TypeReference tr, StringBuilder builder, char sep) + { + if (tr.IsNested && !(tr.MetadataType == MetadataType.Var || tr.MetadataType == MetadataType.MVar)) { + FormatName (tr.DeclaringType, builder, sep); + builder.Append (sep); + } + if (!string.IsNullOrEmpty (tr.Namespace)) { + builder.Append (tr.Namespace); + builder.Append ("."); + } + + builder.Append (tr.Name); } static void FormatElementType (TypeReference tr, StringBuilder builder) @@ -163,8 +351,7 @@ namespace Mono return; } } - - builder.Append (tr.Name); + FormatName (tr, builder, '+'); } } }