Thursday, May 2, 2013

No MAKE mistakes and build PINtool with Visual Studio

A not very long ago (late 2010), I started to look into PIN (you don't need a description. do you?) and the there were some inconveniences discovered. Well to name a few:
  • Press F7 and get a pintool Dll.
  • No Intellisence for PIN related code.
  • Bad syntax coloring for PIN Code.
  • No code definition.
  • Not to use VS console to build.
  • No other tools like GNU Make or NMake,...
  • Build the anywhere I like
Documentation says modify any of tools in PIN sources folder and use make and live with what you have. I din't like it because it was more like writing code in Notepad for PIN part, so started to look how to make it more likable. There were two places to look, 
  • Make files
  • MyPinTool.sln (Sample Visual Studio Project)
While looking at these places I found enough information to solve all the problems listed above. A step-by-step guide is as follows (To save there'll be mostly pictures) assuming you have successfully created a Empty Project in Visual Studio and have added some C/C++ source.

Step 1: create a build macro:
  Step 1.1: Click View-> Property Manager
   Step 1.2: Property Page
Property Manager
 Step 1.3: Add New Property Sheet
Add New Property Sheet
 Step 1.4: Name the sheet and Click "Add"


Step 1.5: Sheet Properties
Step 1.6: User Macros(1) -> Add Marco(2) -> Name = "Anything like PinDir" and Value = "Path to extracted PIN root directory" -> Check "Set this macro as ..." box -> OK.



Congratulations, you have just added PIN directory as build macro. This (Value of macro) be the only if you change PIN path or version.

Step 2: Compiler Settings
 Step 2.1: Project -> Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories -> [DROP_DOWN] -> <Edit...>

 Step 2.2: PinDir is the macro we created in Step 1  
Additional Include Directories.
 Alternatively you can just paste following content in the box next to "Additional Include Directories" (Step 2.1)

$(PinDir)\extras\xed2-ia32\include;$(PinDir)\source\tools\InstLib;$(PinDir)\source\include\gen;$(PinDir)\source\include;$(PinDir)\extras\components\include;%(AdditionalIncludeDirectories)

There may be some directories that may not be required in all the projects but "it works" :) . From here onward assuming you are in "C/C++" section in "Property Pages".

 Step 2.3: Compiler Preprocessors
    Paste following in Preprocessors -> Preprocessor Definitions
  TARGET_WINDOWS;BIGARRAY_MULTIPLIER=1;USING_XED;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0;TARGET_IA32;HOST_IA32;%(PreprocessorDefinitions)
  
Preprocessors listed above are joined by ';'. I don't know use/meaning (yet) of most of them but again , It works.

  Step 2.4: Optimization
   Optimization => Disables(/Od)
   Enable Intrinsic Functions => Yes(/Oi)

  Step 2.5: Code Generation
   Enable Minimal Rebuild => No(/Gm)
   Enable C++ Exceptions => No
   Runtime Library => Multi Threaded(/MT)

Step 2.6: Advanced
  Disable Specific Warnings: 4530

After all the options are "Apply"ied, my compiler Command Line looks like:

/I"C:\Pin\pin-2.12-58423-msvc10-windows\extras\xed2-ia32\include" /I"C:\Pin\pin-2.12-58423-msvc10-windows\source\tools\InstLib" /I"C:\Pin\pin-2.12-58423-msvc10-windows\source\include\pin\gen" /I"C:\Pin\pin-2.12-58423-msvc10-windows\source\include\pin" /I"C:\Pin\pin-2.12-58423-msvc10-windows\extras\components\include" /ZI /nologo /W3 /WX- /Od /Oi /Oy- /D "TARGET_WINDOWS" /D "BIGARRAY_MULTIPLIER=1" /D "USING_XED" /D "_CRT_SECURE_NO_DEPRECATE" /D "_SECURE_SCL=0" /D "TARGET_IA32" /D "HOST_IA32" /D "_WINDLL" /Gm- /RTC1 /MT /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\CallLog.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /wd"4530" /analyze- /errorReport:queue 

Step 3: Linker Settings
 Lets begin Main Manu Bar
  Step 3.1: Additional Libraries
  Project -> Properties -> Configuration Properties -> Linker -> Additional Library Directories -> [DROP_DOWN] -> <Edit...>

Step 3.2: Add Libraries Directories

 AlternatievelyYou can paste following content in the box next to "Additional Library Directories"
$(PinDir)\ia32\lib-ext;$(PinDir)\extras\xed2-ia32\lib;$(PinDir)\ia32\lib;%(AdditionalLibraryDirectories)

 Step 3.3: Add Libraries
   Input -> Additional Dependencies -> [DROP_DOWN] -> <Edit...>
Not: Do not forget to Uncheck the "Inherit from ...." box (3) at the bottom. There are some conflicts with default libraries.

Or you can paste following line in the "Additional Dependencies" box
pin.lib;libxed.lib;libcpmt.lib;libcmt.lib;pinvm.lib;kernel32.lib;ntdll-32.lib

  Step 3.4: Ignore Default Libraries
   Ignore All Default Libraries => Yes (/NODEFAULTLIB)

  Step 3.5: Advanced
   Entry Point => Ptrace_DllMainCRTStartup@12
  Step 3.6: Command Line
   Additional Options => /EXPORT:main
 After "Apply"ing all linker settings the command line looks like 
/OUT:"C:\******\visual studio 2010\Projects\CallLog\Debug\CallLog.dll" /NOLOGO /LIBPATH:"C:\Pin\pin-2.12-58423-msvc10-windows\ia32\lib-ext" /LIBPATH:"C:\Pin\pin-2.12-58423-msvc10-windows\extras\xed2-ia32\lib" /LIBPATH:"C:\Pin\pin-2.12-58423-msvc10-windows\ia32\lib" /LIBPATH:"C:\Pin\pin-2.12-58423-msvc10-windows\extras\components\lib\ia32" /DLL "pin.lib" "libxed.lib" "libcpmt.lib" "libcmt.lib" "pinvm.lib" "kernel32.lib" "ntdll-32.lib" /NODEFAULTLIB /MANIFEST /ManifestFile:"Debug\CallLog.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\******\visual studio 2010\Projects\CallLog\Debug\CallLog.pdb" /PGD:"C:\******\visual studio 2010\Projects\CallLog\Debug\CallLog.pgd" /TLBID:1 /ENTRY:"Ptrace_DllMainCRTStartup@12" /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE 
Thats all that we need to do to build a pintool only with Visual Studio (I used 2010/2008. Not tested on 2012) unless I forgot to tell you that we must tell Visual Studio to create a Dll and not to use Multi-Byte-Character-Set like this.

Hope this helped you even if that you is me some time in future.

Important: All the steps mentioned above "just work". I din't ask so many questions so won't answer.