You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
5.4 KiB
179 lines
5.4 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
/*! @file
|
|
* pin tool combined from multi-DLLs (main_dll, dynamic_secondary_dll, static_secondary_dll).
|
|
* This is the "main DLL", use PIN API only in this DLL
|
|
* usage of PIN API in dynamic_secondary_dll and static_secondary_dll is not allowed
|
|
* (see README for more inforamtion)
|
|
*
|
|
* NOTE: New Pin image loader supports dynamic loading of Pin DLLs.
|
|
* Look at Mantis 3280 for implementation details.
|
|
* The test also validates the dynamic loading feature.
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <fstream>
|
|
|
|
#include <link.h>
|
|
#include <dlfcn.h>
|
|
|
|
#include "pin.H"
|
|
|
|
using std::cerr;
|
|
using std::endl;
|
|
using std::hex;
|
|
using std::string;
|
|
|
|
KNOB<BOOL> KnobEnumerate(KNOB_MODE_WRITEONCE, "pintool",
|
|
"enumerate", "0", "Enumerate modules loaded by Pin");
|
|
|
|
KNOB<string> KnobOutputFile1(KNOB_MODE_WRITEONCE, "pintool",
|
|
"o1", "static_secondary_dll.out", "Output file 1");
|
|
|
|
KNOB<string> KnobOutputFile2(KNOB_MODE_WRITEONCE, "pintool",
|
|
"o2", "dynamic_secondary_dll.out", "Output file 2");
|
|
|
|
/* ===================================================================== */
|
|
/* Global Variables and Declerations */
|
|
/* ===================================================================== */
|
|
|
|
PIN_LOCK pinLock;
|
|
|
|
typedef VOID (* BEFORE_BBL)(ADDRINT ip);
|
|
typedef int (* INIT_F)(bool enumerate, const char* out_filename);
|
|
typedef VOID (* FINI_F)();
|
|
|
|
// Functions pointers for dynamic_secondary_dll
|
|
BEFORE_BBL pBeforeBBL2;
|
|
INIT_F pInit2;
|
|
FINI_F pFini2;
|
|
|
|
// Dll imports for static_secondary_dll
|
|
extern "C" __declspec( dllimport ) VOID BeforeBBL1(ADDRINT ip);
|
|
extern "C" __declspec( dllimport ) VOID Init1(const char*);
|
|
extern "C" __declspec( dllimport ) VOID Fini1();
|
|
|
|
/* ===================================================================== */
|
|
|
|
// This function is called before every basic block
|
|
VOID PIN_FAST_ANALYSIS_CALL BeforeBBL(ADDRINT ip)
|
|
{
|
|
PIN_GetLock(&pinLock, PIN_GetTid());
|
|
BeforeBBL1(ip);
|
|
pBeforeBBL2(ip);
|
|
PIN_ReleaseLock(&pinLock);
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
|
|
// Pin calls this function every time a new trace is encountered
|
|
VOID Trace(TRACE trace, VOID *v)
|
|
{
|
|
// Visit every basic block in the trace
|
|
for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl))
|
|
{
|
|
// Insert a call to BeforeBBL before every bbl, passing the ip address.
|
|
BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)BeforeBBL, IARG_FAST_ANALYSIS_CALL,
|
|
IARG_INST_PTR, IARG_END);
|
|
}
|
|
}
|
|
|
|
VOID ThreadStart(THREADID threadid, CONTEXT *ctxt, INT32 flags, VOID *v)
|
|
{
|
|
PIN_GetLock(&pinLock, PIN_GetTid());
|
|
BeforeBBL1(0);
|
|
pBeforeBBL2(0);
|
|
PIN_ReleaseLock(&pinLock);
|
|
}
|
|
|
|
VOID ThreadFini(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v)
|
|
{
|
|
PIN_GetLock(&pinLock, PIN_GetTid());
|
|
BeforeBBL1(0);
|
|
pBeforeBBL2(0);
|
|
PIN_ReleaseLock(&pinLock);
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
|
|
// This function is called when the application exits
|
|
VOID Fini(INT32 code, VOID *v)
|
|
{
|
|
Fini1();
|
|
pFini2();
|
|
}
|
|
|
|
// This function gets info of an image loaded by Pin loader.
|
|
// Invoked by dl_iterate_phdr()
|
|
int dl_iterate_callback(struct dl_phdr_info * info, size_t size, VOID * data)
|
|
{
|
|
cerr << info->dlpi_name << " " << hex << info->dlpi_addr << " " << info->dlpi_phdr->p_memsz << endl;
|
|
// Increment module counter.
|
|
++(*reinterpret_cast<int *>(data));
|
|
return 0;
|
|
}
|
|
|
|
/* ===================================================================== */
|
|
|
|
int main(int argc, char * argv[])
|
|
{
|
|
// Initialize pin
|
|
PIN_Init(argc, argv);
|
|
|
|
PIN_InitLock(&pinLock);
|
|
|
|
// Register Trace() to be called to instrument traces
|
|
TRACE_AddInstrumentFunction(Trace, 0);
|
|
|
|
// Register Fini() to be called when the application exits
|
|
PIN_AddFiniFunction(Fini, 0);
|
|
|
|
// Call Static secondary dll Init1()
|
|
Init1(KnobOutputFile1.Value().c_str());
|
|
|
|
int nModules;
|
|
|
|
// Dynamic secondary dll - load library, initialize function pointers
|
|
// and call Init2()
|
|
VOID * module = dlopen("dynamic_secondary_dll.dll", RTLD_NOW);
|
|
if (module == NULL)
|
|
{
|
|
cerr << "Failed to load dynamic_secondary_dll.dll" << endl;
|
|
exit(1);
|
|
}
|
|
pInit2 = reinterpret_cast<INIT_F>(dlsym(module, "Init2"));
|
|
pBeforeBBL2 = reinterpret_cast<BEFORE_BBL>(dlsym(module, "BeforeBBL2"));
|
|
pFini2 = reinterpret_cast<FINI_F>(dlsym(module, "Fini2"));
|
|
if (pInit2 == NULL || pBeforeBBL2 == NULL || pFini2 == NULL)
|
|
{
|
|
cerr << "Failed to find proc addresses in dynamic_secondary_dll.dll" << endl;
|
|
exit(1);
|
|
}
|
|
|
|
nModules = pInit2(KnobEnumerate, KnobOutputFile2.Value().c_str());
|
|
|
|
int nModulesMain = 0;
|
|
// Enumerate DLLs currently loaded by Pin loader.
|
|
dl_iterate_phdr(dl_iterate_callback, &nModulesMain);
|
|
|
|
if (KnobEnumerate && ((nModulesMain <= 0) || (nModulesMain != nModules)))
|
|
{
|
|
// Failure. Module enumeration results in main and dynamic Dlls don't match.
|
|
PIN_ExitApplication(1);
|
|
}
|
|
|
|
// Start the program, never returns
|
|
PIN_StartProgram();
|
|
|
|
return 0;
|
|
}
|