blob: baa3b1f8c780338f4750d63e8cbda29fb6e66d8b [file] [log] [blame]
// 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 <memory>
#include "base/logging.h"
#include "courgette/assembly_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 void* start, size_t length)
: failure_reason_("uninitialized") {
start_ = reinterpret_cast<const uint8_t*>(start);
length_ = length;
end_ = start_ + length_;
};
Disassembler::~Disassembler() {};
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);
}
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