disassembler.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. // Copyright (c) 2011 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. #include "courgette/disassembler.h"
  5. #include "base/check_op.h"
  6. #include "base/memory/ptr_util.h"
  7. #include "courgette/assembly_program.h"
  8. #include "courgette/encoded_program.h"
  9. namespace courgette {
  10. Disassembler::RvaVisitor_Abs32::RvaVisitor_Abs32(
  11. const std::vector<RVA>& rva_locations,
  12. const AddressTranslator& translator)
  13. : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
  14. }
  15. RVA Disassembler::RvaVisitor_Abs32::Get() const {
  16. // For Abs32 targets, get target RVA from architecture-dependent functions.
  17. return translator_.PointerToTargetRVA(translator_.RVAToPointer(*it_));
  18. }
  19. Disassembler::RvaVisitor_Rel32::RvaVisitor_Rel32(
  20. const std::vector<RVA>& rva_locations,
  21. const AddressTranslator& translator)
  22. : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
  23. }
  24. RVA Disassembler::RvaVisitor_Rel32::Get() const {
  25. // For Rel32 targets, only handle 32-bit offsets.
  26. return *it_ + 4 + Read32LittleEndian(translator_.RVAToPointer(*it_));
  27. }
  28. Disassembler::Disassembler(const uint8_t* start, size_t length)
  29. : failure_reason_("uninitialized") {
  30. start_ = start;
  31. length_ = length;
  32. end_ = start_ + length_;
  33. }
  34. Disassembler::~Disassembler() = default;
  35. const uint8_t* Disassembler::FileOffsetToPointer(FileOffset file_offset) const {
  36. CHECK_LE(file_offset, static_cast<FileOffset>(end_ - start_));
  37. return start_ + file_offset;
  38. }
  39. const uint8_t* Disassembler::RVAToPointer(RVA rva) const {
  40. FileOffset file_offset = RVAToFileOffset(rva);
  41. if (file_offset == kNoFileOffset)
  42. return nullptr;
  43. return FileOffsetToPointer(file_offset);
  44. }
  45. std::unique_ptr<AssemblyProgram> Disassembler::CreateProgram(bool annotate) {
  46. if (!ok() || !ExtractAbs32Locations() || !ExtractRel32Locations())
  47. return nullptr;
  48. std::unique_ptr<AssemblyProgram> program =
  49. std::make_unique<AssemblyProgram>(kind(), image_base());
  50. PrecomputeLabels(program.get());
  51. RemoveUnusedRel32Locations(program.get());
  52. program->DefaultAssignIndexes();
  53. if (annotate) {
  54. if (!program->AnnotateLabels(GetInstructionGenerator(program.get())))
  55. return nullptr;
  56. }
  57. return program;
  58. }
  59. Status Disassembler::DisassembleAndEncode(AssemblyProgram* program,
  60. EncodedProgram* encoded) {
  61. program->PrepareEncodedProgram(encoded);
  62. return encoded->GenerateInstructions(program->kind(),
  63. GetInstructionGenerator(program))
  64. ? C_OK
  65. : C_DISASSEMBLY_FAILED;
  66. }
  67. bool Disassembler::Good() {
  68. failure_reason_ = nullptr;
  69. return true;
  70. }
  71. bool Disassembler::Bad(const char* reason) {
  72. failure_reason_ = reason;
  73. return false;
  74. }
  75. void Disassembler::PrecomputeLabels(AssemblyProgram* program) {
  76. std::unique_ptr<RvaVisitor> abs32_visitor(CreateAbs32TargetRvaVisitor());
  77. std::unique_ptr<RvaVisitor> rel32_visitor(CreateRel32TargetRvaVisitor());
  78. program->PrecomputeLabels(abs32_visitor.get(), rel32_visitor.get());
  79. }
  80. void Disassembler::ReduceLength(size_t reduced_length) {
  81. CHECK_LE(reduced_length, length_);
  82. length_ = reduced_length;
  83. end_ = start_ + length_;
  84. }
  85. } // namespace courgette