Exemple #1
0
int main(int argc, char *argv[]) {
    Diagnostics::initialize();
    ::mlog = Diagnostics::Facility("tool", Diagnostics::destination);
    Diagnostics::mfacilities.insertAndAdjust(::mlog);

    // Parse the command-line
    Partitioner2::Engine engine;
    std::vector<std::string> specimenNames = parseCommandLine(argc, argv, engine);
    if (specimenNames.empty())
        throw std::runtime_error("no specimen specified; see --help");

    // Load specimen into memory
    MemoryMap map = engine.loadSpecimens(specimenNames);

    // Configure instruction semantics
    Partitioner2::Partitioner partitioner = engine.createPartitioner();
    Disassembler *disassembler = engine.obtainDisassembler();
    const RegisterDictionary *regdict = disassembler->get_registers();
    if (disassembler->dispatcher() == NULL)
        throw std::runtime_error("no instruction semantics for this architecture");    
    BaseSemantics::RiscOperatorsPtr ops = InstructionSemantics2::ConcreteSemantics::RiscOperators::instance(regdict);
    BaseSemantics::DispatcherPtr cpu = disassembler->dispatcher()->create(ops);
    ConcreteSemantics::MemoryState::promote(ops->currentState()->memoryState())->memoryMap(map);

    // Find starting address
    rose_addr_t va = 0;
    if (settings.startVa) {
        va = *settings.startVa;
    } else if (engine.isaName() == "coldfire") {
        // Use the interrupt vector to initialize the stack pointer and instruction pointer.
        uint32_t sp, ip;
        if (4 != map.at(0).limit(4).read((uint8_t*)&sp).size())
            throw std::runtime_error("cannot read stack pointer at address 0x00000000");
        ops->writeRegister(disassembler->stackPointerRegister(), ops->number_(32, ByteOrder::be_to_host(sp)));
        if (4 != map.at(4).limit(4).read((uint8_t*)&ip).size())
            throw std::runtime_error("cannot read instruction pointer at address 0x00000004");
        va = ByteOrder::be_to_host(ip);
    } else if (!map.atOrAfter(0).require(MemoryMap::EXECUTABLE).next().assignTo(va)) {
        throw std::runtime_error("no starting address specified and none marked executable");
    }
    ops->writeRegister(disassembler->instructionPointerRegister(), ops->number_(32, va));

    // Execute
    map.dump(::mlog[INFO]);
    while (1) {
        va = ops->readRegister(disassembler->instructionPointerRegister())->get_number();
        SgAsmInstruction *insn = partitioner.instructionProvider()[va];
        SAWYER_MESG(::mlog[TRACE]) <<unparseInstructionWithAddress(insn, NULL, regdict) <<"\n";
        try {
            cpu->processInstruction(insn);
        } catch (const BaseSemantics::Exception &e) {
            ::mlog[WARN] <<e <<"\n";
        }
    }

    // std::cout <<"Final state:\n";
    // std::cout <<*ops->currentState();
}
int
main(int argc, char *argv[]) {
    ROSE_INITIALIZE;
    Diagnostics::initAndRegister(&::mlog, "tool");

    // Parse command-line
    P2::Engine engine;
    Settings settings;
    std::vector<std::string> specimen = parseCommandLine(argc, argv, engine, settings);
    if (specimen.empty()) {
        ::mlog[FATAL] <<"no specimen supplied on command-line; see --help\n";
        exit(1);
    }

    // Load specimen into ROSE's simulated memory
    if (!engine.parseContainers(specimen.front())) {
        ::mlog[FATAL] <<"cannot parse specimen binary container\n";
        exit(1);
    }
    Disassembler *disassembler = engine.obtainDisassembler();
    if (!disassembler) {
        ::mlog[FATAL] <<"no disassembler for this architecture\n";
        exit(1);
    }
    const RegisterDescriptor REG_IP = disassembler->instructionPointerRegister();
    ASSERT_require2(REG_IP.is_valid(), "simulation must know what register serves as the instruction pointer");

    // Single-step the specimen natively in a debugger and show each instruction.
    BinaryDebugger debugger(specimen);
    while (!debugger.isTerminated()) {
        uint64_t ip = debugger.readRegister(REG_IP).toInteger();
        uint8_t buf[16];                                // 16 should be large enough for any instruction
        size_t nBytes = debugger.readMemory(ip, sizeof buf, buf);
        if (0 == nBytes) {
            ::mlog[ERROR] <<"cannot read memory at " <<StringUtility::addrToString(ip) <<"\n";
        } else if (SgAsmInstruction *insn = disassembler->disassembleOne(buf, ip, nBytes, ip)) {
            std::cout <<unparseInstructionWithAddress(insn) <<"\n";
        } else {
            ::mlog[ERROR] <<"cannot disassemble instruction at " <<StringUtility::addrToString(ip) <<"\n";
        }
        debugger.singleStep();
    }
    std::cout <<debugger.howTerminated();
}