Exemple #1
0
        public void EmitPortableExecutable()
        {
            bool succeeded = false;

            FileStream mapFileStream = null;
            TextWriter mapFile       = null;

            try
            {
                string mapFileName = Path.ChangeExtension(_objectFilePath, ".map");
                mapFileStream = new FileStream(mapFileName, FileMode.Create, FileAccess.Write);
                mapFile       = new StreamWriter(mapFileStream);

                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                mapFile.WriteLine($@"R2R object emission started: {DateTime.Now}");

                _sectionBuilder = new SectionBuilder();

                _textSectionIndex  = _sectionBuilder.AddSection(R2RPEBuilder.TextSectionName, SectionCharacteristics.ContainsCode | SectionCharacteristics.MemExecute | SectionCharacteristics.MemRead, 512);
                _rdataSectionIndex = _sectionBuilder.AddSection(".rdata", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemRead, 512);
                _dataSectionIndex  = _sectionBuilder.AddSection(".data", SectionCharacteristics.ContainsInitializedData | SectionCharacteristics.MemWrite | SectionCharacteristics.MemRead, 512);

                int nodeIndex = -1;
                foreach (var depNode in _nodes)
                {
                    ++nodeIndex;
                    ObjectNode node = depNode as ObjectNode;

                    if (node == null)
                    {
                        continue;
                    }

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

                    ObjectData nodeContents = node.GetData(_nodeFactory);

                    string name = null;

                    if (mapFile != null)
                    {
                        name = depNode.GetType().ToString();
                        int firstGeneric = name.IndexOf('[');
                        if (firstGeneric < 0)
                        {
                            firstGeneric = name.Length;
                        }
                        int lastDot = name.LastIndexOf('.', firstGeneric - 1, firstGeneric);
                        if (lastDot > 0)
                        {
                            name = name.Substring(lastDot + 1);
                        }
                    }

                    EmitObjectData(nodeContents, nodeIndex, name, node.Section, mapFile);
                }

                _sectionBuilder.SetReadyToRunHeaderTable(_nodeFactory.Header, _nodeFactory.Header.GetData(_nodeFactory).Data.Length);

                Machine targetMachine;
                switch (_nodeFactory.Target.Architecture)
                {
                case Internal.TypeSystem.TargetArchitecture.X64:
                    targetMachine = Machine.Amd64;
                    break;

                case Internal.TypeSystem.TargetArchitecture.X86:
                    targetMachine = Machine.I386;
                    break;

                default:
                    throw new NotImplementedException(_nodeFactory.Target.Architecture.ToString());
                }

                using (var peStream = File.Create(_objectFilePath))
                {
                    _sectionBuilder.EmitR2R(targetMachine, _inputPeReader, UpdateDirectories, peStream);
                }

                mapFile.WriteLine($@"R2R object emission finished: {DateTime.Now}, {stopwatch.ElapsedMilliseconds} msecs");
                mapFile.Flush();
                mapFileStream.Flush();

                succeeded = true;
            }
            finally
            {
                if (mapFile != null)
                {
                    mapFile.Dispose();
                }
                if (mapFileStream != null)
                {
                    mapFileStream.Dispose();
                }
                if (!succeeded)
                {
                    // If there was an exception while generating the OBJ file, make sure we don't leave the unfinished
                    // object file around.
                    try
                    {
                        File.Delete(_objectFilePath);
                    }
                    catch
                    {
                    }
                }
            }
        }