Пример #1
0
        private Utf8String GetPrefixMangledSignatureName(IPrefixMangledSignature prefixMangledSignature)
        {
            Utf8StringBuilder sb = new Utf8StringBuilder();

            sb.Append(EnterNameScopeSequence).Append(prefixMangledSignature.Prefix).Append(ExitNameScopeSequence);

            var signature = prefixMangledSignature.BaseSignature;

            sb.Append(signature.Flags.ToStringInvariant());

            sb.Append(EnterNameScopeSequence);

            string sigRetTypeName = GetMangledTypeName(signature.ReturnType);

            if (_mangleForCplusPlus)
            {
                sigRetTypeName = sigRetTypeName.Replace("::", "_");
            }
            sb.Append(sigRetTypeName);

            for (int i = 0; i < signature.Length; i++)
            {
                sb.Append("__");
                string sigArgName = GetMangledTypeName(signature[i]);
                if (_mangleForCplusPlus)
                {
                    sigArgName = sigArgName.Replace("::", "_");
                }
                sb.Append(sigArgName);
            }

            sb.Append(ExitNameScopeSequence);

            return(sb.ToUtf8String());
        }
Пример #2
0
        public override Utf8String GetMangledMethodName(MethodDesc method)
        {
            if (_mangleForCplusPlus)
            {
                return(GetUnqualifiedMangledMethodName(method));
            }
            else
            {
                Utf8String utf8MangledName;
                lock (this)
                {
                    if (_mangledMethodNames.TryGetValue(method, out utf8MangledName))
                    {
                        return(utf8MangledName);
                    }
                }

                Utf8StringBuilder sb = new Utf8StringBuilder();
                sb.Append(GetMangledTypeName(method.OwningType));
                sb.Append("__");
                sb.Append(GetUnqualifiedMangledMethodName(method));
                utf8MangledName = sb.ToUtf8String();

                lock (this)
                {
                    if (!_mangledMethodNames.ContainsKey(method))
                    {
                        _mangledMethodNames.Add(method, utf8MangledName);
                    }
                }

                return(utf8MangledName);
            }
        }
Пример #3
0
        private Utf8String GetPrefixMangledMethodName(IPrefixMangledMethod prefixMangledMethod)
        {
            Utf8StringBuilder sb = new Utf8StringBuilder();

            sb.Append(EnterNameScopeSequence).Append(prefixMangledMethod.Prefix).Append(ExitNameScopeSequence);

            if (_mangleForCplusPlus)
            {
                string name = GetMangledMethodName(prefixMangledMethod.BaseMethod).ToString().Replace("::", "_");
                sb.Append(name);
            }
            else
            {
                sb.Append(GetMangledMethodName(prefixMangledMethod.BaseMethod));
            }

            return(sb.ToUtf8String());
        }
Пример #4
0
        public void BuildCFIMap(NodeFactory factory, ObjectNode node)
        {
            _offsetToCfis.Clear();
            _offsetToCfiStart.Clear();
            _offsetToCfiEnd.Clear();
            _offsetToCfiLsdaBlobName.Clear();
            _frameOpened = false;

            INodeWithCodeInfo nodeWithCodeInfo = node as INodeWithCodeInfo;

            if (nodeWithCodeInfo == null)
            {
                return;
            }

            FrameInfo[] frameInfos = nodeWithCodeInfo.FrameInfos;
            if (frameInfos == null)
            {
                return;
            }

            byte[]     gcInfo = nodeWithCodeInfo.GCInfo;
            ObjectData ehInfo = nodeWithCodeInfo.EHInfo;

            for (int i = 0; i < frameInfos.Length; i++)
            {
                FrameInfo frameInfo = frameInfos[i];

                int    start = frameInfo.StartOffset;
                int    end   = frameInfo.EndOffset;
                int    len   = frameInfo.BlobData.Length;
                byte[] blob  = frameInfo.BlobData;

                ObjectNodeSection lsdaSection = LsdaSection;
                if (ShouldShareSymbol(node))
                {
                    lsdaSection = lsdaSection.GetSharedSection(((ISymbolNode)node).GetMangledName(_nodeFactory.NameMangler));
                }
                SwitchSection(_nativeObjectWriter, lsdaSection.Name, GetCustomSectionAttributes(lsdaSection), lsdaSection.ComdatName);

                _sb.Clear().Append("_lsda").Append(i.ToStringInvariant()).Append(_currentNodeZeroTerminatedName);
                byte[] blobSymbolName = _sb.ToUtf8String().UnderlyingArray;
                EmitSymbolDef(blobSymbolName);

                FrameInfoFlags flags = frameInfo.Flags;
                if (ehInfo != null)
                {
                    flags |= FrameInfoFlags.HasEHInfo;
                }
                EmitIntValue((byte)flags, 1);

                if (i != 0)
                {
                    EmitSymbolRef(_sb.Clear().Append("_lsda0").Append(_currentNodeZeroTerminatedName), RelocType.IMAGE_REL_BASED_REL32, 4);

                    // emit relative offset from the main function
                    EmitIntValue((ulong)(start - frameInfos[0].StartOffset), 4);
                }

                if (ehInfo != null)
                {
                    EmitSymbolRef(_sb.Clear().Append("_ehInfo").Append(_currentNodeZeroTerminatedName), RelocType.IMAGE_REL_BASED_REL32, 4);
                }

                if (gcInfo != null)
                {
                    EmitBlob(gcInfo);
                    gcInfo = null;
                }

                if (ehInfo != null)
                {
                    // TODO: Place EHInfo into different section for better locality
                    Debug.Assert(ehInfo.Alignment == 1);
                    Debug.Assert(ehInfo.DefinedSymbols.Length == 0);
                    EmitSymbolDef(_sb /* ehInfo */);
                    EmitBlobWithRelocs(ehInfo.Data, ehInfo.Relocs);
                    ehInfo = null;
                }

                // For Unix, we build CFI blob map for each offset.
                Debug.Assert(len % CfiCodeSize == 0);

                // Record start/end of frames which shouldn't be overlapped.
                _offsetToCfiStart.Add(start);
                _offsetToCfiEnd.Add(end);
                _offsetToCfiLsdaBlobName.Add(start, blobSymbolName);
                for (int j = 0; j < len; j += CfiCodeSize)
                {
                    // The first byte of CFI_CODE is offset from the range the frame covers.
                    // Compute code offset from the root method.
                    int           codeOffset = blob[j] + start;
                    List <byte[]> cfis;
                    if (!_offsetToCfis.TryGetValue(codeOffset, out cfis))
                    {
                        cfis = new List <byte[]>();
                        _offsetToCfis.Add(codeOffset, cfis);
                    }
                    byte[] cfi = new byte[CfiCodeSize];
                    Array.Copy(blob, j, cfi, 0, CfiCodeSize);
                    cfis.Add(cfi);
                }
            }

            EnsureCurrentSection();
        }
Пример #5
0
        private Utf8String ComputeUnqualifiedMangledMethodName(MethodDesc method)
        {
            if (method is EcmaMethod)
            {
                var deduplicator = new HashSet <string>();

                // Add consistent names for all methods of the type, independent on the order in which
                // they are compiled
                lock (this)
                {
                    if (!_unqualifiedMangledMethodNames.ContainsKey(method))
                    {
                        foreach (var m in method.OwningType.GetMethods())
                        {
                            string name = SanitizeName(m.Name);

                            name = DisambiguateName(name, deduplicator);
                            deduplicator.Add(name);

                            _unqualifiedMangledMethodNames.Add(m, name);
                        }
                    }
                    return(_unqualifiedMangledMethodNames[method]);
                }
            }

            Utf8String utf8MangledName;

            var methodDefinition = method.GetMethodDefinition();

            if (methodDefinition != method)
            {
                // Instantiated generic method
                Utf8StringBuilder sb = new Utf8StringBuilder();
                sb.Append(GetUnqualifiedMangledMethodName(methodDefinition.GetTypicalMethodDefinition()));

                sb.Append(EnterNameScopeSequence);

                var inst = method.Instantiation;
                for (int i = 0; i < inst.Length; i++)
                {
                    string instArgName = GetMangledTypeName(inst[i]);
                    if (_mangleForCplusPlus)
                    {
                        instArgName = instArgName.Replace("::", "_");
                    }
                    if (i > 0)
                    {
                        sb.Append("__");
                    }
                    sb.Append(instArgName);
                }

                sb.Append(ExitNameScopeSequence);

                utf8MangledName = sb.ToUtf8String();
            }
            else
            {
                var typicalMethodDefinition = method.GetTypicalMethodDefinition();
                if (typicalMethodDefinition != method)
                {
                    // Method on an instantiated type
                    utf8MangledName = GetUnqualifiedMangledMethodName(typicalMethodDefinition);
                }
                else if (method is IPrefixMangledMethod)
                {
                    utf8MangledName = GetPrefixMangledMethodName((IPrefixMangledMethod)method);
                }
                else if (method is IPrefixMangledType)
                {
                    utf8MangledName = GetPrefixMangledTypeName((IPrefixMangledType)method);
                }
                else if (method is IPrefixMangledSignature)
                {
                    utf8MangledName = GetPrefixMangledSignatureName((IPrefixMangledSignature)method);
                }
                else
                {
                    // Assume that Name is unique for all other methods
                    utf8MangledName = new Utf8String(SanitizeName(method.Name));
                }
            }

            // Unless we're doing CPP mangling, there's no point in caching the unqualified
            // method name. We only needed it to construct the fully qualified name. Nobody
            // is going to ask for the unqualified name again.
            if (_mangleForCplusPlus)
            {
                lock (this)
                {
                    if (!_unqualifiedMangledMethodNames.ContainsKey(method))
                    {
                        _unqualifiedMangledMethodNames.Add(method, utf8MangledName);
                    }
                }
            }

            return(utf8MangledName);
        }
Пример #6
0
        public void BuildCFIMap(NodeFactory factory, ObjectNode node)
        {
            _offsetToCfis.Clear();
            _offsetToCfiStart.Clear();
            _offsetToCfiEnd.Clear();
            _offsetToCfiLsdaBlobName.Clear();
            _frameOpened = false;

            INodeWithCodeInfo nodeWithCodeInfo = node as INodeWithCodeInfo;

            if (nodeWithCodeInfo == null)
            {
                return;
            }

            FrameInfo[] frameInfos = nodeWithCodeInfo.FrameInfos;
            if (frameInfos == null)
            {
                return;
            }

            byte[] gcInfo = nodeWithCodeInfo.GCInfo;
            ObjectNode.ObjectData ehInfo = nodeWithCodeInfo.EHInfo;

            for (int i = 0; i < frameInfos.Length; i++)
            {
                FrameInfo frameInfo = frameInfos[i];

                int    start = frameInfo.StartOffset;
                int    end   = frameInfo.EndOffset;
                int    len   = frameInfo.BlobData.Length;
                byte[] blob  = frameInfo.BlobData;

                if (_targetPlatform.OperatingSystem == TargetOS.Windows)
                {
                    _sb.Clear().Append("_unwind").Append(i.ToStringInvariant());

                    ObjectNodeSection section = ObjectNodeSection.XDataSection;
                    if (node.ShouldShareNodeAcrossModules(factory) && factory.Target.OperatingSystem == TargetOS.Windows)
                    {
                        section = section.GetSharedSection(_sb.ToString());
                        CreateCustomSection(section);
                    }
                    SwitchSection(_nativeObjectWriter, section.Name);

                    byte[] blobSymbolName = _sb.Append(_currentNodeZeroTerminatedName).ToUtf8String().UnderlyingArray;

                    EmitAlignment(4);
                    EmitSymbolDef(blobSymbolName);

                    FrameInfoFlags flags = frameInfo.Flags;
                    if (ehInfo != null)
                    {
                        flags |= FrameInfoFlags.HasEHInfo;
                    }

                    EmitBlob(blob);

                    EmitIntValue((byte)flags, 1);

                    if (ehInfo != null)
                    {
                        EmitSymbolRef(_sb.Clear().Append("_ehInfo").Append(_currentNodeZeroTerminatedName), RelocType.IMAGE_REL_BASED_ABSOLUTE);
                    }

                    if (gcInfo != null)
                    {
                        EmitBlob(gcInfo);
                        gcInfo = null;
                    }

                    if (ehInfo != null)
                    {
                        // TODO: Place EHInfo into different section for better locality
                        Debug.Assert(ehInfo.Alignment == 1);
                        Debug.Assert(ehInfo.DefinedSymbols.Length == 0);
                        EmitSymbolDef(_sb /* ehInfo */);
                        EmitBlobWithRelocs(ehInfo.Data, ehInfo.Relocs);
                        ehInfo = null;
                    }

                    // TODO: Currently we get linker errors if we emit frame info for shared types.
                    //       This needs follow-up investigation.
                    if (!node.ShouldShareNodeAcrossModules(factory))
                    {
                        // For window, just emit the frame blob (UNWIND_INFO) as a whole.
                        EmitWinFrameInfo(start, end, len, blobSymbolName);
                    }
                }
                else
                {
                    SwitchSection(_nativeObjectWriter, LsdaSection.Name);

                    _sb.Clear().Append("_lsda").Append(i.ToStringInvariant()).Append(_currentNodeZeroTerminatedName);
                    byte[] blobSymbolName = _sb.ToUtf8String().UnderlyingArray;
                    EmitSymbolDef(blobSymbolName);

                    FrameInfoFlags flags = frameInfo.Flags;
                    if (ehInfo != null)
                    {
                        flags |= FrameInfoFlags.HasEHInfo;
                    }
                    EmitIntValue((byte)flags, 1);

                    if (i != 0)
                    {
                        EmitSymbolRef(_sb.Clear().Append("_lsda0").Append(_currentNodeZeroTerminatedName), RelocType.IMAGE_REL_BASED_REL32, 4);

                        // emit relative offset from the main function
                        EmitIntValue((ulong)(start - frameInfos[0].StartOffset), 4);
                    }

                    if (ehInfo != null)
                    {
                        EmitSymbolRef(_sb.Clear().Append("_ehInfo").Append(_currentNodeZeroTerminatedName), RelocType.IMAGE_REL_BASED_REL32, 4);
                    }

                    if (gcInfo != null)
                    {
                        EmitBlob(gcInfo);
                        gcInfo = null;
                    }

                    if (ehInfo != null)
                    {
                        // TODO: Place EHInfo into different section for better locality
                        Debug.Assert(ehInfo.Alignment == 1);
                        Debug.Assert(ehInfo.DefinedSymbols.Length == 0);
                        EmitSymbolDef(_sb /* ehInfo */);
                        EmitBlobWithRelocs(ehInfo.Data, ehInfo.Relocs);
                        ehInfo = null;
                    }

                    // For Unix, we build CFI blob map for each offset.
                    Debug.Assert(len % CfiCodeSize == 0);

                    // Record start/end of frames which shouldn't be overlapped.
                    _offsetToCfiStart.Add(start);
                    _offsetToCfiEnd.Add(end);
                    _offsetToCfiLsdaBlobName.Add(start, blobSymbolName);
                    for (int j = 0; j < len; j += CfiCodeSize)
                    {
                        // The first byte of CFI_CODE is offset from the range the frame covers.
                        // Compute code offset from the root method.
                        int           codeOffset = blob[j] + start;
                        List <byte[]> cfis;
                        if (!_offsetToCfis.TryGetValue(codeOffset, out cfis))
                        {
                            cfis = new List <byte[]>();
                            _offsetToCfis.Add(codeOffset, cfis);
                        }
                        byte[] cfi = new byte[CfiCodeSize];
                        Array.Copy(blob, j, cfi, 0, CfiCodeSize);
                        cfis.Add(cfi);
                    }
                }

                EnsureCurrentSection();
            }
        }