util: integrate LLVM-based Disassembler

The LLVM Disassembler infrastructure can be used to analyze many kinds
of ELF Binaries. For every instruction the used and defined registers
is available as well as information about the instruction itself.

Change-Id: I9cc89b6c116ceff7b5143a6f179ae31c4e994d2d
This commit is contained in:
Christian Dietrich
2013-06-06 13:16:23 +02:00
parent 593e703807
commit 40f610b536
22 changed files with 1180 additions and 0 deletions

View File

@ -5,6 +5,7 @@ if("${CMAKE_VERSION}" VERSION_GREATER 2.8.3)
# (makes cmake 2.8.4 and newer) # (makes cmake 2.8.4 and newer)
cmake_policy(SET CMP0017 NEW) cmake_policy(SET CMP0017 NEW)
endif("${CMAKE_VERSION}" VERSION_GREATER 2.8.3) endif("${CMAKE_VERSION}" VERSION_GREATER 2.8.3)
ENABLE_TESTING()
PROJECT(Fail*) PROJECT(Fail*)
@ -19,6 +20,12 @@ SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
## (The autoconf'd Bochs instance is placed in the auto-configured path, ## (The autoconf'd Bochs instance is placed in the auto-configured path,
## as we still just call Bochs' Makefile's make install) ## as we still just call Bochs' Makefile's make install)
# where will executable tests be written ?
IF (EXECUTABLE_OUTPUT_PATH)
SET (CXX_TEST_PATH ${EXECUTABLE_OUTPUT_PATH})
ELSE (EXECUTABLE_OUTPUT_PATH)
SET (CXX_TEST_PATH .)
ENDIF (EXECUTABLE_OUTPUT_PATH)
#### Setup search path for custom cmake scipts #### #### Setup search path for custom cmake scipts ####
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

34
cmake/FindLLVM.cmake Normal file
View File

@ -0,0 +1,34 @@
find_program(LLVMCONFIG NAMES llvm-config llvm-config-3.1)
if( NOT LLVMCONFIG )
message(FATAL_ERROR "llvm-config not found, try installing llvm-dev llvm")
else()
message(STATUS "[Fail*] LLVM Disassembler: Found llvm-config @ ${LLVMCONFIG}")
endif()
# examine LLVM include directory
execute_process( COMMAND ${LLVMCONFIG} --includedir
OUTPUT_VARIABLE LLVM_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE )
include_directories( ${LLVM_INCLUDE_DIRS} )
# Library path
execute_process( COMMAND ${LLVMCONFIG} --libdir
OUTPUT_VARIABLE LLVM_LIBRARY_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE )
link_directories( ${LLVM_LIBRARY_DIRS} )
# necessary CPP flags.
execute_process( COMMAND ${LLVMCONFIG} --cxxflags
OUTPUT_VARIABLE LLVM_CXX_FLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE )
# and additional libs (this is -ldl and -lpthread in llvm 3.1)
execute_process( COMMAND ${LLVMCONFIG} --ldflags
OUTPUT_VARIABLE LLVM_LDFLAGS
OUTPUT_STRIP_TRAILING_WHITESPACE )
## FIXME? Here we add *all* libraries to the link step (although we need only a handful..)
execute_process( COMMAND ${LLVMCONFIG} --libs all
OUTPUT_VARIABLE LLVM_LIBS
OUTPUT_STRIP_TRAILING_WHITESPACE )

View File

@ -10,6 +10,8 @@
#cmakedefine BUILD_X86 #cmakedefine BUILD_X86
#cmakedefine BUILD_ARM #cmakedefine BUILD_ARM
#cmakedefine BUILD_LLVM_DISASSEMBLER
#define ARCH_TOOL_PREFIX "@ARCH_TOOL_PREFIX@" #define ARCH_TOOL_PREFIX "@ARCH_TOOL_PREFIX@"
#endif // __VARIANT_CONFIG_HPP__ #endif // __VARIANT_CONFIG_HPP__

View File

@ -62,3 +62,9 @@ mark_as_advanced(FAIL_OBJDUMP)
add_library(fail-util ${SRCS}) add_library(fail-util ${SRCS})
add_dependencies(fail-util fail-comm) add_dependencies(fail-util fail-comm)
target_link_libraries(fail-util ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LIB_IBERTY} ) target_link_libraries(fail-util ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LIB_IBERTY} )
option(BUILD_LLVM_DISASSEMBLER "Build the llvm based disassembler (exactly llvm 3.1 required)" OFF)
if (BUILD_LLVM_DISASSEMBLER)
add_subdirectory(llvmdisassembler)
endif (BUILD_LLVM_DISASSEMBLER)

View File

@ -0,0 +1,27 @@
set(SRCS
LLVMDisassembler.cpp
LLVMDisassembler.hpp
LLVMtoFailBochs.cpp
LLVMtoFailBochs.hpp
LLVMtoFailGem5.hpp
LLVMtoFailGem5.cpp
LLVMtoFailTranslator.cpp
LLVMtoFailTranslator.hpp
)
include(FindLLVM)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS}" )
add_library(fail-llvmdisassembler ${SRCS})
add_dependencies(fail-llvmdisassembler fail-sal)
target_link_libraries(fail-llvmdisassembler ${LLVM_LIBS} ${LLVM_LDFLAGS} )
### Tests
add_executable(llvmDisTest testing/llvmDisTest.cc)
target_link_libraries(llvmDisTest fail-llvmdisassembler fail-sal)
add_test(NAME llvmDisx86Test COMMAND llvmDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/x86 )
add_test(NAME llvmDisx86_64Test COMMAND llvmDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/x86_64 )
add_test(NAME llvmDisARMM3Test COMMAND llvmDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/armm3 )
add_test(NAME llvmDisARM9Test COMMAND llvmDisTest ${CMAKE_CURRENT_SOURCE_DIR}/testing/arm9 )

View File

@ -0,0 +1,151 @@
#ifndef __puma
#include "LLVMDisassembler.hpp"
using namespace fail;
using namespace llvm;
using namespace llvm::object;
LLVMtoFailTranslator & LLVMDisassembler::getTranslator() {
if ( ltofail == 0 ){
std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl;
switch ( llvm::Triple::ArchType(object->getArch()) ) {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
ltofail = new LLVMtoFailBochs;
break;
case llvm::Triple::arm:
ltofail = new LLVMtoFailGem5;
break;
default:
std::cout << " not supported :(";
exit(1);
}
}
return *ltofail;
}
void LLVMDisassembler::disassemble()
{
error_code ec;
for (section_iterator i = object->begin_sections(),
e = object->end_sections();
i != e; i.increment(ec)) {
if (error(ec)) break;
bool text;
if (error(i->isText(text))) break;
if (!text) continue;
uint64_t SectionAddr;
if (error(i->getAddress(SectionAddr))) break;
uint64_t SectionLength;
if (error(i->getSize(SectionLength))) break;
// Make a list of all the symbols in this section.
std::vector<std::pair<uint64_t, StringRef> > Symbols;
for (symbol_iterator si = object->begin_symbols(),
se = object->end_symbols();
si != se; si.increment(ec)) {
bool contains;
StringRef Name;
if (!error(i->containsSymbol(*si, contains)) && contains) {
uint64_t Address;
if (error(si->getAddress(Address))) break;
Address -= SectionAddr;
if (error(si->getName(Name))) break;
Symbols.push_back(std::make_pair(Address, Name));
}
}
// Sort the symbols by address, just in case they didn't come in that way.
array_pod_sort(Symbols.begin(), Symbols.end());
StringRef name;
if (error(i->getName(name))) break;
// If the section has no symbols just insert a dummy one and disassemble
// the whole section.
if (Symbols.empty())
Symbols.push_back(std::make_pair(0, name));
StringRef Bytes;
if (error(i->getContents(Bytes))) break;
StringRefMemoryObject memoryObject(Bytes);
uint64_t Size;
uint64_t Index;
uint64_t SectSize;
if (error(i->getSize(SectSize))) break;
// Disassemble symbol by symbol.
for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
uint64_t Start = Symbols[si].first;
uint64_t End;
// The end is either the size of the section or the beginning of the next
// symbol.
if (si == se - 1)
End = SectSize;
// Make sure this symbol takes up space.
else if (Symbols[si + 1].first != Start)
End = Symbols[si + 1].first - 1;
else
// This symbol has the same address as the next symbol. Skip it.
continue;
for (Index = Start; Index < End; Index += Size) {
MCInst Inst;
if (disas->getInstruction(Inst, Size, memoryObject, Index,
nulls(), nulls())) {
const MCInstrDesc &desc = this->instr_info->get(Inst.getOpcode());
// Inst.dump();
Instr instr_info;
instr_info.opcode = Inst.getOpcode();
instr_info.length = Size;
instr_info.address = SectionAddr + Index;
unsigned int pos = 0;
for (MCInst::iterator it = Inst.begin(); it != Inst.end(); ++it) {
if (it->isValid() && it->isReg()
&& it->getReg() != 0 /* NOREG */) {
// Distinguish between input and
// output register operands
if (pos < desc.getNumDefs())
instr_info.reg_defs.push_back(it->getReg());
else
instr_info.reg_uses.push_back(it->getReg());
}
pos ++;
}
const uint16_t *ptr = desc.getImplicitUses();
for (unsigned int i = 0; i < desc.getNumImplicitUses(); i++) {
if (ptr[i] == 0) // NOREG
continue;
instr_info.reg_uses.push_back(ptr[i]);
}
ptr = desc.getImplicitDefs();
for (unsigned int i = 0; i < desc.getNumImplicitDefs(); i++) {
if (ptr[i] == 0) // NOREG
continue;
instr_info.reg_defs.push_back(ptr[i]);
}
// Insert the instruction info into the instr map
(*instrs)[instr_info.address] = instr_info;
} else {
if (Size == 0)
Size = 1; // skip illegible bytes
}
}
}
}
}
void LLVMDisassembler::StringRefMemoryObject::anchor() {}
#endif

View File

@ -0,0 +1,141 @@
#ifndef __LLVMDISASSEMBLER_HPP__
#define __LLVMDISASSEMBLER_HPP__
#ifndef __puma
#include <iostream>
#include <vector>
#include <map>
#include <limits.h>
#include "llvm/Object/ObjectFile.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/OwningPtr.h"
#include "LLVMtoFailTranslator.hpp"
#include "LLVMtoFailBochs.hpp"
#include "LLVMtoFailGem5.hpp"
namespace fail {
class LLVMDisassembler {
public:
typedef uint16_t register_t;
typedef unsigned int address_t;
struct Instr {
unsigned int opcode;
unsigned int address;
unsigned char length;
std::vector<register_t> reg_uses;
std::vector<register_t> reg_defs;
};
typedef std::map<address_t, Instr> InstrMap;
private:
const llvm::object::ObjectFile *object;
const llvm::Target *target;
std::string triple;
std::string MCPU;
std::string FeaturesStr;
llvm::OwningPtr<llvm::MCSubtargetInfo> subtargetinfo;
llvm::OwningPtr<const llvm::MCDisassembler> disas;
llvm::OwningPtr<const llvm::MCInstrInfo> instr_info;
llvm::OwningPtr<const llvm::MCRegisterInfo> register_info;
llvm::OwningPtr<InstrMap> instrs;
fail::LLVMtoFailTranslator * ltofail;
static std::string GetTriple(const llvm::object::ObjectFile *Obj) {
llvm::Triple TT("unknown-unknown-unknown");
TT.setArch(llvm::Triple::ArchType(Obj->getArch()));
std::string TripleName = TT.str();
return TripleName;
}
static const llvm::Target *GetTarget(const std::string &TripleName) {
// Get the target specific parser.
std::string Error;
const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TripleName, Error);
if (TheTarget)
return TheTarget;
std::cerr << "error: unable to get target for '" << TripleName
<< std::endl;
return 0;
}
static bool error(llvm::error_code ec) {
if (!ec) return false;
std::cerr << "DIS" << ": error reading file: " << ec.message() << ".\n";
return true;
}
class StringRefMemoryObject : public llvm::MemoryObject {
virtual void anchor();
llvm::StringRef Bytes;
public:
StringRefMemoryObject(llvm::StringRef bytes) : Bytes(bytes) {}
uint64_t getBase() const { return 0; }
uint64_t getExtent() const { return Bytes.size(); }
int readByte(uint64_t Addr, uint8_t *Byte) const {
if (Addr >= getExtent())
return -1;
*Byte = Bytes[Addr];
return 0;
}
};
public:
LLVMDisassembler(const llvm::object::ObjectFile *object) : ltofail(0) {
this->object = object;
this->triple = GetTriple(object);
this->target = GetTarget(triple);
this->subtargetinfo.reset(target->createMCSubtargetInfo(triple, MCPU, FeaturesStr));
this->disas.reset(target->createMCDisassembler(*subtargetinfo));
this->instr_info.reset(target->createMCInstrInfo());
this->register_info.reset(target->createMCRegInfo(triple));
this->instrs.reset(new InstrMap());
}
~LLVMDisassembler() { delete ltofail; };
InstrMap &getInstrMap() { return *instrs; };
const llvm::MCRegisterInfo &getRegisterInfo() { return *register_info;}
fail::LLVMtoFailTranslator & getTranslator() ;
const std::string & GetTriple() const { return triple; };
void disassemble();
};
}
#endif // puma
#endif // __LLVMDISASSEMBLER_HPP__

View File

@ -0,0 +1,50 @@
#include "LLVMtoFailBochs.hpp"
#include "sal/x86/X86Architecture.hpp"
using namespace fail;
LLVMtoFailBochs::LLVMtoFailBochs() {
#ifndef __puma
/* These magic numbers are taken from the llvm compiler (MC), they
do not appear in any header. They hopefully will never
change */
llvm_to_fail_map[1] = reginfo_t(RID_CAX, 8, 8) ; // AH
llvm_to_fail_map[2] = reginfo_t(RID_CAX, 8, 0); // AL
llvm_to_fail_map[3] = reginfo_t(RID_CAX, 16, 0); // AX
llvm_to_fail_map[43] = reginfo_t(RID_CAX, 32, 0); // EAX
llvm_to_fail_map[4] = reginfo_t(RID_CBX, 8, 8); // BH
llvm_to_fail_map[5] = reginfo_t(RID_CBX, 8, 0); // BL
llvm_to_fail_map[8] = reginfo_t(RID_CBX, 16, 0); // BX
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH
llvm_to_fail_map[10] = reginfo_t(RID_CCX, 0xff); // CL
llvm_to_fail_map[28] = reginfo_t(RID_CCX, 16, 0); // CX
llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX
llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH
llvm_to_fail_map[32] = reginfo_t(RID_CDX, 0xff); // DL
llvm_to_fail_map[42] = reginfo_t(RID_CDX, 16, 0); // DX
llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX
llvm_to_fail_map[30] = reginfo_t(RID_CDI, 16, 0); // DI
llvm_to_fail_map[31] = reginfo_t(RID_CDI, 8, 0); // DIL
llvm_to_fail_map[47] = reginfo_t(RID_CDI); // EDI
llvm_to_fail_map[6] = reginfo_t(RID_CBP, 16, 0); // BP
llvm_to_fail_map[7] = reginfo_t(RID_CBP, 8, 0); // BPL
llvm_to_fail_map[44] = reginfo_t(RID_CBP); // EBP
llvm_to_fail_map[49] = reginfo_t(RID_FLAGS); // EFLAGS
llvm_to_fail_map[50] = reginfo_t(RID_PC); // EIP
llvm_to_fail_map[115] = reginfo_t(RID_CSI, 16, 0); // SI
llvm_to_fail_map[53] = reginfo_t(RID_CSI); // ESI
llvm_to_fail_map[54] = reginfo_t(RID_CSP); // ESP
llvm_to_fail_map[117] = reginfo_t(RID_CSP, 16, 0); // SP
llvm_to_fail_map[118] = reginfo_t(RID_CSP, 8, 0); // SPL
#endif
}

View File

@ -0,0 +1,19 @@
#ifndef __LLVMTOFAILBOCHS_HPP_
#define __LLVMTOFAILBOCHS_HPP_
#include "LLVMtoFailTranslator.hpp"
#include <stdlib.h>
#include <iostream>
namespace fail {
class LLVMtoFailBochs : public LLVMtoFailTranslator {
public:
LLVMtoFailBochs();
};
} // end of namespace
#endif

View File

@ -0,0 +1,28 @@
#include "LLVMtoFailGem5.hpp"
#include "sal/arm/ArmArchitecture.hpp"
using namespace fail;
LLVMtoFailGem5::LLVMtoFailGem5() {
#ifndef __puma
/* These magic numbers are taken from the machine descriptions of
LLVM they (hopefully) will not change, since they are not exported
via a header */
llvm_to_fail_map[60] = reginfo_t(RI_R0);
llvm_to_fail_map[61] = reginfo_t(RI_R1);
llvm_to_fail_map[62] = reginfo_t(RI_R2);
llvm_to_fail_map[63] = reginfo_t(RI_R3);
llvm_to_fail_map[64] = reginfo_t(RI_R4);
llvm_to_fail_map[65] = reginfo_t(RI_R5);
llvm_to_fail_map[66] = reginfo_t(RI_R6);
llvm_to_fail_map[67] = reginfo_t(RI_R7);
llvm_to_fail_map[68] = reginfo_t(RI_R8);
llvm_to_fail_map[69] = reginfo_t(RI_R9);
llvm_to_fail_map[70] = reginfo_t(RI_R10);
llvm_to_fail_map[71] = reginfo_t(RI_R11);
llvm_to_fail_map[72] = reginfo_t(RI_R12);
llvm_to_fail_map[105] = reginfo_t(RI_SP);
llvm_to_fail_map[40] = reginfo_t(RI_LR);
llvm_to_fail_map[43] = reginfo_t(RI_IP);
#endif
}

View File

@ -0,0 +1,19 @@
#ifndef __LLVMTOFAILGEM5_HPP_
#define __LLVMTOFAILGEM5_HPP_
#include "LLVMtoFailTranslator.hpp"
#include <stdlib.h>
#include <iostream>
namespace fail {
class LLVMtoFailGem5 : public LLVMtoFailTranslator {
public:
LLVMtoFailGem5();
};
} // end of namespace
#endif

View File

@ -0,0 +1,42 @@
#include "LLVMtoFailTranslator.hpp"
#include "sal/SALInst.hpp"
using namespace fail;
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
#ifndef __puma
ltof_map_t::iterator it = llvm_to_fail_map.find(regid);
if( it != llvm_to_fail_map.end() ) {// found
return (*it).second;
} else { // not found
std::cout << "Fail ID for LLVM Register id " << regid << " not found :(" << std::endl;
//exit(EXIT_FAILURE);
return notfound;
}
#endif
}
regdata_t LLVMtoFailTranslator::getRegisterContent(ConcreteCPU& cpu, const reginfo_t &reginfo){
regdata_t result;
Register* reg = cpu.getRegister(reginfo.id);
result = cpu.getRegisterContent(reg);
result &= reginfo.mask;
result >>= reginfo.offset;
return result;
}
void LLVMtoFailTranslator::setRegisterContent(ConcreteCPU & cpu, const reginfo_t &reginfo, regdata_t value){
Register* reg = cpu.getRegister(reginfo.id);
regdata_t origval = cpu.getRegisterContent(reg); // Get register Value from fail
origval &= ~(reginfo.mask); // clear bits to write
value <<= reginfo.offset; // shift value to write up to position
value &= reginfo.mask; // mask out trailing and leading bits
value |= origval; // set bits to write
cpu.setRegisterContent( reg, value ); // write back register content
}

View File

@ -0,0 +1,67 @@
#ifndef __LLVMTOFAILTRANSLATOR_HPP_
#define __LLVMTOFAILTRANSLATOR_HPP_
#include "sal/SALConfig.hpp"
#include "sal/ConcreteCPU.hpp"
#include <map>
namespace fail {
/**
* Translates LLVM disassembler ids
* to Fail* SAL representations.
*/
class LLVMtoFailTranslator {
public:
struct reginfo_t {
int id;
regwidth_t width;
regdata_t mask;
byte_t offset;
int toDataAddress() const {
// .. 5 4 | 7 6 5 4 | 3 2 1 0
// <reg> | <width> | <offset>
return (id << 8) | ((width/8) << 4) | (offset / 8);
}
static reginfo_t fromDataAddress(int addr) {
int id = addr >> 8;
regwidth_t width = ((addr >> 4) & 0xf) * 8;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, width, offset);
}
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
};
protected:
LLVMtoFailTranslator(){};
#ifndef __puma
typedef std::map<unsigned int, struct reginfo_t> ltof_map_t;
ltof_map_t llvm_to_fail_map;
#endif
public:
const reginfo_t & getFailRegisterID(unsigned int regid);
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
void setRegisterContent(ConcreteCPU & cpu, const reginfo_t &reg, regdata_t value);
regdata_t getRegisterContent(ConcreteCPU & cpu, unsigned int llvmid) {
return getRegisterContent(cpu, getFailRegisterID(llvmid));
}
void setRegisterContent(ConcreteCPU & cpu, unsigned int llvmid, regdata_t value) {
setRegisterContent(cpu, getFailRegisterID(llvmid), value);
}
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
private:
reginfo_t notfound;
};
} // end of namespace
#endif

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,281 @@
Triple: arm-unknown-unknown
Number of Registers: 278
0 - NOREG
1 - APSR
2 - CPSR
3 - D0
4 - D1
5 - D2
6 - D3
7 - D4
8 - D5
9 - D6
10 - D7
11 - D8
12 - D9
13 - D10
14 - D11
15 - D12
16 - D13
17 - D14
18 - D15
19 - D16
20 - D17
21 - D18
22 - D19
23 - D20
24 - D21
25 - D22
26 - D23
27 - D24
28 - D25
29 - D26
30 - D27
31 - D28
32 - D29
33 - D30
34 - D31
35 - FPEXC
36 - FPSCR
37 - FPSCR_NZCV
38 - FPSID
39 - ITSTATE
40 - LR
41 - MVFR0
42 - MVFR1
43 - PC
44 - Q0
45 - Q1
46 - Q2
47 - Q3
48 - Q4
49 - Q5
50 - Q6
51 - Q7
52 - Q8
53 - Q9
54 - Q10
55 - Q11
56 - Q12
57 - Q13
58 - Q14
59 - Q15
60 - R0
61 - R1
62 - R2
63 - R3
64 - R4
65 - R5
66 - R6
67 - R7
68 - R8
69 - R9
70 - R10
71 - R11
72 - R12
73 - S0
74 - S1
75 - S2
76 - S3
77 - S4
78 - S5
79 - S6
80 - S7
81 - S8
82 - S9
83 - S10
84 - S11
85 - S12
86 - S13
87 - S14
88 - S15
89 - S16
90 - S17
91 - S18
92 - S19
93 - S20
94 - S21
95 - S22
96 - S23
97 - S24
98 - S25
99 - S26
100 - S27
101 - S28
102 - S29
103 - S30
104 - S31
105 - SP
106 - SPSR
107 - D0_D2
108 - D1_D3
109 - D2_D4
110 - D3_D5
111 - D4_D6
112 - D5_D7
113 - D6_D8
114 - D7_D9
115 - D8_D10
116 - D9_D11
117 - D10_D12
118 - D11_D13
119 - D12_D14
120 - D13_D15
121 - D14_D16
122 - D15_D17
123 - D16_D18
124 - D17_D19
125 - D18_D20
126 - D19_D21
127 - D20_D22
128 - D21_D23
129 - D22_D24
130 - D23_D25
131 - D24_D26
132 - D25_D27
133 - D26_D28
134 - D27_D29
135 - D28_D30
136 - D29_D31
137 - Q0_Q1
138 - Q1_Q2
139 - Q2_Q3
140 - Q3_Q4
141 - Q4_Q5
142 - Q5_Q6
143 - Q6_Q7
144 - Q7_Q8
145 - Q8_Q9
146 - Q9_Q10
147 - Q10_Q11
148 - Q11_Q12
149 - Q12_Q13
150 - Q13_Q14
151 - Q14_Q15
152 - Q0_Q1_Q2_Q3
153 - Q1_Q2_Q3_Q4
154 - Q2_Q3_Q4_Q5
155 - Q3_Q4_Q5_Q6
156 - Q4_Q5_Q6_Q7
157 - Q5_Q6_Q7_Q8
158 - Q6_Q7_Q8_Q9
159 - Q7_Q8_Q9_Q10
160 - Q8_Q9_Q10_Q11
161 - Q9_Q10_Q11_Q12
162 - Q10_Q11_Q12_Q13
163 - Q11_Q12_Q13_Q14
164 - Q12_Q13_Q14_Q15
165 - D0_D1_D2
166 - D1_D2_D3
167 - D2_D3_D4
168 - D3_D4_D5
169 - D4_D5_D6
170 - D5_D6_D7
171 - D6_D7_D8
172 - D7_D8_D9
173 - D8_D9_D10
174 - D9_D10_D11
175 - D10_D11_D12
176 - D11_D12_D13
177 - D12_D13_D14
178 - D13_D14_D15
179 - D14_D15_D16
180 - D15_D16_D17
181 - D16_D17_D18
182 - D17_D18_D19
183 - D18_D19_D20
184 - D19_D20_D21
185 - D20_D21_D22
186 - D21_D22_D23
187 - D22_D23_D24
188 - D23_D24_D25
189 - D24_D25_D26
190 - D25_D26_D27
191 - D26_D27_D28
192 - D27_D28_D29
193 - D28_D29_D30
194 - D29_D30_D31
195 - D0_D2_D4
196 - D1_D3_D5
197 - D2_D4_D6
198 - D3_D5_D7
199 - D4_D6_D8
200 - D5_D7_D9
201 - D6_D8_D10
202 - D7_D9_D11
203 - D8_D10_D12
204 - D9_D11_D13
205 - D10_D12_D14
206 - D11_D13_D15
207 - D12_D14_D16
208 - D13_D15_D17
209 - D14_D16_D18
210 - D15_D17_D19
211 - D16_D18_D20
212 - D17_D19_D21
213 - D18_D20_D22
214 - D19_D21_D23
215 - D20_D22_D24
216 - D21_D23_D25
217 - D22_D24_D26
218 - D23_D25_D27
219 - D24_D26_D28
220 - D25_D27_D29
221 - D26_D28_D30
222 - D27_D29_D31
223 - D0_D2_D4_D6
224 - D1_D3_D5_D7
225 - D2_D4_D6_D8
226 - D3_D5_D7_D9
227 - D4_D6_D8_D10
228 - D5_D7_D9_D11
229 - D6_D8_D10_D12
230 - D7_D9_D11_D13
231 - D8_D10_D12_D14
232 - D9_D11_D13_D15
233 - D10_D12_D14_D16
234 - D11_D13_D15_D17
235 - D12_D14_D16_D18
236 - D13_D15_D17_D19
237 - D14_D16_D18_D20
238 - D15_D17_D19_D21
239 - D16_D18_D20_D22
240 - D17_D19_D21_D23
241 - D18_D20_D22_D24
242 - D19_D21_D23_D25
243 - D20_D22_D24_D26
244 - D21_D23_D25_D27
245 - D22_D24_D26_D28
246 - D23_D25_D27_D29
247 - D24_D26_D28_D30
248 - D25_D27_D29_D31
249 - D1_D2
250 - D3_D4
251 - D5_D6
252 - D7_D8
253 - D9_D10
254 - D11_D12
255 - D13_D14
256 - D15_D16
257 - D17_D18
258 - D19_D20
259 - D21_D22
260 - D23_D24
261 - D25_D26
262 - D27_D28
263 - D29_D30
264 - D1_D2_D3_D4
265 - D3_D4_D5_D6
266 - D5_D6_D7_D8
267 - D7_D8_D9_D10
268 - D9_D10_D11_D12
269 - D11_D12_D13_D14
270 - D13_D14_D15_D16
271 - D15_D16_D17_D18
272 - D17_D18_D19_D20
273 - D19_D20_D21_D22
274 - D21_D22_D23_D24
275 - D23_D24_D25_D26
276 - D25_D26_D27_D28
277 - D27_D28_D29_D30

View File

@ -0,0 +1,71 @@
#include <assert.h>
class random_generator_t
{
private:
unsigned int a; // (sqrt(5)-1)/2 = 0.61803398875
unsigned int b;
unsigned int last_val;
unsigned int sd;
public:
void forth() {
last_val = a*last_val + b;
}
random_generator_t(unsigned int seed = 1)
: a(2654435769), b(seed), last_val(1), sd(seed){
forth();
}
unsigned int item() const {
return last_val;
}
void reset() {
last_val = 1;
b = sd;
forth();
}
};
void sort(int len, int arr[] )
{
int tmp;
int again;
int i;
for(again=1; again; )
for( again=0, i=0; i < (len-1); ++i){
assert(0<=i && i+1 <len);
if( arr[i] > arr[i+1] ){
tmp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = tmp;
again = 1;
}
}
}
int main()
{
const unsigned int arr_size = 10000; //50000;
int arr[arr_size];
int i;
random_generator_t rand;
for(i=0; i!=arr_size; ++i){
arr[i] = rand.item();
rand.forth();
}
sort(arr_size, arr);
}

View File

@ -0,0 +1,4 @@
g++ -m32 bubble.cc -o x86
g++ -m64 bubble.cc -o x86_64
arm-none-eabi-g++ -mcpu=cortex-m3 bubble.cc -o armm3
arm-none-eabi-g++ -mcpu=arm9 bubble.cc -o arm9

View File

@ -0,0 +1,68 @@
#ifndef __puma
#include "../LLVMDisassembler.hpp"
using namespace llvm;
using namespace llvm::object;
using namespace fail;
int main(int argc, char* argv[]) {
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
// Initialize targets and assembly printers/parsers.
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs();
// llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
std::string file;
if(argc > 1){
std::cout << "Trying to disassemble: " << argv[1] << std::endl;
file = argv[1];
} else {
std::cerr << "No file to disassemble :(" << std::endl;
return -1;
}
OwningPtr<Binary> binary;
if (error_code ec = createBinary(file, binary)) {
std::cerr << "Dis" << ": '" << file << "': " << ec.message() << ".\n";
return -1;
}
ObjectFile *obj = dyn_cast<ObjectFile>(binary.get());
LLVMDisassembler disas(obj);
disas.disassemble();
LLVMDisassembler::InstrMap &instr_map = disas.getInstrMap();
std::cout << "Map Size: " << instr_map.size() << "\nTriple: " << disas.GetTriple() << std::endl;
LLVMDisassembler::InstrMap::const_iterator itr;
const MCRegisterInfo &reg_info = disas.getRegisterInfo();
std::cout << std::endl << "Number of Registers: " << reg_info.getNumRegs() << std::endl;
// for(unsigned int i = 0; i < reg_info.getNumRegs(); ++i){
// std::cout << i << " - " << reg_info.getName(i) << std::endl;
// }
fail::LLVMtoFailTranslator & ltof = disas.getTranslator() ;
for(itr = instr_map.begin(); itr != instr_map.end(); ++itr){
const LLVMDisassembler::Instr &instr = (*itr).second;
std::cout << std::hex << (*itr).first << " | " << instr.opcode << std::endl;
std::cout << std::dec << "USES: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_uses.begin();
it != instr.reg_uses.end(); ++it) {
std::cout << reg_info.getName(*it) <<"(" << *it << ") ";
std::cout << "Fail: " << ltof.getFailRegisterId(*it) << " ";
}
std::cout << std::endl;
std::cout << "DEFS: ";
for (std::vector<uint16_t>::const_iterator it = instr.reg_defs.begin();
it != instr.reg_defs.end(); ++it) {
std::cout << reg_info.getName(*it) << "(" << *it << ") ";
}
std::cout << std::endl;
}
}
#endif

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,163 @@
Triple: x86_64-unknown-unknown
Number of Registers: 160
0 - NOREG
1 - AH
2 - AL
3 - AX
4 - BH
5 - BL
6 - BP
7 - BPL
8 - BX
9 - CH
10 - CL
11 - CR0
12 - CR1
13 - CR2
14 - CR3
15 - CR4
16 - CR5
17 - CR6
18 - CR7
19 - CR8
20 - CR9
21 - CR10
22 - CR11
23 - CR12
24 - CR13
25 - CR14
26 - CR15
27 - CS
28 - CX
29 - DH
30 - DI
31 - DIL
32 - DL
33 - DR0
34 - DR1
35 - DR2
36 - DR3
37 - DR4
38 - DR5
39 - DR6
40 - DR7
41 - DS
42 - DX
43 - EAX
44 - EBP
45 - EBX
46 - ECX
47 - EDI
48 - EDX
49 - EFLAGS
50 - EIP
51 - EIZ
52 - ES
53 - ESI
54 - ESP
55 - FP0
56 - FP1
57 - FP2
58 - FP3
59 - FP4
60 - FP5
61 - FP6
62 - FS
63 - GS
64 - IP
65 - MM0
66 - MM1
67 - MM2
68 - MM3
69 - MM4
70 - MM5
71 - MM6
72 - MM7
73 - R8
74 - R8B
75 - R8D
76 - R8W
77 - R9
78 - R9B
79 - R9D
80 - R9W
81 - R10
82 - R10B
83 - R10D
84 - R10W
85 - R11
86 - R11B
87 - R11D
88 - R11W
89 - R12
90 - R12B
91 - R12D
92 - R12W
93 - R13
94 - R13B
95 - R13D
96 - R13W
97 - R14
98 - R14B
99 - R14D
100 - R14W
101 - R15
102 - R15B
103 - R15D
104 - R15W
105 - RAX
106 - RBP
107 - RBX
108 - RCX
109 - RDI
110 - RDX
111 - RIP
112 - RIZ
113 - RSI
114 - RSP
115 - SI
116 - SIL
117 - SP
118 - SPL
119 - SS
120 - ST0
121 - ST1
122 - ST2
123 - ST3
124 - ST4
125 - ST5
126 - ST6
127 - ST7
128 - XMM0
129 - XMM1
130 - XMM2
131 - XMM3
132 - XMM4
133 - XMM5
134 - XMM6
135 - XMM7
136 - XMM8
137 - XMM9
138 - XMM10
139 - XMM11
140 - XMM12
141 - XMM13
142 - XMM14
143 - XMM15
144 - YMM0
145 - YMM1
146 - YMM2
147 - YMM3
148 - YMM4
149 - YMM5
150 - YMM6
151 - YMM7
152 - YMM8
153 - YMM9
154 - YMM10
155 - YMM11
156 - YMM12
157 - YMM13
158 - YMM14
159 - YMM15