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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « build/all.gyp ('k') | tools/win/static_initializers/static_initializers.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <dia2.h>
6 #include <stdio.h>
7
8 #include <string>
9
10 // Create an IDiaData source and open a PDB file.
11 static bool LoadDataFromPdb(const wchar_t* filename,
12 IDiaDataSource** source,
13 IDiaSession** session,
14 IDiaSymbol** global,
15 DWORD* machine_type) {
16 // Alternate path to search for debug data.
17 const wchar_t search_path[] = L"SRV**\\\\symbols\\symbols";
18 DWORD mach_type = 0;
19 HRESULT hr = CoInitialize(NULL);
20
21 // Obtain access to the provider.
22 hr = CoCreateInstance(__uuidof(DiaSource),
23 NULL,
24 CLSCTX_INPROC_SERVER,
25 __uuidof(IDiaDataSource),
26 (void**)source);
27
28 if (FAILED(hr)) {
29 printf("CoCreateInstance failed - HRESULT = %08X\n", hr);
30 return false;
31 }
32
33 wchar_t ext[MAX_PATH];
34 _wsplitpath_s(filename, NULL, 0, NULL, 0, NULL, 0, ext, MAX_PATH);
35
36 // Open and prepare the debug data associated with the executable.
37 hr = (*source)->loadDataForExe(filename, search_path, NULL);
38 if (FAILED(hr)) {
39 printf("loadDataForExe failed - HRESULT = %08X\n", hr);
40 return false;
41 }
42
43 // Open a session for querying symbols.
44 hr = (*source)->openSession(session);
45
46 if (FAILED(hr)) {
47 printf("openSession failed - HRESULT = %08X\n", hr);
48 return false;
49 }
50
51 // Retrieve a reference to the global scope.
52 hr = (*session)->get_globalScope(global);
53
54 if (FAILED(hr)) {
55 printf("get_globalScope failed\n");
56 return false;
57 }
58
59 // Set machine type for getting correct register names.
60 if (SUCCEEDED((*global)->get_machineType(&mach_type))) {
61 switch (mach_type) {
62 case IMAGE_FILE_MACHINE_I386:
63 *machine_type = CV_CFL_80386;
64 break;
65 case IMAGE_FILE_MACHINE_IA64:
66 *machine_type = CV_CFL_IA64;
67 break;
68 case IMAGE_FILE_MACHINE_AMD64:
69 *machine_type = CV_CFL_AMD64;
70 break;
71 default:
72 printf("unexpected machine type\n");
73 return false;
74 }
75 }
76
77 return true;
78 }
79
80 // Release DIA objects and CoUninitialize.
81 static void Cleanup(IDiaSymbol* global_symbol, IDiaSession* dia_session) {
82 if (global_symbol)
83 global_symbol->Release();
84 if (dia_session)
85 dia_session->Release();
86 CoUninitialize();
87 }
88
89 static void PrintIfDynamicInitializer(const std::wstring& module,
90 IDiaSymbol* symbol) {
91 DWORD symtag;
92
93 if (FAILED(symbol->get_symTag(&symtag)))
94 return;
95
96 if (symtag != SymTagFunction && symtag != SymTagBlock)
97 return;
98
99 BSTR bstr_name;
100 if (SUCCEEDED(symbol->get_name(&bstr_name))) {
101 if (wcsstr(bstr_name, L"`dynamic initializer for '")) {
102 wprintf(L"%s: %s\n", module.c_str(), bstr_name);
103 SysFreeString(bstr_name);
104 }
105 }
106 }
107
108 static bool DumpStaticInitializers(IDiaSymbol* global_symbol) {
109 // Retrieve the compilands first.
110 IDiaEnumSymbols* enum_symbols;
111 if (FAILED(global_symbol->findChildren(
112 SymTagCompiland, NULL, nsNone, &enum_symbols))) {
113 return false;
114 }
115
116 IDiaSymbol* compiland;
117 ULONG element_count = 0;
118
119 std::wstring current_module;
120 while (SUCCEEDED(enum_symbols->Next(1, &compiland, &element_count)) &&
121 (element_count == 1)) {
122 BSTR bstr_name;
123 if (FAILED(compiland->get_name(&bstr_name))) {
124 current_module = L"<unknown>";
125 } else {
126 current_module = bstr_name;
127 SysFreeString(bstr_name);
128 }
129
130 // Find all the symbols defined in this compiland, and print them if they
131 // have the name corresponding to an initializer.
132 IDiaEnumSymbols* enum_children;
133 if (SUCCEEDED(compiland->findChildren(
134 SymTagNull, NULL, nsNone, &enum_children))) {
135 IDiaSymbol* symbol;
136 ULONG children = 0;
137 while (SUCCEEDED(enum_children->Next(1, &symbol, &children)) &&
138 children == 1) { // Enumerate until we don't get any more symbols.
139 PrintIfDynamicInitializer(current_module, symbol);
140 symbol->Release();
141 }
142 enum_children->Release();
143 }
144 compiland->Release();
145 }
146
147 enum_symbols->Release();
148 return true;
149 }
150
151 int wmain(int argc, wchar_t* argv[]) {
152 if (argc != 2) {
153 wprintf(L"usage: %ls binary_name\n", argv[0]);
154 return 1;
155 }
156
157 IDiaDataSource* dia_data_source;
158 IDiaSession* dia_session;
159 IDiaSymbol* global_symbol;
160 DWORD machine_type = CV_CFL_80386;
161 if (!LoadDataFromPdb(argv[1],
162 &dia_data_source,
163 &dia_session,
164 &global_symbol,
165 &machine_type)) {
166 wprintf(L"Couldn't load data from pdb.\n");
167 return 1;
168 }
169
170 wprintf(L"Static initializers in %s:\n", argv[1]);
171
172 if (!DumpStaticInitializers(global_symbol))
173 return 1;
174
175 Cleanup(global_symbol, dia_session);
176
177 return 0;
178 }
OLDNEW
« 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