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"
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
27 ////////////////////////////////////////////////////////////////////////////////
29 Disassembler
* DetectDisassembler(const void* buffer
, size_t length
) {
30 Disassembler
* disassembler
= NULL
;
32 disassembler
= new DisassemblerWin32X86(buffer
, length
);
33 if (disassembler
->ParseHeader())
38 disassembler
= new DisassemblerElf32X86(buffer
, length
);
39 if (disassembler
->ParseHeader())
44 disassembler
= new DisassemblerElf32ARM(buffer
, length
);
45 if (disassembler
->ParseHeader())
53 Status
DetectExecutableType(const void* buffer
, size_t length
,
55 size_t* detected_length
) {
57 Disassembler
* disassembler
= DetectDisassembler(buffer
, length
);
60 *type
= disassembler
->kind();
61 *detected_length
= disassembler
->length();
66 // We failed to detect anything
69 return C_INPUT_NOT_RECOGNIZED
;
72 Status
ParseDetectedExecutable(const void* buffer
, size_t length
,
73 AssemblyProgram
** output
) {
76 Disassembler
* disassembler
= DetectDisassembler(buffer
, length
);
79 return C_INPUT_NOT_RECOGNIZED
;
82 AssemblyProgram
* program
= new AssemblyProgram(disassembler
->kind());
84 if (!disassembler
->Disassemble(program
)) {
87 return C_DISASSEMBLY_FAILED
;
95 void DeleteAssemblyProgram(AssemblyProgram
* program
) {
99 Disassembler::Disassembler(const void* start
, size_t length
)
100 : failure_reason_("uninitialized") {
102 start_
= reinterpret_cast<const uint8
*>(start
);
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
;
119 bool Disassembler::Bad(const char* reason
) {
120 failure_reason_
= reason
;
124 void Disassembler::ReduceLength(size_t reduced_length
) {
125 if (reduced_length
< length_
)
126 length_
= reduced_length
;
129 } // namespace courgette