Пример #1
0
sBool PDBFileReader::ReadDebugInfo(sChar *fileName,DebugInfo &to)
{
    sBool readOk = sFALSE;

    if(FAILED(CoInitialize(0)))
        return sFALSE;

    IDiaDataSource *source = 0;
    CoCreateInstance(__uuidof(DiaSource),0,CLSCTX_INPROC_SERVER,
                     __uuidof(IDiaDataSource),(void**) &source);

    if(source)
    {
        wchar_t wideFileName[260];
        mbstowcs(wideFileName,fileName,260);
        if(SUCCEEDED(source->loadDataForExe(wideFileName,0,0)))
        {
            if(SUCCEEDED(source->openSession(&Session)))
            {
                ReadEverything(to);

                readOk = sTRUE;
                Session->Release();
            }
        }

        source->Release();
    }

    CoUninitialize();

    return readOk;
}
Пример #2
0
  void close()
  {
    if ( pGlobal != NULL )
    {
      pGlobal->Release();
      pGlobal = NULL;
    }

    if ( pSession != NULL )
    {
      pSession->Release();
      pSession = NULL;
    }

    if ( pSource != NULL )
    {
      pSource->Release();
      pSource = NULL;
    }

    if ( dia_hmod != NULL )
    {
      FreeLibrary(dia_hmod);
      dia_hmod = NULL;
    }
  }
Пример #3
0
static void ProcessPdbFile(const char *fileNameA)
{
    HRESULT             hr;
    IDiaDataSource *    dia = NULL;
    IDiaSession *       session = NULL;
    str::Str<char>      report;

    dia = LoadDia();
    if (!dia)
        return;

    ScopedMem<WCHAR> fileName(str::conv::FromAnsi(fileNameA));
    hr = dia->loadDataForExe(fileName, 0, 0);
    if (FAILED(hr)) {
        logf("  failed to load %s or its debug symbols from .pdb file\n", fileNameA);
        goto Exit;
    }

    hr = dia->openSession(&session);
    if (FAILED(hr)) {
        log("  failed to open DIA session\n");
        goto Exit;
    }

    if (g_dumpTypes)
        DumpTypes(session);

    if (g_dumpSections)
        DumpSections(session);

    if (g_dumpSymbols)
        DumpSymbols(session);

    fputs("Format: 1\n", stdout);
    if (g_compact) {
        str::Str<char> res;
        GetInternedStringsReport(res);
        fputs(res.Get(), stdout);
    }
    fputs(g_report.Get(), stdout);

Exit:
    UnkReleaseSafe(session);
}
Пример #4
0
IDiaSymbol* PF_OpenAndFindGlobalScopeFromPdbFile(const wchar_t *szFilename)
{
	IDiaSession *pSession = NULL;
	IDiaSymbol *pGlobalScope = NULL;
	IDiaDataSource *pSource;

	HRESULT hr = CoCreateInstance(CLSID_DiaSource,
		NULL,
		CLSCTX_INPROC_SERVER,
		__uuidof(IDiaDataSource),
		(void **)&pSource);
	if (FAILED(hr))
	{
		fwprintf_s(stdout, L"Could not CoCreate CLSID_DiaSource.\n");
		return NULL;
	}

	if (FAILED(pSource->loadDataFromPdb(szFilename)))
	{
		fwprintf_s(stdout, L"loadDataFromPdb.\n");
		return NULL;
	}
	if (FAILED(pSource->openSession(&pSession)))
	{
		fwprintf_s(stdout, L"openSession.\n");
		pSession = 0;
		return NULL;
	}

	if (FAILED(pSession->get_globalScope(&pGlobalScope)))
	{
		fwprintf_s(stdout, L"globalscope.\n");
		pSession = 0;
		pGlobalScope = 0;
		return NULL;
	}
	pSession = 0;
	return pGlobalScope;
}
Пример #5
0
  HRESULT open(
    const char *input_file,
    const char *user_spath = NULL,
    ea_t load_address = BADADDR,
    input_exe_reader_t exe_reader = NULL,
    input_mem_reader_t mem_reader = NULL)
  {
    // Already open?
    if ( pSession != NULL )
      return S_OK;

    // When the debugger is active, first try to load debug directory from the memory
    ea_t load_address_order[2];
    // when remote debugging, don't use files on disk
    bool remote_debug = false;
#ifndef BUILDING_EFD
#ifndef PDBTOTIL
    if ( get_process_state() != DSTATE_NOTASK )
    {
      load_address_order[0] = load_address;
      load_address_order[1] = BADADDR;
      remote_debug = dbg->is_remote();
    }
    else
#endif
#endif
    {
      load_address_order[0] = BADADDR;
      load_address_order[1] = load_address;
    }

    HRESULT hr;
    do
    {
      // No interface was created?
      hr = create_dia_source();
      if ( FAILED(hr) )
        break;

      qwstring wpath, winput;
      get_input_and_sym_path(input_file, user_spath, winput, wpath);

      if ( exe_reader == NULL && mem_reader == NULL && !remote_debug )
        // Try to load input file as PDB
        hr = pSource->loadDataFromPdb(winput.c_str());
      else
        hr = E_FAIL;

      // Failed? Try to load as EXE
      if ( FAILED(hr) )
      {
        CCallback callback(exe_reader, mem_reader);
        callback.AddRef();

        if ( !remote_debug )
        {
          // Open the executable
          callback.OpenExe(winput.c_str());
        }

        for ( int i=0; i < qnumber(load_address_order); i++ )
        {
          callback.SetLoadAddress(load_address_order[i]);
          hr = pSource->loadDataForExe(winput.c_str(), wpath.c_str(), (IDiaLoadCallback *)&callback);
          if ( SUCCEEDED(hr) )
            break;
        }
      }

      // Failed? Then nothing else to try, quit
      if ( FAILED(hr) )
        break;

      // Open a session for querying symbols
      hr = pSource->openSession(&pSession);
      if ( FAILED(hr) )
        break;

      // Set load address
      if ( load_address != BADADDR )
        pSession->put_loadAddress(load_address);

      // Retrieve a reference to the global scope
      hr = pSession->get_globalScope(&pGlobal);
      if ( FAILED(hr) )
        break;

      hr = S_OK;
    } while ( false );

    // Make sure we cleanup
    if ( FAILED(hr) )
      close();

    return hr;
  }
Пример #6
0
DDR_RC
PdbScanner::startScan(OMRPortLibrary *portLibrary, Symbol_IR *ir, vector<string> *debugFiles, const char *blacklistPath)
{
	DDR_RC rc = DDR_RC_OK;
	IDiaDataSource *diaDataSource = NULL;
	IDiaSession *diaSession = NULL;
	IDiaSymbol *diaSymbol = NULL;
	_ir = ir;

	initBaseTypeList();

	if (FAILED(CoInitialize(NULL))) {
		rc = DDR_RC_ERROR;
	}

	if (DDR_RC_OK == rc) {
		rc = loadBlacklist(blacklistPath);
	}

	if (DDR_RC_OK == rc) {
		/* For each input Pdb file, load the file, then add the UDTs and Enums.
		 * If findChildren(SymTagNull, ...) were to be used instead of finding
		 * the UDTs and enums separately, duplicate types are returned with
		 * undecorated names. The IR would contain inner classes twice, once as
		 * an inner class, and once with no parent link and an undecorated name.
		 * Finding UDT and enum children separately seems to work around this
		 * quirk in the PDB API.
		 */
		for (vector<string>::iterator it = debugFiles->begin(); it != debugFiles->end(); ++it) {
			const string &file = *it;
			const size_t len = file.length();
			wchar_t *filename = new wchar_t[len + 1];
			mbstowcs(filename, file.c_str(), len + 1);
			rc = loadDataFromPdb(filename, &diaDataSource, &diaSession, &diaSymbol);

			if (DDR_RC_OK == rc) {
				rc = addChildrenSymbols(diaSymbol, SymTagUDT, NULL);
			}

			if (DDR_RC_OK == rc) {
				rc = addChildrenSymbols(diaSymbol, SymTagEnum, NULL);
			}

			if (DDR_RC_OK == rc) {
				rc = addChildrenSymbols(diaSymbol, SymTagTypedef, NULL);
			}

			if (NULL != diaDataSource) {
				diaDataSource->Release();
				diaDataSource = NULL;
			}
			if (NULL != diaSession) {
				diaSession->Release();
				diaSession = NULL;
			}
			if (NULL != diaSymbol) {
				diaSymbol->Release();
				diaSymbol = NULL;
			}
			delete[] filename;
			if (DDR_RC_OK != rc) {
				break;
			}
		}
	}
	/* Field and superclass types which are needed before the type is found
	 * are added to a postponed list. After all types are found, process the
	 * postponed list to add these missing references.
	 */
	if (DDR_RC_OK == rc) {
		rc = updatePostponedFieldNames();
	}

	CoUninitialize();

	return rc;
}
Пример #7
0
sBool PDBFileReader::ReadDebugInfo(sChar *fileName,DebugInfo &to)
{
	static const struct DLLDesc
	{
		const char *Filename;
		IID UseCLSID;
	} DLLs[] = {
		"msdia71.dll", __uuidof(DiaSource71),
		"msdia80.dll", __uuidof(DiaSource80),
		"msdia90.dll", __uuidof(DiaSource90),
		// add more here as new versions appear (as long as they're backwards-compatible)
		0
	};

  sBool readOk = false;

  if(FAILED(CoInitialize(0)))
	{
		fprintf(stderr, "  failed to initialize COM\n");
    return false;
	}

  IDiaDataSource *source = 0;
  HRESULT hr = E_FAIL;

	// Try creating things "the official way"
	for(sInt i=0;DLLs[i].Filename;i++)
	{
		hr = CoCreateInstance(DLLs[i].UseCLSID,0,CLSCTX_INPROC_SERVER,
			__uuidof(IDiaDataSource),(void**) &source);

		if(SUCCEEDED(hr))
			break;
	}

  if(FAILED(hr))
  {
		// None of the classes are registered, but most programmers will have the
		// DLLs on their system anyway and can copy it over; try loading it directly.

		for(sInt i=0;DLLs[i].Filename;i++)
		{
			HMODULE hDIADll = LoadLibrary(DLLs[i].Filename);
			if(hDIADll)
			{
				typedef HRESULT (__stdcall *PDllGetClassObject)(REFCLSID rclsid,REFIID riid,void** ppvObj);
				PDllGetClassObject DllGetClassObject = (PDllGetClassObject) GetProcAddress(hDIADll,"DllGetClassObject");
				if(DllGetClassObject)
				{
					// first create a class factory
          IClassFactory *classFactory;
					hr = DllGetClassObject(DLLs[i].UseCLSID,IID_IClassFactory,(void**) &classFactory);
					if(SUCCEEDED(hr))
					{
						hr = classFactory->CreateInstance(0,__uuidof(IDiaDataSource),(void**) &source);
						classFactory->Release();
					}
				}

				if(SUCCEEDED(hr))
					break;
				else
					FreeLibrary(hDIADll);
			}
		}
  }

  if(source)
  {
    wchar_t wideFileName[260];
    mbstowcs(wideFileName,fileName,260);
    if(SUCCEEDED(source->loadDataForExe(wideFileName,0,0)))
    {
      if(SUCCEEDED(source->openSession(&Session)))
      {
        ReadEverything(to);

        readOk = true;
        Session->Release();
      }
			else
				fprintf(stderr,"  failed to open DIA session\n");
    }
		else
			fprintf(stderr,"  failed to load debug symbols (PDB not found)\n");

    source->Release();
  }
	else
		fprintf(stderr,"  couldn't find (or properly initialize) any DIA dll, copying msdia*.dll to app dir might help.\n");

  CoUninitialize();

  return readOk;
}
Пример #8
0
bool LoadDIASymbols(const wxString &strPDBFile, 
					wxInt32 modulenum,
					std::list<CFunctionDescription> & llFuncs,
					stdext::hash_map<BasedAddress,int> & addressmap
					)
{
	// Create DIA80 Data Source Object
	IDiaDataSource *pDataSource;
	HRESULT hr = NoRegCoCreate( L"msdia80.dll", _uuidof( DiaSource ), _uuidof( IDiaDataSource ), (void **) &(pDataSource));
	if(!SUCCEEDED(hr)) 
	{
		return false;
	}
	/*
	HMODULE mod=LoadLibrary(L"msdia80.dll");
	if(!mod)
	{
		return false;
	}

	TYPEOF_DllGetClassObject *pGetClassObject=(TYPEOF_DllGetClassObject *)GetProcAddress(mod,"DllGetClassObject");
	if(!pGetClassObject)
	{
		FreeLibrary(mod);
		return false;
	}

	IClassFactory *pcf;
	HRESULT hr=(*pGetClassObject)(CLSID_DiaSource,IID_IClassFactory,(void **)&pcf);
	if(!SUCCEEDED(hr))
	{
		FreeLibrary(mod);
		return false;
	}

	IDiaDataSource *pDataSource;
	hr=pcf->CreateInstance(NULL,_uuidof(IDiaDataSource),(void **)&pDataSource);
	if(!SUCCEEDED(hr))
	{
		pcf->Release();
		FreeLibrary(mod);
		return false;
	}
	pcf->Release();
*/
		
	// Load the executable's debug symbols
	hr=pDataSource->loadDataFromPdb(strPDBFile);
	if(!SUCCEEDED(hr))
	{
		pDataSource->Release();
		return false;	
	}
	
	// Open a symbol session
	IDiaSession *pDIASession;
	hr=pDataSource->openSession(&pDIASession);
	if(!SUCCEEDED(hr)) 
	{
		pDataSource->Release();
		return false;
	}

	// Set the UNBASED address on the session, for resolving BasedAddress addrs
	hr=pDIASession->put_loadAddress(0);
	if(!SUCCEEDED(hr)) 
	{
		pDIASession->Release();
		pDataSource->Release();
		return false;
	}

	// Get addresses for this module
	std::list<BasedAddress> addresses;
	for(stdext::hash_map<BasedAddress,int>::iterator iter=addressmap.begin();iter!=addressmap.end();iter++)
	{
		if(iter->first.nModule==modulenum)
		{
			addresses.push_back(iter->first);
		}
	}
	stdext::hash_map<DWORD,wxInt32> functions;

	int curidx=(int)llFuncs.size();

	for(std::list<BasedAddress>::iterator itera=addresses.begin();itera!=addresses.end();itera++)
	{
		// Get the symbol for this thing
		IDiaSymbol* pFunc;
		if(FAILED(pDIASession->findSymbolByVA(itera->nAddr, SymTagFunction, &pFunc)) || pFunc==NULL)
		{
			continue;
		}

		// Get the unique symbol index id
		DWORD indexId;
		if(FAILED(pFunc->get_symIndexId(&indexId)))
		{
			pFunc->Release();
			continue;
		}

		// See if we have this function already
		stdext::hash_map<DWORD,int>::iterator iterf=functions.find(indexId);
		if(iterf!=functions.end())
		{
			addressmap[*itera]=iterf->second;
		}
		else
		{
			CFunctionDescription func;
	
			//////
			ULONGLONG addr;
			if(FAILED(pFunc->get_virtualAddress(&addr)))
			{
				pFunc->Release();
				continue;
			}

			//////
			ULONGLONG length;
			if(FAILED(pFunc->get_length(&length)))
			{
				pFunc->Release();
				continue;
			}

			/////////
			BSTR pName;
			if(FAILED(pFunc->get_name(&pName)))
			{
				pFunc->Release();
				continue;
			}
			func.strMangledName=(const LPWSTR)pName;
			LocalFree(pName);
				
			char mangled[512];
			WideCharToMultiByte(CP_UTF8,0,func.strMangledName,-1,mangled,512,NULL,NULL);
			
			/////////
			char outbase[512];
			__unDName(outbase,mangled,512,&malloc,&free,0x1000);
			wchar_t outbasew[512];
			MultiByteToWideChar(CP_UTF8,0,outbase,-1,outbasew,512);
			
			func.strBaseName=(const wchar_t *)(outbasew);

			/////////
			char outfull[512];
			__unDName(outfull,mangled,512,&malloc,&free,0);
			wchar_t outfullw[512];
			MultiByteToWideChar(CP_UTF8,0,outfull,-1,outfullw,512);
			
			func.strFullName=(const wchar_t *)(outfullw);


			//////////
			func.nAddress=BasedAddress(addr,modulenum);
			func.nByteLength=length;
			
			/////////

			IDiaEnumLineNumbers *pdeln;
			func.strSourceFile=wxT("<unknown>");
			func.nFirstSourceLine=0;
			func.nLastSourceLine=0;
			bool bGotFile=false;
			if(SUCCEEDED(pDIASession->findLinesByVA(addr,length,&pdeln)))
			{
				IDiaLineNumber *pdln;
				int nLineItem=0;
				while(SUCCEEDED(pdeln->Item(nLineItem,&pdln)))
				{
					DWORD dwLineNumber;
					IDiaSourceFile *pdsf;
					if(SUCCEEDED(pdln->get_lineNumber(&dwLineNumber)) &&
						SUCCEEDED(pdln->get_sourceFile(&pdsf)))
					{
						BSTR filename;
						if(SUCCEEDED(pdsf->get_fileName(&filename)))
						{
							if(bGotFile)
							{
								if(filename==func.strSourceFile)
								{
									if(dwLineNumber<func.nFirstSourceLine)
									{
										func.nFirstSourceLine=dwLineNumber;
									}
									if(dwLineNumber>func.nLastSourceLine)
									{
										func.nLastSourceLine=dwLineNumber;
									}
								}
							}
							else
							{
								bGotFile=true;
								func.strSourceFile=filename;
								func.nFirstSourceLine=dwLineNumber;
								func.nLastSourceLine=dwLineNumber;
							}
							LocalFree(filename);
						}
						pdsf->Release();
					}
					pdln->Release();
					nLineItem++;
				}
				pdeln->Release();
			}
           
			llFuncs.push_back(func);

			functions[indexId]=curidx;

			addressmap[*itera]=curidx;

			curidx++;
		}
	}
	
	pDIASession->Release();
	pDataSource->Release();
		
//	FreeLibrary(mod);

	return true;
}