Telemetry: Add a reload action and a reload benchmark.
[chromium-blink-merge.git] / courgette / disassembler.cc
blob103bbe014b82e5525b89c17ab8bb4fd833883b1c
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_x86.h"
17 #include "courgette/disassembler_win32_x86.h"
18 #include "courgette/encoded_program.h"
20 // COURGETTE_HISTOGRAM_TARGETS prints out a histogram of how frequently
21 // different target addresses are referenced. Purely for debugging.
22 #define COURGETTE_HISTOGRAM_TARGETS 0
24 namespace courgette {
26 ////////////////////////////////////////////////////////////////////////////////
28 Disassembler* DetectDisassembler(const void* buffer, size_t length) {
29 Disassembler* disassembler = NULL;
31 disassembler = new DisassemblerWin32X86(buffer, length);
32 if (disassembler->ParseHeader())
33 return disassembler;
34 else
35 delete disassembler;
37 disassembler = new DisassemblerElf32X86(buffer, length);
38 if (disassembler->ParseHeader())
39 return disassembler;
40 else
41 delete disassembler;
43 return NULL;
46 Status DetectExecutableType(const void* buffer, size_t length,
47 ExecutableType* type,
48 size_t* detected_length) {
50 Disassembler* disassembler = DetectDisassembler(buffer, length);
52 if (disassembler) {
53 *type = disassembler->kind();
54 *detected_length = disassembler->length();
55 delete disassembler;
56 return C_OK;
59 // We failed to detect anything
60 *type = EXE_UNKNOWN;
61 *detected_length = 0;
62 return C_INPUT_NOT_RECOGNIZED;
65 Status ParseDetectedExecutable(const void* buffer, size_t length,
66 AssemblyProgram** output) {
67 *output = NULL;
69 Disassembler* disassembler = DetectDisassembler(buffer, length);
71 if (!disassembler) {
72 return C_INPUT_NOT_RECOGNIZED;
75 AssemblyProgram* program = new AssemblyProgram();
77 if (!disassembler->Disassemble(program)) {
78 delete program;
79 delete disassembler;
80 return C_DISASSEMBLY_FAILED;
83 delete disassembler;
84 *output = program;
85 return C_OK;
88 void DeleteAssemblyProgram(AssemblyProgram* program) {
89 delete program;
92 Disassembler::Disassembler(const void* start, size_t length)
93 : failure_reason_("uninitialized") {
95 start_ = reinterpret_cast<const uint8*>(start);
96 length_ = length;
97 end_ = start_ + length_;
100 Disassembler::~Disassembler() {};
102 const uint8* Disassembler::OffsetToPointer(size_t offset) const {
103 assert(start_ + offset <= end_);
104 return start_ + offset;
107 bool Disassembler::Good() {
108 failure_reason_ = NULL;
109 return true;
112 bool Disassembler::Bad(const char* reason) {
113 failure_reason_ = reason;
114 return false;
117 void Disassembler::ReduceLength(size_t reduced_length) {
118 if (reduced_length < length_)
119 length_ = reduced_length;
122 } // namespace courgette