summaryrefslogtreecommitdiffstats
path: root/src/managed/main.cpp
blob: 3f2ac5b79cfc34e7d1de491d154d1f83894913d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// Convert DMD CodeView debug information to PDB files

// Copyright (c) 2009 by Rainer Schuetze, All Rights Reserved

//

// License for redistribution is given by the Artistic License 2.0

// see file LICENSE for further details


// CLR interface to cv2pdb created by Alexander Bothe


#include "../PEImage.h"
#include "../cv2pdb.h"
#include "vcclr.h"

using namespace System;
using namespace System::IO;
using namespace System::Text;

namespace CodeViewToPDB
{
	///<summary>Exports DMD CodeView debug information from an executable file to a separate .pdb file</summary>

	public ref class CodeViewToPDBConverter
	{
	public:
		delegate void MsgHandler(String^ Message);
		///<summary>If an error occurs it will be reported via this event</summary>

		static event MsgHandler^ Message;
		
		///<summary>Exports DMD CodeView debug information from an executable file to a separate .pdb file</summary>

		static bool DoConvert(String^ InputExe,String^ OutputExe,String^ OutputPDBFile,bool IsD2)
		{
			if(!File::Exists(InputExe))
			{
				Message("Input file doesn't exist!");
				return false;
			}
			
			if(String::IsNullOrEmpty(OutputPDBFile) || String::IsNullOrEmpty(OutputExe))
			{
				Message("Empty arguments not allowed!");
				return false;
			}
		
			char* input=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(InputExe).ToPointer();
			char* outname=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(OutputExe).ToPointer();
			char* pdbname=(char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(OutputPDBFile).ToPointer();

			PEImage img(input);

			if (img.countCVEntries() == 0)
			{
				Message("No codeview debug entries found");
				return false;
			}

			CV2PDB cv2pdb(img);
			cv2pdb.initLibraries();
			cv2pdb.Dversion = IsD2?2:1;

			File::Delete(OutputPDBFile);

			if(cv2pdb.openPDB(pdbname) 
			&& cv2pdb.initSegMap() 
			&& cv2pdb.initGlobalTypes()
			&& cv2pdb.createModules()
			&& cv2pdb.addTypes()
			&& cv2pdb.addSymbols()
			&& cv2pdb.addSrcLines()
			&& cv2pdb.addPublics()
			&& cv2pdb.writeImage(outname))
			{	}
			else
			{
				Message(gcnew String(cv2pdb.getLastError()));
				return false;
			}
			
			return true;
		}
	
		static bool DoConvert(String^ Exe,String^ OutputPDBFile)
		{
			return DoConvert(Exe,Exe,OutputPDBFile,true);
		}
		
		static bool DoConvert(String^ Exe)
		{
			return DoConvert(Exe,Exe,Path::ChangeExtension(Exe,".pdb"),true);
		}
	};
}