OLD | NEW |
1 // Copyright 2012 Google Inc. All Rights Reserved. | 1 // Copyright 2012 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 const char kUsage[] = | 188 const char kUsage[] = |
189 "Usage: pdb_dump [options] <PDB file>...\n" | 189 "Usage: pdb_dump [options] <PDB file>...\n" |
190 " Dumps information from streams in a supplied PDB files, and optionally\n" | 190 " Dumps information from streams in a supplied PDB files, and optionally\n" |
191 " explodes the streams in the PDB files to individual files in an\n" | 191 " explodes the streams in the PDB files to individual files in an\n" |
192 " output directory named '<PDB file>.streams'.\n" | 192 " output directory named '<PDB file>.streams'.\n" |
193 "\n" | 193 "\n" |
194 " Optional Options:\n" | 194 " Optional Options:\n" |
195 " --dump-symbol-records if provided the symbol record stream will be\n" | 195 " --dump-symbol-records if provided the symbol record stream will be\n" |
196 " dumped. This is a big stream so it could take a lot of time to\n" | 196 " dumped. This is a big stream so it could take a lot of time to\n" |
197 " process.\n" | 197 " process.\n" |
| 198 " --dump-fpo if provided, the FPO stream will be dumped\n" |
198 " --dump-type-info if provided the type info stream will be dumped.\n" | 199 " --dump-type-info if provided the type info stream will be dumped.\n" |
199 " This is a big stream so it could take a lot of time to process.\n" | 200 " This is a big stream so it could take a lot of time to process.\n" |
200 " --dump-modules if provided the module streams will be dumped. Note\n" | 201 " --dump-modules if provided the module streams will be dumped. Note\n" |
201 " that this can take a long time as there may be many of these\n" | 202 " that this can take a long time as there may be many of these\n" |
202 " streams.\n" | 203 " streams.\n" |
203 " --explode-streams if provided, each PDB file's streams will be\n" | 204 " --explode-streams if provided, each PDB file's streams will be\n" |
204 " exploded into a directory named '<PDB file>.streams'\n"; | 205 " exploded into a directory named '<PDB file>.streams'\n"; |
205 | 206 |
206 } // namespace | 207 } // namespace |
207 | 208 |
208 PdbDumpApp::PdbDumpApp() | 209 PdbDumpApp::PdbDumpApp() |
209 : application::AppImplBase("PDB Dumper"), | 210 : application::AppImplBase("PDB Dumper"), |
210 explode_streams_(false), | 211 explode_streams_(false), |
211 dump_symbol_record_(false), | 212 dump_symbol_record_(false), |
| 213 dump_fpo_(false), |
212 dump_type_info_(false), | 214 dump_type_info_(false), |
213 dump_modules_(false) { | 215 dump_modules_(false) { |
214 } | 216 } |
215 | 217 |
216 bool PdbDumpApp::ParseCommandLine(const base::CommandLine* command_line) { | 218 bool PdbDumpApp::ParseCommandLine(const base::CommandLine* command_line) { |
217 DCHECK(command_line != NULL); | 219 DCHECK(command_line != NULL); |
218 | 220 |
219 explode_streams_ = command_line->HasSwitch("explode-streams"); | 221 explode_streams_ = command_line->HasSwitch("explode-streams"); |
220 dump_symbol_record_ = command_line->HasSwitch("dump-symbol-records"); | 222 dump_symbol_record_ = command_line->HasSwitch("dump-symbol-records"); |
| 223 dump_fpo_ = command_line->HasSwitch("dump-fpo"); |
221 dump_type_info_ = command_line->HasSwitch("dump-type-info"); | 224 dump_type_info_ = command_line->HasSwitch("dump-type-info"); |
222 dump_modules_ = command_line->HasSwitch("dump-modules"); | 225 dump_modules_ = command_line->HasSwitch("dump-modules"); |
223 | 226 |
224 base::CommandLine::StringVector args = command_line->GetArgs(); | 227 base::CommandLine::StringVector args = command_line->GetArgs(); |
225 if (args.empty()) | 228 if (args.empty()) |
226 return Usage("You must provide at least one input file."); | 229 return Usage("You must provide at least one input file."); |
227 | 230 |
228 for (size_t i = 0; i < args.size(); ++i) { | 231 for (size_t i = 0; i < args.size(); ++i) { |
229 pdb_files_.push_back(base::FilePath(args[i])); | 232 pdb_files_.push_back(base::FilePath(args[i])); |
230 } | 233 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 // Read the dbi stream. | 275 // Read the dbi stream. |
273 DbiStream dbi_stream; | 276 DbiStream dbi_stream; |
274 stream = pdb_file.GetStream(pdb::kDbiStream).get(); | 277 stream = pdb_file.GetStream(pdb::kDbiStream).get(); |
275 if (stream != NULL && dbi_stream.Read(stream)) { | 278 if (stream != NULL && dbi_stream.Read(stream)) { |
276 DumpDbiStream(dbi_stream); | 279 DumpDbiStream(dbi_stream); |
277 } else { | 280 } else { |
278 LOG(ERROR) << "No Dbi stream."; | 281 LOG(ERROR) << "No Dbi stream."; |
279 return 1; | 282 return 1; |
280 } | 283 } |
281 | 284 |
| 285 if (dump_fpo_) { |
| 286 scoped_refptr<pdb::PdbStream> fpo_stream = |
| 287 pdb_file.GetStream(dbi_stream.dbg_header().fpo); |
| 288 |
| 289 scoped_refptr<pdb::PdbStream> new_fpo_stream = |
| 290 pdb_file.GetStream(dbi_stream.dbg_header().new_fpo); |
| 291 |
| 292 DumpFpoStream(fpo_stream.get(), new_fpo_stream.get()); |
| 293 } |
282 // Read the type info stream. | 294 // Read the type info stream. |
283 stream = pdb_file.GetStream(pdb::kTpiStream).get(); | 295 stream = pdb_file.GetStream(pdb::kTpiStream).get(); |
284 TypeInfoEnumerator type_info_enum; | 296 TypeInfoEnumerator type_info_enum; |
285 | 297 |
286 if (type_info_enum.Init(stream)) { | 298 if (type_info_enum.Init(stream)) { |
287 if (dump_type_info_) | 299 if (dump_type_info_) |
288 DumpTypeInfoStream(out(), type_info_enum); | 300 DumpTypeInfoStream(out(), type_info_enum); |
289 } else { | 301 } else { |
290 LOG(ERROR) << "No type info stream."; | 302 LOG(ERROR) << "No type info stream."; |
291 return 1; | 303 return 1; |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 ::fprintf(out(), "\tp_data: %d\n", dbi_stream.dbg_header().p_data); | 438 ::fprintf(out(), "\tp_data: %d\n", dbi_stream.dbg_header().p_data); |
427 ::fprintf(out(), "\tnew_fpo: %d\n", dbi_stream.dbg_header().new_fpo); | 439 ::fprintf(out(), "\tnew_fpo: %d\n", dbi_stream.dbg_header().new_fpo); |
428 ::fprintf(out(), "\tsection_header_origin: %d\n", | 440 ::fprintf(out(), "\tsection_header_origin: %d\n", |
429 dbi_stream.dbg_header().section_header_origin); | 441 dbi_stream.dbg_header().section_header_origin); |
430 } | 442 } |
431 | 443 |
432 void PdbDumpApp::DumpDbiStream(const DbiStream& dbi_stream) { | 444 void PdbDumpApp::DumpDbiStream(const DbiStream& dbi_stream) { |
433 DumpDbiHeaders(dbi_stream); | 445 DumpDbiHeaders(dbi_stream); |
434 } | 446 } |
435 | 447 |
| 448 void PdbDumpApp::DumpFpoStream(PdbStream* fpo_stream, |
| 449 PdbStream* new_fpo_stream) { |
| 450 if (!fpo_stream) { |
| 451 ::fprintf(out(), "No FPO stream!\n"); |
| 452 } else { |
| 453 ::fprintf(out(), "FPO Records:\n"); |
| 454 FPO_DATA fpo_data = {}; |
| 455 while (fpo_stream->Read(&fpo_data, 1)) { |
| 456 // A bit of indentation makes it easier to separate the records visually. |
| 457 ::fprintf(out(), " ulOffStart: 0x%08X\n", fpo_data.ulOffStart); |
| 458 ::fprintf(out(), " cbProcSize: 0x%08X\n", fpo_data.cbProcSize); |
| 459 ::fprintf(out(), " cdwLocals: 0x%08X\n", fpo_data.cdwLocals); |
| 460 ::fprintf(out(), " cdwParams: 0x%04X\n", fpo_data.cdwParams); |
| 461 ::fprintf(out(), " cbProlog: %d\n", fpo_data.cbProlog); |
| 462 ::fprintf(out(), " cbRegs: %d\n", fpo_data.cbRegs); |
| 463 ::fprintf(out(), " fHasSEH: %d\n", fpo_data.fHasSEH); |
| 464 ::fprintf(out(), " fUseBP: %d\n", fpo_data.fUseBP); |
| 465 ::fprintf(out(), " reserved: %d\n", fpo_data.reserved); |
| 466 ::fprintf(out(), " cbFrame: %d\n", fpo_data.cbFrame); |
| 467 } |
| 468 } |
| 469 |
| 470 if (!new_fpo_stream) { |
| 471 ::fprintf(out(), "No new FPO stream!\n"); |
| 472 } else { |
| 473 ::fprintf(out(), "Don't know how to dump new FPO stream yet.\n"); |
| 474 } |
| 475 } |
| 476 |
436 } // namespace pdb | 477 } // namespace pdb |
OLD | NEW |