123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- // Copyright (c) 2011 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "courgette/disassembler.h"
- #include "base/check_op.h"
- #include "base/memory/ptr_util.h"
- #include "courgette/assembly_program.h"
- #include "courgette/encoded_program.h"
- namespace courgette {
- Disassembler::RvaVisitor_Abs32::RvaVisitor_Abs32(
- const std::vector<RVA>& rva_locations,
- const AddressTranslator& translator)
- : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
- }
- RVA Disassembler::RvaVisitor_Abs32::Get() const {
- // For Abs32 targets, get target RVA from architecture-dependent functions.
- return translator_.PointerToTargetRVA(translator_.RVAToPointer(*it_));
- }
- Disassembler::RvaVisitor_Rel32::RvaVisitor_Rel32(
- const std::vector<RVA>& rva_locations,
- const AddressTranslator& translator)
- : VectorRvaVisitor<RVA>(rva_locations), translator_(translator) {
- }
- RVA Disassembler::RvaVisitor_Rel32::Get() const {
- // For Rel32 targets, only handle 32-bit offsets.
- return *it_ + 4 + Read32LittleEndian(translator_.RVAToPointer(*it_));
- }
- Disassembler::Disassembler(const uint8_t* start, size_t length)
- : failure_reason_("uninitialized") {
- start_ = start;
- length_ = length;
- end_ = start_ + length_;
- }
- Disassembler::~Disassembler() = default;
- const uint8_t* Disassembler::FileOffsetToPointer(FileOffset file_offset) const {
- CHECK_LE(file_offset, static_cast<FileOffset>(end_ - start_));
- return start_ + file_offset;
- }
- const uint8_t* Disassembler::RVAToPointer(RVA rva) const {
- FileOffset file_offset = RVAToFileOffset(rva);
- if (file_offset == kNoFileOffset)
- return nullptr;
- return FileOffsetToPointer(file_offset);
- }
- std::unique_ptr<AssemblyProgram> Disassembler::CreateProgram(bool annotate) {
- if (!ok() || !ExtractAbs32Locations() || !ExtractRel32Locations())
- return nullptr;
- std::unique_ptr<AssemblyProgram> program =
- std::make_unique<AssemblyProgram>(kind(), image_base());
- PrecomputeLabels(program.get());
- RemoveUnusedRel32Locations(program.get());
- program->DefaultAssignIndexes();
- if (annotate) {
- if (!program->AnnotateLabels(GetInstructionGenerator(program.get())))
- return nullptr;
- }
- return program;
- }
- Status Disassembler::DisassembleAndEncode(AssemblyProgram* program,
- EncodedProgram* encoded) {
- program->PrepareEncodedProgram(encoded);
- return encoded->GenerateInstructions(program->kind(),
- GetInstructionGenerator(program))
- ? C_OK
- : C_DISASSEMBLY_FAILED;
- }
- bool Disassembler::Good() {
- failure_reason_ = nullptr;
- return true;
- }
- bool Disassembler::Bad(const char* reason) {
- failure_reason_ = reason;
- return false;
- }
- void Disassembler::PrecomputeLabels(AssemblyProgram* program) {
- std::unique_ptr<RvaVisitor> abs32_visitor(CreateAbs32TargetRvaVisitor());
- std::unique_ptr<RvaVisitor> rel32_visitor(CreateRel32TargetRvaVisitor());
- program->PrecomputeLabels(abs32_visitor.get(), rel32_visitor.get());
- }
- void Disassembler::ReduceLength(size_t reduced_length) {
- CHECK_LE(reduced_length, length_);
- length_ = reduced_length;
- end_ = start_ + length_;
- }
- } // namespace courgette
|