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 |