Revert 221932 "Refactor KeySystems code to call a function to po..."
[chromium-blink-merge.git] / courgette / disassembler.cc
blob798a367369a870386ddd8ea6f9365fa9be1c7ff1
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.
5 #include "courgette/disassembler.h"
7 #include <algorithm>
8 #include <string>
9 #include <vector>
11 #include "base/basictypes.h"
12 #include "base/logging.h"
14 #include "courgette/assembly_program.h"
15 #include "courgette/courgette.h"
16 #include "courgette/disassembler_elf_32_arm.h"
17 #include "courgette/disassembler_elf_32_x86.h"
18 #include "courgette/disassembler_win32_x86.h"
19 #include "courgette/encoded_program.h"
21 // COURGETTE_HISTOGRAM_TARGETS prints out a histogram of how frequently
22 // different target addresses are referenced. Purely for debugging.
23 #define COURGETTE_HISTOGRAM_TARGETS 0
25 namespace courgette {
27 ////////////////////////////////////////////////////////////////////////////////
29 Disassembler* DetectDisassembler(const void* buffer, size_t length) {
30 Disassembler* disassembler = NULL;
32 disassembler = new DisassemblerWin32X86(buffer, length);
33 if (disassembler->ParseHeader())
34 return disassembler;
35 else
36 delete disassembler;
38 disassembler = new DisassemblerElf32X86(buffer, length);
39 if (disassembler->ParseHeader())
40 return disassembler;
41 else
42 delete disassembler;
44 disassembler = new DisassemblerElf32ARM(buffer, length);
45 if (disassembler->ParseHeader())
46 return disassembler;
47 else
48 delete disassembler;
50 return NULL;
53 Status DetectExecutableType(const void* buffer, size_t length,
54 ExecutableType* type,
55 size_t* detected_length) {
57 Disassembler* disassembler = DetectDisassembler(buffer, length);
59 if (disassembler) {
60 *type = disassembler->kind();
61 *detected_length = disassembler->length();
62 delete disassembler;
63 return C_OK;
66 // We failed to detect anything
67 *type = EXE_UNKNOWN;
68 *detected_length = 0;
69 return C_INPUT_NOT_RECOGNIZED;
72 Status ParseDetectedExecutable(const void* buffer, size_t length,
73 AssemblyProgram** output) {
74 *output = NULL;
76 Disassembler* disassembler = DetectDisassembler(buffer, length);
78 if (!disassembler) {
79 return C_INPUT_NOT_RECOGNIZED;
82 AssemblyProgram* program = new AssemblyProgram(disassembler->kind());
84 if (!disassembler->Disassemble(program)) {
85 delete program;
86 delete disassembler;
87 return C_DISASSEMBLY_FAILED;
90 delete disassembler;
91 *output = program;
92 return C_OK;
95 void DeleteAssemblyProgram(AssemblyProgram* program) {
96 delete program;
99 Disassembler::Disassembler(const void* start, size_t length)
100 : failure_reason_("uninitialized") {
102 start_ = reinterpret_cast<const uint8*>(start);
103 length_ = length;
104 end_ = start_ + length_;
107 Disassembler::~Disassembler() {};
109 const uint8* Disassembler::OffsetToPointer(size_t offset) const {
110 assert(start_ + offset <= end_);
111 return start_ + offset;
114 bool Disassembler::Good() {
115 failure_reason_ = NULL;
116 return true;
119 bool Disassembler::Bad(const char* reason) {
120 failure_reason_ = reason;
121 return false;
124 void Disassembler::ReduceLength(size_t reduced_length) {
125 if (reduced_length < length_)
126 length_ = reduced_length;
129 } // namespace courgette