| OLD | NEW |
| 1 // -*- mode: c++ -*- | 1 // -*- mode: c++ -*- |
| 2 | 2 |
| 3 // Copyright (c) 2011, Google Inc. | 3 // Copyright (c) 2011, Google Inc. |
| 4 // All rights reserved. | 4 // All rights reserved. |
| 5 // | 5 // |
| 6 // Redistribution and use in source and binary forms, with or without | 6 // Redistribution and use in source and binary forms, with or without |
| 7 // modification, are permitted provided that the following conditions are | 7 // modification, are permitted provided that the following conditions are |
| 8 // met: | 8 // met: |
| 9 // | 9 // |
| 10 // * Redistributions of source code must retain the above copyright | 10 // * Redistributions of source code must retain the above copyright |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 Module *module, vector<Module::Line> *lines) { | 321 Module *module, vector<Module::Line> *lines) { |
| 322 DwarfLineToModule handler(module, compilation_dir_, lines); | 322 DwarfLineToModule handler(module, compilation_dir_, lines); |
| 323 dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); | 323 dwarf2reader::LineInfo parser(program, length, byte_reader_, &handler); |
| 324 parser.Start(); | 324 parser.Start(); |
| 325 } | 325 } |
| 326 private: | 326 private: |
| 327 string compilation_dir_; | 327 string compilation_dir_; |
| 328 dwarf2reader::ByteReader *byte_reader_; // WEAK | 328 dwarf2reader::ByteReader *byte_reader_; // WEAK |
| 329 }; | 329 }; |
| 330 | 330 |
| 331 bool DumpSymbols::CreateEmptyModule(scoped_ptr<Module>& module) { |
| 332 // Select an object file, if SetArchitecture hasn't been called to set one |
| 333 // explicitly. |
| 334 if (!selected_object_file_) { |
| 335 // If there's only one architecture, that's the one. |
| 336 if (object_files_.size() == 1) |
| 337 selected_object_file_ = &object_files_[0]; |
| 338 else { |
| 339 // Look for an object file whose architecture matches our own. |
| 340 const NXArchInfo *local_arch = NXGetLocalArchInfo(); |
| 341 if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) { |
| 342 fprintf(stderr, "%s: object file contains more than one" |
| 343 " architecture, none of which match the current" |
| 344 " architecture; specify an architecture explicitly" |
| 345 " with '-a ARCH' to resolve the ambiguity\n", |
| 346 object_filename_.c_str()); |
| 347 return false; |
| 348 } |
| 349 } |
| 350 } |
| 351 |
| 352 assert(selected_object_file_); |
| 353 |
| 354 // Find the name of the selected file's architecture, to appear in |
| 355 // the MODULE record and in error messages. |
| 356 const NXArchInfo *selected_arch_info = |
| 357 google_breakpad::BreakpadGetArchInfoFromCpuType( |
| 358 selected_object_file_->cputype, selected_object_file_->cpusubtype); |
| 359 |
| 360 const char *selected_arch_name = selected_arch_info->name; |
| 361 if (strcmp(selected_arch_name, "i386") == 0) |
| 362 selected_arch_name = "x86"; |
| 363 |
| 364 // Produce a name to use in error messages that includes the |
| 365 // filename, and the architecture, if there is more than one. |
| 366 selected_object_name_ = object_filename_; |
| 367 if (object_files_.size() > 1) { |
| 368 selected_object_name_ += ", architecture "; |
| 369 selected_object_name_ + selected_arch_name; |
| 370 } |
| 371 |
| 372 // Compute a module name, to appear in the MODULE record. |
| 373 string module_name = object_filename_; |
| 374 module_name = basename(&module_name[0]); |
| 375 |
| 376 // Choose an identifier string, to appear in the MODULE record. |
| 377 string identifier = Identifier(); |
| 378 if (identifier.empty()) |
| 379 return false; |
| 380 identifier += "0"; |
| 381 |
| 382 // Create a module to hold the debugging information. |
| 383 module.reset(new Module(module_name, |
| 384 "mac", |
| 385 selected_arch_name, |
| 386 identifier)); |
| 387 return true; |
| 388 } |
| 389 |
| 331 bool DumpSymbols::ReadDwarf(google_breakpad::Module *module, | 390 bool DumpSymbols::ReadDwarf(google_breakpad::Module *module, |
| 332 const mach_o::Reader &macho_reader, | 391 const mach_o::Reader &macho_reader, |
| 333 const mach_o::SectionMap &dwarf_sections, | 392 const mach_o::SectionMap &dwarf_sections, |
| 334 bool handle_inter_cu_refs) const { | 393 bool handle_inter_cu_refs) const { |
| 335 // Build a byte reader of the appropriate endianness. | 394 // Build a byte reader of the appropriate endianness. |
| 336 ByteReader byte_reader(macho_reader.big_endian() | 395 ByteReader byte_reader(macho_reader.big_endian() |
| 337 ? dwarf2reader::ENDIANNESS_BIG | 396 ? dwarf2reader::ENDIANNESS_BIG |
| 338 : dwarf2reader::ENDIANNESS_LITTLE); | 397 : dwarf2reader::ENDIANNESS_LITTLE); |
| 339 | 398 |
| 340 // Construct a context for this file. | 399 // Construct a context for this file. |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 reader_.bits_64() ? 8 : 4, | 587 reader_.bits_64() ? 8 : 4, |
| 529 true, | 588 true, |
| 530 &stabs_to_module); | 589 &stabs_to_module); |
| 531 if (!stabs_reader.Process()) | 590 if (!stabs_reader.Process()) |
| 532 return false; | 591 return false; |
| 533 stabs_to_module.Finalize(); | 592 stabs_to_module.Finalize(); |
| 534 return true; | 593 return true; |
| 535 } | 594 } |
| 536 | 595 |
| 537 bool DumpSymbols::ReadSymbolData(Module** out_module) { | 596 bool DumpSymbols::ReadSymbolData(Module** out_module) { |
| 538 // Select an object file, if SetArchitecture hasn't been called to set one | 597 scoped_ptr<Module> module; |
| 539 // explicitly. | 598 if (!CreateEmptyModule(module)) |
| 540 if (!selected_object_file_) { | |
| 541 // If there's only one architecture, that's the one. | |
| 542 if (object_files_.size() == 1) | |
| 543 selected_object_file_ = &object_files_[0]; | |
| 544 else { | |
| 545 // Look for an object file whose architecture matches our own. | |
| 546 const NXArchInfo *local_arch = NXGetLocalArchInfo(); | |
| 547 if (!SetArchitecture(local_arch->cputype, local_arch->cpusubtype)) { | |
| 548 fprintf(stderr, "%s: object file contains more than one" | |
| 549 " architecture, none of which match the current" | |
| 550 " architecture; specify an architecture explicitly" | |
| 551 " with '-a ARCH' to resolve the ambiguity\n", | |
| 552 object_filename_.c_str()); | |
| 553 return false; | |
| 554 } | |
| 555 } | |
| 556 } | |
| 557 | |
| 558 assert(selected_object_file_); | |
| 559 | |
| 560 // Find the name of the selected file's architecture, to appear in | |
| 561 // the MODULE record and in error messages. | |
| 562 const NXArchInfo *selected_arch_info = | |
| 563 google_breakpad::BreakpadGetArchInfoFromCpuType( | |
| 564 selected_object_file_->cputype, selected_object_file_->cpusubtype); | |
| 565 | |
| 566 const char *selected_arch_name = selected_arch_info->name; | |
| 567 if (strcmp(selected_arch_name, "i386") == 0) | |
| 568 selected_arch_name = "x86"; | |
| 569 | |
| 570 // Produce a name to use in error messages that includes the | |
| 571 // filename, and the architecture, if there is more than one. | |
| 572 selected_object_name_ = object_filename_; | |
| 573 if (object_files_.size() > 1) { | |
| 574 selected_object_name_ += ", architecture "; | |
| 575 selected_object_name_ + selected_arch_name; | |
| 576 } | |
| 577 | |
| 578 // Compute a module name, to appear in the MODULE record. | |
| 579 string module_name = object_filename_; | |
| 580 module_name = basename(&module_name[0]); | |
| 581 | |
| 582 // Choose an identifier string, to appear in the MODULE record. | |
| 583 string identifier = Identifier(); | |
| 584 if (identifier.empty()) | |
| 585 return false; | 599 return false; |
| 586 identifier += "0"; | |
| 587 | |
| 588 // Create a module to hold the debugging information. | |
| 589 scoped_ptr<Module> module(new Module(module_name, | |
| 590 "mac", | |
| 591 selected_arch_name, | |
| 592 identifier)); | |
| 593 | 600 |
| 594 // Parse the selected object file. | 601 // Parse the selected object file. |
| 595 mach_o::Reader::Reporter reporter(selected_object_name_); | 602 mach_o::Reader::Reporter reporter(selected_object_name_); |
| 596 mach_o::Reader reader(&reporter); | 603 mach_o::Reader reader(&reporter); |
| 597 if (!reader.Read(&contents_[0] | 604 if (!reader.Read(&contents_[0] |
| 598 + selected_object_file_->offset, | 605 + selected_object_file_->offset, |
| 599 selected_object_file_->size, | 606 selected_object_file_->size, |
| 600 selected_object_file_->cputype, | 607 selected_object_file_->cputype, |
| 601 selected_object_file_->cpusubtype)) | 608 selected_object_file_->cpusubtype)) |
| 602 return false; | 609 return false; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 617 | 624 |
| 618 if (ReadSymbolData(&module) && module) { | 625 if (ReadSymbolData(&module) && module) { |
| 619 bool res = module->Write(stream, symbol_data_); | 626 bool res = module->Write(stream, symbol_data_); |
| 620 delete module; | 627 delete module; |
| 621 return res; | 628 return res; |
| 622 } | 629 } |
| 623 | 630 |
| 624 return false; | 631 return false; |
| 625 } | 632 } |
| 626 | 633 |
| 634 // Read the selected object file's debugging information, and write out the |
| 635 // header only to |stream|. Return true on success; if an error occurs, report |
| 636 // it and return false. |
| 637 bool DumpSymbols::WriteSymbolFileHeader(std::ostream &stream) { |
| 638 scoped_ptr<Module> module; |
| 639 if (!CreateEmptyModule(module)) |
| 640 return false; |
| 641 |
| 642 return module->Write(stream, symbol_data_); |
| 643 } |
| 644 |
| 627 } // namespace google_breakpad | 645 } // namespace google_breakpad |
| OLD | NEW |