Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1682)

Unified Diff: tools/win/static_initializers/static_initializers.cc

Issue 66613003: Static initializers tool for Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixes Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build/all.gyp ('k') | tools/win/static_initializers/static_initializers.gyp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/win/static_initializers/static_initializers.cc
diff --git a/tools/win/static_initializers/static_initializers.cc b/tools/win/static_initializers/static_initializers.cc
new file mode 100644
index 0000000000000000000000000000000000000000..a09715ee47263a71aa846cb79117b4cfcb3c2c21
--- /dev/null
+++ b/tools/win/static_initializers/static_initializers.cc
@@ -0,0 +1,178 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <dia2.h>
+#include <stdio.h>
+
+#include <string>
+
+// Create an IDiaData source and open a PDB file.
+static bool LoadDataFromPdb(const wchar_t* filename,
+ IDiaDataSource** source,
+ IDiaSession** session,
+ IDiaSymbol** global,
+ DWORD* machine_type) {
+ // Alternate path to search for debug data.
+ const wchar_t search_path[] = L"SRV**\\\\symbols\\symbols";
+ DWORD mach_type = 0;
+ HRESULT hr = CoInitialize(NULL);
+
+ // Obtain access to the provider.
+ hr = CoCreateInstance(__uuidof(DiaSource),
+ NULL,
+ CLSCTX_INPROC_SERVER,
+ __uuidof(IDiaDataSource),
+ (void**)source);
+
+ if (FAILED(hr)) {
+ printf("CoCreateInstance failed - HRESULT = %08X\n", hr);
+ return false;
+ }
+
+ wchar_t ext[MAX_PATH];
+ _wsplitpath_s(filename, NULL, 0, NULL, 0, NULL, 0, ext, MAX_PATH);
+
+ // Open and prepare the debug data associated with the executable.
+ hr = (*source)->loadDataForExe(filename, search_path, NULL);
+ if (FAILED(hr)) {
+ printf("loadDataForExe failed - HRESULT = %08X\n", hr);
+ return false;
+ }
+
+ // Open a session for querying symbols.
+ hr = (*source)->openSession(session);
+
+ if (FAILED(hr)) {
+ printf("openSession failed - HRESULT = %08X\n", hr);
+ return false;
+ }
+
+ // Retrieve a reference to the global scope.
+ hr = (*session)->get_globalScope(global);
+
+ if (FAILED(hr)) {
+ printf("get_globalScope failed\n");
+ return false;
+ }
+
+ // Set machine type for getting correct register names.
+ if (SUCCEEDED((*global)->get_machineType(&mach_type))) {
+ switch (mach_type) {
+ case IMAGE_FILE_MACHINE_I386:
+ *machine_type = CV_CFL_80386;
+ break;
+ case IMAGE_FILE_MACHINE_IA64:
+ *machine_type = CV_CFL_IA64;
+ break;
+ case IMAGE_FILE_MACHINE_AMD64:
+ *machine_type = CV_CFL_AMD64;
+ break;
+ default:
+ printf("unexpected machine type\n");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+// Release DIA objects and CoUninitialize.
+static void Cleanup(IDiaSymbol* global_symbol, IDiaSession* dia_session) {
+ if (global_symbol)
+ global_symbol->Release();
+ if (dia_session)
+ dia_session->Release();
+ CoUninitialize();
+}
+
+static void PrintIfDynamicInitializer(const std::wstring& module,
+ IDiaSymbol* symbol) {
+ DWORD symtag;
+
+ if (FAILED(symbol->get_symTag(&symtag)))
+ return;
+
+ if (symtag != SymTagFunction && symtag != SymTagBlock)
+ return;
+
+ BSTR bstr_name;
+ if (SUCCEEDED(symbol->get_name(&bstr_name))) {
+ if (wcsstr(bstr_name, L"`dynamic initializer for '")) {
+ wprintf(L"%s: %s\n", module.c_str(), bstr_name);
+ SysFreeString(bstr_name);
+ }
+ }
+}
+
+static bool DumpStaticInitializers(IDiaSymbol* global_symbol) {
+ // Retrieve the compilands first.
+ IDiaEnumSymbols* enum_symbols;
+ if (FAILED(global_symbol->findChildren(
+ SymTagCompiland, NULL, nsNone, &enum_symbols))) {
+ return false;
+ }
+
+ IDiaSymbol* compiland;
+ ULONG element_count = 0;
+
+ std::wstring current_module;
+ while (SUCCEEDED(enum_symbols->Next(1, &compiland, &element_count)) &&
+ (element_count == 1)) {
+ BSTR bstr_name;
+ if (FAILED(compiland->get_name(&bstr_name))) {
+ current_module = L"<unknown>";
+ } else {
+ current_module = bstr_name;
+ SysFreeString(bstr_name);
+ }
+
+ // Find all the symbols defined in this compiland, and print them if they
+ // have the name corresponding to an initializer.
+ IDiaEnumSymbols* enum_children;
+ if (SUCCEEDED(compiland->findChildren(
+ SymTagNull, NULL, nsNone, &enum_children))) {
+ IDiaSymbol* symbol;
+ ULONG children = 0;
+ while (SUCCEEDED(enum_children->Next(1, &symbol, &children)) &&
+ children == 1) { // Enumerate until we don't get any more symbols.
+ PrintIfDynamicInitializer(current_module, symbol);
+ symbol->Release();
+ }
+ enum_children->Release();
+ }
+ compiland->Release();
+ }
+
+ enum_symbols->Release();
+ return true;
+}
+
+int wmain(int argc, wchar_t* argv[]) {
+ if (argc != 2) {
+ wprintf(L"usage: %ls binary_name\n", argv[0]);
+ return 1;
+ }
+
+ IDiaDataSource* dia_data_source;
+ IDiaSession* dia_session;
+ IDiaSymbol* global_symbol;
+ DWORD machine_type = CV_CFL_80386;
+ if (!LoadDataFromPdb(argv[1],
+ &dia_data_source,
+ &dia_session,
+ &global_symbol,
+ &machine_type)) {
+ wprintf(L"Couldn't load data from pdb.\n");
+ return 1;
+ }
+
+ wprintf(L"Static initializers in %s:\n", argv[1]);
+
+ if (!DumpStaticInitializers(global_symbol))
+ return 1;
+
+ Cleanup(global_symbol, dia_session);
+
+ return 0;
+}
« no previous file with comments | « build/all.gyp ('k') | tools/win/static_initializers/static_initializers.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698