コード例 #1
0
        public static void EmitObject(string objectFilePath, IEnumerable <DependencyNode> nodes, NodeFactory factory)
        {
            using (ObjectWriter objectWriter = new ObjectWriter(objectFilePath, factory))
            {
                // TODO: Exception handling on Unix
                if (factory.Target.IsWindows)
                {
                    objectWriter.CreateCustomSection(MethodCodeNode.ContentSection);

                    // Emit sentinels for managed code section.
                    ObjectNodeSection codeStartSection = factory.CompilationModuleGroup.IsSingleFileCompilation ? MethodCodeNode.StartSection : MethodCodeNode.StartSection.GetSharedSection("__managedcode_a");
                    objectWriter.SetSection(codeStartSection);
                    objectWriter.EmitSymbolDef("__managedcode_a");
                    objectWriter.EmitIntValue(0, 1);
                    ObjectNodeSection codeEndSection = factory.CompilationModuleGroup.IsSingleFileCompilation ? MethodCodeNode.EndSection : MethodCodeNode.EndSection.GetSharedSection("__managedcode_z");
                    objectWriter.SetSection(codeEndSection);
                    objectWriter.EmitSymbolDef("__managedcode_z");
                    objectWriter.EmitIntValue(0, 1);
                }

                // Build file info map.
                objectWriter.BuildFileInfoMap(nodes);

                foreach (DependencyNode depNode in nodes)
                {
                    ObjectNode node = depNode as ObjectNode;
                    if (node == null)
                    {
                        continue;
                    }

                    if (node.ShouldSkipEmittingObjectNode(factory))
                    {
                        continue;
                    }

#if DEBUG
                    Debug.Assert(_previouslyWrittenNodeNames.Add(node.GetName()), "Duplicate node name emitted to file", "Node {0} has already been written to the output object file {1}", node.GetName(), objectFilePath);
#endif
                    ObjectNode.ObjectData nodeContents = node.GetData(factory);

                    ObjectNodeSection section = node.Section;
                    if (node.ShouldShareNodeAcrossModules(factory) && factory.Target.OperatingSystem == TargetOS.Windows)
                    {
                        Debug.Assert(node is ISymbolNode);
                        section = section.GetSharedSection(((ISymbolNode)node).MangledName);
                    }

                    // Ensure section and alignment for the node.
                    objectWriter.SetSection(section);
                    objectWriter.EmitAlignment(nodeContents.Alignment);

                    // Build symbol definition map.
                    objectWriter.BuildSymbolDefinitionMap(node, nodeContents.DefinedSymbols);

                    // Build CFI map (Unix) or publish unwind blob (Windows).
                    objectWriter.BuildCFIMap(factory, node);

                    // Build debug location map
                    objectWriter.BuildDebugLocInfoMap(node);

                    Relocation[] relocs          = nodeContents.Relocs;
                    int          nextRelocOffset = -1;
                    int          nextRelocIndex  = -1;
                    if (relocs.Length > 0)
                    {
                        nextRelocOffset = relocs[0].Offset;
                        nextRelocIndex  = 0;
                    }

                    int i = 0;
                    while (i < nodeContents.Data.Length)
                    {
                        // Emit symbol definitions if necessary
                        objectWriter.EmitSymbolDefinition(i);

                        // Emit CFI codes for the given offset.
                        objectWriter.EmitCFICodes(i);

                        // Emit debug loc info if needed.
                        objectWriter.EmitDebugLocInfo(i);

                        if (i == nextRelocOffset)
                        {
                            Relocation reloc = relocs[nextRelocIndex];

                            int size = objectWriter.EmitSymbolReference(reloc.Target, reloc.Delta, reloc.RelocType);

                            // Update nextRelocIndex/Offset
                            if (++nextRelocIndex < relocs.Length)
                            {
                                nextRelocOffset = relocs[nextRelocIndex].Offset;
                            }
                            i += size;
                        }
                        else
                        {
                            objectWriter.EmitIntValue(nodeContents.Data[i], 1);
                            i++;
                        }
                    }

                    // It is possible to have a symbol just after all of the data.
                    objectWriter.EmitSymbolDefinition(nodeContents.Data.Length);

                    // Emit the last CFI to close the frame.
                    objectWriter.EmitCFICodes(nodeContents.Data.Length);

                    if (objectWriter.HasFunctionDebugInfo())
                    {
                        // Build debug local var info
                        objectWriter.EmitDebugVarInfo(node);

                        objectWriter.EmitDebugFunctionInfo(nodeContents.Data.Length);
                    }
                }

                objectWriter.EmitDebugModuleInfo();
            }
        }
コード例 #2
0
ファイル: ObjectWriter.cs プロジェクト: modulexcite/corert
        public static void EmitObject(string objectFilePath, IEnumerable <DependencyNode> nodes, NodeFactory factory)
        {
            using (ObjectWriter objectWriter = new ObjectWriter(objectFilePath, factory))
            {
                string currentSection = "";

                // Build file info map.
                string[] debugFileInfos = objectWriter.BuildFileInfoMap(nodes);
                if (debugFileInfos != null)
                {
                    objectWriter.EmitDebugFileInfo(debugFileInfos.Length, debugFileInfos);
                }

                foreach (DependencyNode depNode in nodes)
                {
                    ObjectNode node = depNode as ObjectNode;
                    if (node == null)
                    {
                        continue;
                    }

                    if (node.ShouldSkipEmittingObjectNode(factory))
                    {
                        continue;
                    }

#if DEBUG
                    Debug.Assert(_previouslyWrittenNodeNames.Add(node.GetName()), "Duplicate node name emitted to file", "Node {0} has already been written to the output object file {1}", node.GetName(), objectFilePath);
#endif
                    ObjectNode.ObjectData nodeContents = node.GetData(factory);

                    if (currentSection != node.Section)
                    {
                        currentSection = node.Section;
                        objectWriter.SwitchSection(currentSection);
                    }

                    objectWriter.EmitAlignment(nodeContents.Alignment);

                    Relocation[] relocs          = nodeContents.Relocs;
                    int          nextRelocOffset = -1;
                    int          nextRelocIndex  = -1;
                    if (relocs != null && relocs.Length > 0)
                    {
                        nextRelocOffset = relocs[0].Offset;
                        nextRelocIndex  = 0;
                    }

                    // Build symbol definition map.
                    objectWriter.BuildSymbolDefinitionMap(nodeContents.DefinedSymbols);

                    // Build debug location map
                    objectWriter.BuildDebugLocInfoMap(node);

                    for (int i = 0; i < nodeContents.Data.Length; i++)
                    {
                        // Emit symbol definitions if necessary
                        objectWriter.EmitSymbolDefinition(i);

                        // Emit debug loc info if needed.
                        objectWriter.EmitDebugLocInfo(i);

                        if (i == nextRelocOffset)
                        {
                            Relocation reloc = relocs[nextRelocIndex];

                            ISymbolNode target       = reloc.Target;
                            string      targetName   = objectWriter.GetSymbolToEmitForTargetPlatform(target.MangledName);
                            int         size         = 0;
                            bool        isPCRelative = false;
                            switch (reloc.RelocType)
                            {
                            case RelocType.IMAGE_REL_BASED_DIR64:
                                size = 8;
                                break;

                            case RelocType.IMAGE_REL_BASED_REL32:
                                size         = 4;
                                isPCRelative = true;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                            // Emit symbol reference
                            objectWriter.EmitSymbolRef(targetName, size, isPCRelative, reloc.Delta);

                            // Update nextRelocIndex/Offset
                            if (++nextRelocIndex < relocs.Length)
                            {
                                nextRelocOffset = relocs[nextRelocIndex].Offset;
                            }
                            i += size - 1;
                            continue;
                        }

                        objectWriter.EmitIntValue(nodeContents.Data[i], 1);
                    }

                    // It is possible to have a symbol just after all of the data.
                    objectWriter.EmitSymbolDefinition(nodeContents.Data.Length);

                    // The first definition is the main node name
                    string nodeName = objectWriter._offsetToDefSymbol[0][0].MangledName;
                    // Emit frame info for object code.
                    if (node is INodeWithFrameInfo)
                    {
                        FrameInfo[] frameInfos = ((INodeWithFrameInfo)node).FrameInfos;
                        if (frameInfos != null)
                        {
                            foreach (var frameInfo in frameInfos)
                            {
                                objectWriter.EmitFrameInfo(nodeName,
                                                           frameInfo.StartOffset,
                                                           frameInfo.EndOffset,
                                                           frameInfo.BlobData.Length,
                                                           frameInfo.BlobData);
                            }
                        }
                    }

                    objectWriter.FlushDebugLocs(nodeName, nodeContents.Data.Length);
                    objectWriter.SwitchSection(currentSection);
                }
            }
        }
コード例 #3
0
ファイル: ObjectWriter.cs プロジェクト: MyOwnClone/corert
        public static void EmitObject(string objectFilePath, IEnumerable <DependencyNode> nodes, NodeFactory factory)
        {
            using (ObjectWriter objectWriter = new ObjectWriter(objectFilePath, factory))
            {
                // Build file info map.
                objectWriter.BuildFileInfoMap(nodes);

                foreach (DependencyNode depNode in nodes)
                {
                    ObjectNode node = depNode as ObjectNode;
                    if (node == null)
                    {
                        continue;
                    }

                    if (node.ShouldSkipEmittingObjectNode(factory))
                    {
                        continue;
                    }

#if DEBUG
                    Debug.Assert(_previouslyWrittenNodeNames.Add(node.GetName()), "Duplicate node name emitted to file", "Node {0} has already been written to the output object file {1}", node.GetName(), objectFilePath);
#endif
                    ObjectNode.ObjectData nodeContents = node.GetData(factory);
                    // Ensure section and alignment for the node.
                    objectWriter.SetSection(node.Section);
                    objectWriter.EmitAlignment(nodeContents.Alignment);

                    Relocation[] relocs          = nodeContents.Relocs;
                    int          nextRelocOffset = -1;
                    int          nextRelocIndex  = -1;
                    if (relocs != null && relocs.Length > 0)
                    {
                        nextRelocOffset = relocs[0].Offset;
                        nextRelocIndex  = 0;
                    }

                    // Build symbol definition map.
                    objectWriter.BuildSymbolDefinitionMap(nodeContents.DefinedSymbols);

                    // Build CFI map (Unix) or publish unwind blob (Windows).
                    objectWriter.BuildCFIMap(node);

                    // Build debug location map
                    objectWriter.BuildDebugLocInfoMap(node);

                    for (int i = 0; i < nodeContents.Data.Length; i++)
                    {
                        // Emit symbol definitions if necessary
                        objectWriter.EmitSymbolDefinition(i);

                        // Emit CFI codes for the given offset.
                        objectWriter.EmitCFICodes(i);

                        // Emit debug loc info if needed.
                        objectWriter.EmitDebugLocInfo(i);

                        if (i == nextRelocOffset)
                        {
                            Relocation reloc = relocs[nextRelocIndex];

                            ISymbolNode target       = reloc.Target;
                            string      targetName   = objectWriter.GetSymbolToEmitForTargetPlatform(target.MangledName);
                            int         size         = 0;
                            bool        isPCRelative = false;
                            switch (reloc.RelocType)
                            {
                            case RelocType.IMAGE_REL_BASED_DIR64:
                                size = 8;
                                break;

                            case RelocType.IMAGE_REL_BASED_REL32:
                                size         = 4;
                                isPCRelative = true;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                            // Emit symbol reference
                            objectWriter.EmitSymbolRef(targetName, size, isPCRelative, reloc.Delta);

                            // Update nextRelocIndex/Offset
                            if (++nextRelocIndex < relocs.Length)
                            {
                                nextRelocOffset = relocs[nextRelocIndex].Offset;
                            }
                            i += size - 1;
                            continue;
                        }

                        objectWriter.EmitIntValue(nodeContents.Data[i], 1);
                    }

                    // It is possible to have a symbol just after all of the data.
                    objectWriter.EmitSymbolDefinition(nodeContents.Data.Length);

                    // Emit the last CFI to close the frame.
                    objectWriter.EmitCFICodes(nodeContents.Data.Length);

                    if (objectWriter.HasFunctionDebugInfo())
                    {
                        // Build debug local var info
                        objectWriter.EmitDebugVarInfo(node);

                        objectWriter.EmitDebugFunctionInfo(nodeContents.Data.Length);
                    }
                }

                objectWriter.EmitDebugModuleInfo();
            }
        }