| 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 |