Exemple #1
0
double OOPLyric::GetLineProgress() const {
    LineInfo *currLine = *m_currLine;
    size_t lineHasGone = m_stopWatch->Time() - currLine->GetStartTime();
    if (lineHasGone >= currLine->GetMilSeconds()) {
        return 1;
    }

    // 假如除数为 0,不会来到这里
    return double(lineHasGone) / currLine->GetMilSeconds();
}
Exemple #2
0
InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo& lineInfo,
    RenderTextInfo& renderTextInfo, FloatingObject* lastFloatFromPreviousLine,
    WordMeasurements& wordMeasurements)
{
    reset();

    ASSERT(resolver.position().root() == m_block);

    bool appliedStartWidth = resolver.position().offset() > 0;

    LineWidth width(*m_block, lineInfo.isFirstLine(), requiresIndent(lineInfo.isFirstLine(), lineInfo.previousLineBrokeCleanly(), m_block->style()));

    skipLeadingWhitespace(resolver, lineInfo, lastFloatFromPreviousLine, width);

    if (resolver.position().atEnd())
        return resolver.position();

    BreakingContext context(resolver, lineInfo, width, renderTextInfo, lastFloatFromPreviousLine, appliedStartWidth, m_block);

    while (context.currentObject()) {
        context.initializeForCurrentObject();
        if (context.currentObject()->isBR()) {
            context.handleBR(m_clear);
        } else if (context.currentObject()->isOutOfFlowPositioned()) {
            context.handleOutOfFlowPositioned(m_positionedObjects);
        } else if (context.currentObject()->isFloating()) {
            context.handleFloat();
        } else if (context.currentObject()->isRenderInline()) {
            context.handleEmptyInline();
        } else if (context.currentObject()->isReplaced()) {
            context.handleReplaced();
        } else if (context.currentObject()->isText()) {
            if (context.handleText(wordMeasurements, m_hyphenated)) {
                // We've hit a hard text line break. Our line break iterator is updated, so go ahead and early return.
                return context.lineBreak();
            }
        } else {
            ASSERT_NOT_REACHED();
        }

        if (context.atEnd())
            return context.handleEndOfLine();

        context.commitAndUpdateLineBreakIfNeeded();

        if (context.atEnd())
            return context.handleEndOfLine();

        context.increment();
    }

    context.clearLineBreakIfFitsOnLine();

    return context.handleEndOfLine();
}
int searchLineInfoAddress(const void* arg1,const void* arg2){
    uint64_t key = *((uint64_t*)arg1);
    LineInfo* li = *((LineInfo**)arg2);

    ASSERT(li && "LineInfo should exist");

    uint64_t val = li->GET(lr_address);

    if(key < val)
        return -1;
    if(key >= val + li->getAddressSpan())
        return 1;
    return 0;
}
Exemple #4
0
    void unreachable(const LineInfo& line_info)
    {
        System::println(System::Color::error, "Error: Unreachable code was reached");
        System::println(System::Color::error, line_info.to_string()); // Always print line_info here
#ifndef NDEBUG
        std::abort();
#else
        cleanup_and_exit(EXIT_FAILURE);
#endif
    }
Exemple #5
0
void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
    FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
{
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
        RenderObject* object = resolver.position().object();
        if (object->isOutOfFlowPositioned()
            && object->style()->isOriginalDisplayInlineType()) {
            resolver.runs().addRun(createRun(0, 1, object, resolver));
            lineInfo.incrementRunsFromLeadingWhitespace();
        }
        resolver.position().increment(&resolver);
    }
    resolver.commitExplicitEmbedding(resolver.runs());
}
void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo, LineWidth& width)
{
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
        LineLayoutItem lineLayoutItem = resolver.position().getLineLayoutItem();
        if (lineLayoutItem.isOutOfFlowPositioned()) {
            setStaticPositions(m_block, LineLayoutBox(lineLayoutItem), width.indentText());
            if (lineLayoutItem.style()->isOriginalDisplayInlineType()) {
                resolver.runs().addRun(createRun(0, 1, LineLayoutItem(lineLayoutItem), resolver));
                lineInfo.incrementRunsFromLeadingWhitespace();
            }
        } else if (lineLayoutItem.isFloating()) {
            m_block.insertFloatingObject(LineLayoutBox(lineLayoutItem));
            m_block.positionNewFloats(&width);
        }
        resolver.position().increment(&resolver);
    }
    resolver.commitExplicitEmbedding(resolver.runs());
}
void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo, FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
{
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
        RenderObject& object = *resolver.position().renderer();
        if (object.isOutOfFlowPositioned()) {
            setStaticPositions(m_block, downcast<RenderBox>(object));
            if (object.style().isOriginalDisplayInlineType()) {
                resolver.runs().addRun(new BidiRun(0, 1, object, resolver.context(), resolver.dir()));
                lineInfo.incrementRunsFromLeadingWhitespace();
            }
        } else if (object.isFloating())
            m_block.positionNewFloatOnLine(m_block.insertFloatingObject(downcast<RenderBox>(object)), lastFloatFromPreviousLine, lineInfo, width);
        else if (is<RenderCombineText>(object) && object.style().hasTextCombine() && !downcast<RenderCombineText>(object).isCombined()) {
            downcast<RenderCombineText>(object).combineText();
            if (downcast<RenderCombineText>(object).isCombined())
                continue;
        }
        resolver.increment();
    }
    resolver.commitExplicitEmbedding();
}
Exemple #8
0
void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo& lineInfo,
    FloatingObject* lastFloatFromPreviousLine, LineWidth& width)
{
    while (!resolver.position().atEnd() && !requiresLineBox(resolver.position(), lineInfo, LeadingWhitespace)) {
        RenderObject* object = resolver.position().object();
        if (object->isOutOfFlowPositioned()) {
            setStaticPositions(m_block, toRenderBox(object));
            if (object->style()->isOriginalDisplayInlineType()) {
                resolver.runs().addRun(createRun(0, 1, object, resolver));
                lineInfo.incrementRunsFromLeadingWhitespace();
            }
        } else if (object->isFloating()) {
            m_block->positionNewFloatOnLine(m_block->insertFloatingObject(*toRenderBox(object)), lastFloatFromPreviousLine, lineInfo, width);
        } else if (object->isText() && object->style()->hasTextCombine() && object->isCombineText() && !toRenderCombineText(object)->isCombined()) {
            toRenderCombineText(object)->combineText();
            if (toRenderCombineText(object)->isCombined())
                continue;
        }
        resolver.position().increment(&resolver);
    }
    resolver.commitExplicitEmbedding(resolver.runs());
}
void TauFunctionTrace::instrument(){
    //InstrumentationTool::instrument();

    LineInfoFinder* lineInfoFinder = NULL;
    if (hasLineInformation()){
        lineInfoFinder = getLineInfoFinder();
    }

    InstrumentationPoint* p;

    uint64_t nameAddr = reserveDataOffset(sizeof(uint64_t));
    uint64_t fileAddr = reserveDataOffset(sizeof(uint64_t));
    uint64_t lineAddr = reserveDataOffset(sizeof(uint32_t));
    uint64_t siteIndexAddr = reserveDataOffset(sizeof(uint32_t));

    uint32_t site = functionEntry->addConstantArgument();
    ASSERT(site == functionExit->addConstantArgument());

    std::pebil_map_type<uint64_t, ControlInfo> functions;
    std::vector<uint64_t> orderedfuncs;

    uint32_t sequenceId = 0;
    if (doIntro){
        // go over all functions and intrument entries/exits
        for (uint32_t i = 0; i < getNumberOfExposedFunctions(); i++){
            Function* function = getExposedFunction(i);
            uint64_t addr = function->getBaseAddress();
            if (instrumentList && !instrumentList->functionMatches(function->getName())){
                continue;
            }
            if (!strcmp(function->getName(), "_fini")){
                continue;
            }

            BasicBlock* entryBlock = function->getFlowGraph()->getEntryBlock();
            Vector<BasicBlock*>* exitPoints = function->getFlowGraph()->getExitBlocks();

            std::string c;
            c.append(function->getName());
            if (c == "_start"){
                exitPoints->append(getProgramExitBlock());
                PRINT_INFOR("Special case: inserting exit for _start inside _fini since control generally doesn't reach its exit");
            }

            ASSERT(functions.count(addr) == 0 && "Multiple functions have the same base address?");

            PRINT_INFOR("[FUNCTION index=%d] internal instrumentation: %s", sequenceId, function->getName());

            ControlInfo f = ControlInfo();
            f.name = c;
            f.file = "";
            f.line = 0;
            f.index = sequenceId++;
            f.baseaddr = addr;
            f.type = ControlType_Function;

            LineInfo* li = NULL;
            if (lineInfoFinder){
                li = lineInfoFinder->lookupLineInfo(addr);
            }

            if (li){
                f.file.append(li->getFileName());
                f.line = li->GET(lr_line);
            }

            functions[addr] = f;
            orderedfuncs.push_back(addr);

            InstrumentationPoint* prior = addInstrumentationPoint(entryBlock->getLeader(), functionEntry, InstrumentationMode_tramp, InstLocation_prior);
            prior->setPriority(InstPriority_custom3);
            assignStoragePrior(prior, f.index, site);

            for (uint32_t j = 0; j < exitPoints->size(); j++){
                InstrumentationPoint* after = addInstrumentationPoint((*exitPoints)[j]->getExitInstruction(), functionExit, InstrumentationMode_tramp, InstLocation_prior);
                after->setPriority(InstPriority_custom5);

                if (c == "_start" && j == exitPoints->size() - 1){
                    after->setPriority(InstPriority_custom6);
                }
                assignStoragePrior(after, f.index, site);
            }

            delete exitPoints;
        }

    } else {
        // go over all instructions. when we find a call, instrument it
        for (uint32_t i = 0; i < getNumberOfExposedInstructions(); i++){
            X86Instruction* x = getExposedInstruction(i);
            ASSERT(x->getContainer()->isFunction());
            Function* function = (Function*)x->getContainer();

            if (x->isFunctionCall()){
                uint64_t addr = x->getTargetAddress();
                Symbol* functionSymbol = getElfFile()->lookupFunctionSymbol(addr);
            
                if (functionSymbol){

                    if (instrumentList && !instrumentList->functionMatches(functionSymbol->getSymbolName())){
                        continue;
                    }
                    ASSERT(x->getSizeInBytes() == Size__uncond_jump);
                
                    std::string c;
                    c.append(functionSymbol->getSymbolName());
                    if (functions.count(addr) == 0){
                        PRINT_INFOR("[FUNCTION index=%d] call site instrumentation: %#lx(%s) -> %s", sequenceId, addr, function->getName(), functionSymbol->getSymbolName());

                        ControlInfo f = ControlInfo();
                        f.name = c;
                        f.file = "";
                        f.line = 0;
                        f.index = sequenceId++;
                        f.baseaddr = addr;
                        f.type = ControlType_Function;

                        LineInfo* li = NULL;
                        if (lineInfoFinder){
                            li = lineInfoFinder->lookupLineInfo(addr);
                        }

                        if (li){
                            f.file.append(li->getFileName());
                            f.line = li->GET(lr_line);
                        }

                        functions[addr] = f;
                        orderedfuncs.push_back(addr);
                    }
                    uint32_t idx = functions[addr].index;

                    Base* exitpoint = (Base*)x;
                    if (c == "__libc_start_main"){
                        PRINT_INFOR("Special case: inserting exit for __libc_start_main inside _fini since this call generally doesn't return");
                        exitpoint = (Base*)getProgramExitBlock();
                    }

                    InstrumentationPoint* prior = addInstrumentationPoint(x, functionEntry, InstrumentationMode_tramp, InstLocation_prior);
                    InstrumentationPoint* after = addInstrumentationPoint(exitpoint, functionExit, InstrumentationMode_tramp, InstLocation_after);

                    assignStoragePrior(prior, idx, site);
                    assignStoragePrior(after, idx, site);
                }
            }
        }
    }


    // set up argument passing for function registration
    functionRegister->addArgument(nameAddr);
    functionRegister->addArgument(fileAddr);
    functionRegister->addArgument(lineAddr);
    uint32_t siteReg = functionRegister->addConstantArgument();


    // go over every function that was found, insert a registration call at program start
    for (std::vector<uint64_t>::iterator it = orderedfuncs.begin(); it != orderedfuncs.end(); it++){
        uint64_t addr = *it;
        ControlInfo f = functions[addr];
       
        ASSERT(f.baseaddr == addr);

        InstrumentationPoint* p = addInstrumentationPoint(getProgramEntryBlock(), functionRegister, InstrumentationMode_tramp);
        p->setPriority(InstPriority_custom1);

        const char* cstring = f.name.c_str();
        uint64_t storage = reserveDataOffset(strlen(cstring) + 1);
        initializeReservedData(getInstDataAddress() + storage, strlen(cstring), (void*)cstring);
        assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + nameAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());

        const char* cstring2 = f.file.c_str();
        if (f.file == ""){
            assignStoragePrior(p, NULL, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());            
        } else {
            storage = reserveDataOffset(strlen(cstring2) + 1);
            initializeReservedData(getInstDataAddress() + storage, strlen(cstring2), (void*)cstring2);
            assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());
        }

        assignStoragePrior(p, f.line, getInstDataAddress() + lineAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());
        assignStoragePrior(p, f.index, siteReg);
    }


    if (!instrumentList){
        return;
    }

    // instrument loops
    std::pebil_map_type<uint64_t, ControlInfo> loops;
    std::vector<uint64_t> orderedloops;

    loopRegister->addArgument(nameAddr);
    loopRegister->addArgument(fileAddr);
    loopRegister->addArgument(lineAddr);
    ASSERT(siteReg == loopRegister->addConstantArgument());

    for (uint32_t i = 0; i < getNumberOfExposedFunctions(); i++){
        Function* function = getExposedFunction(i);
        FlowGraph* flowgraph = function->getFlowGraph();

        if (!instrumentList->loopMatches(function->getName())){
            continue;
        }

        for (uint32_t j = 0; j < flowgraph->getNumberOfLoops(); j++){
            Loop* loop = flowgraph->getLoop(j);
            uint32_t depth = flowgraph->getLoopDepth(loop);
            BasicBlock* head = loop->getHead();
            uint64_t addr = head->getBaseAddress();

            // only want outer-most (depth == 1) loops
            if (depth != 1){
                continue;
            }

            BasicBlock** allLoopBlocks = new BasicBlock*[loop->getNumberOfBlocks()];
            loop->getAllBlocks(allLoopBlocks);

            // reject any loop that contains an indirect branch since it is difficult to guarantee that we will find all exits
            bool badLoop = false;
            for (uint32_t k = 0; k < loop->getNumberOfBlocks() && !badLoop; k++){
                BasicBlock* bb = allLoopBlocks[k];
                if (bb->getExitInstruction()->isIndirectBranch()){
                    badLoop = true;
                }
            }

            if (badLoop){
                PRINT_WARN(20, "Loop at %#lx in %s contains an indirect branch so we can't guarantee that all exits will be found. skipping!", addr, function->getName());
                delete[] allLoopBlocks;
                continue;
            }

            std::string c;
            c.append(function->getName());

            uint32_t entryc = 0;

            Vector<LoopPoint*>* points = NULL;

            // if addr already exists, it means that two loops share a head and we are going to merge them logically here
            if (loops.count(addr) == 0){

                ControlInfo f = ControlInfo();
                f.name = c;
                f.file = "";
                f.line = 0;
                f.index = sequenceId++;
                f.baseaddr = addr;
                f.type = ControlType_Loop;

                points = new Vector<LoopPoint*>();
                f.info = points;

                LineInfo* li = NULL;
                if (lineInfoFinder){
                    li = lineInfoFinder->lookupLineInfo(addr);
                }
                if (li){
                    f.file.append(li->getFileName());
                    f.line = li->GET(lr_line);
                }

                loops[addr] = f;
                orderedloops.push_back(addr);

                // find entries into this loop
                for (uint32_t k = 0; k < head->getNumberOfSources(); k++){
                    BasicBlock* source = head->getSourceBlock(k);

                    if (!loop->isBlockIn(source->getIndex())){
                        LoopPoint* lp = new LoopPoint();
                        points->append(lp);

                        lp->flowgraph = flowgraph;
                        lp->source = source;
                        lp->target = NULL;
                        lp->entry = true;
                        lp->interpose = false;

                        if (source->getBaseAddress() + source->getNumberOfBytes() != head->getBaseAddress()){
                            lp->interpose = true;
                            lp->target = head;
                        }
                        entryc++;
                    }
                }
            }

            ControlInfo f = loops[addr];
            points = f.info;

            // find exits from this loop
            uint32_t exitc = 0;
            for (uint32_t k = 0; k < loop->getNumberOfBlocks(); k++){
                BasicBlock* bb = allLoopBlocks[k];
                if (bb->endsWithReturn()){
                    LoopPoint* lp = new LoopPoint();
                    points->append(lp);

                    lp->flowgraph = flowgraph;
                    lp->source = bb;
                    lp->target = NULL;
                    lp->entry = false;
                    lp->interpose = false;
                    exitc++;
                }

                for (uint32_t m = 0; m < bb->getNumberOfTargets(); m++){
                    BasicBlock* target = bb->getTargetBlock(m);
                    if (!loop->isBlockIn(target->getIndex())){
                        LoopPoint* lp = new LoopPoint();
                        points->append(lp);

                        lp->flowgraph = flowgraph;
                        lp->source = bb;
                        lp->target = NULL;
                        lp->entry = false;
                        lp->interpose = false;

                        if (target->getBaseAddress() != bb->getBaseAddress() + bb->getNumberOfBytes()){
                            lp->interpose = true;
                            lp->target = target;
                        }
                        exitc++;
                    }
                }
            }

            PRINT_INFOR("[LOOP index=%d] loop instrumentation %#lx(%s) has %d entries and %d exits", sequenceId-1, addr, function->getName(), entryc, exitc);

            delete[] allLoopBlocks;
        }
    }

    // go over every loop that was found, insert a registration call at program start
    // [source_addr -> [target_addr -> interposed]]
    std::pebil_map_type<uint64_t, std::pebil_map_type<uint64_t, BasicBlock*> > idone;
    for (std::vector<uint64_t>::iterator it = orderedloops.begin(); it != orderedloops.end(); it++){
        uint64_t addr = *it;
        ControlInfo f = loops[addr];
       
        ASSERT(f.baseaddr == addr);

        InstrumentationPoint* p = addInstrumentationPoint(getProgramEntryBlock(), loopRegister, InstrumentationMode_tramp);
        p->setPriority(InstPriority_custom2);

        const char* cstring = f.name.c_str();
        uint64_t storage = reserveDataOffset(strlen(cstring) + 1);
        initializeReservedData(getInstDataAddress() + storage, strlen(cstring), (void*)cstring);
        assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + nameAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());

        const char* cstring2 = f.file.c_str();
        if (f.file == ""){
            assignStoragePrior(p, NULL, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());            
        } else {
            storage = reserveDataOffset(strlen(cstring2) + 1);
            initializeReservedData(getInstDataAddress() + storage, strlen(cstring2), (void*)cstring2);
            assignStoragePrior(p, getInstDataAddress() + storage, getInstDataAddress() + fileAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());
        }

        assignStoragePrior(p, f.line, getInstDataAddress() + lineAddr, X86_REG_CX, getInstDataAddress() + getRegStorageOffset());
        assignStoragePrior(p, f.index, siteReg);

        // now add instrumentation for each loop entry/exit
        Vector<LoopPoint*>* v = (Vector<LoopPoint*>*)f.info;
        for (uint32_t i = 0; i < v->size(); i++){
            LoopPoint* lp = (*v)[i];
            ASSERT(lp->flowgraph && lp->source);

            BasicBlock* bb = lp->source;
            if (lp->interpose){
                ASSERT(lp->target);
                if (idone.count(lp->source->getBaseAddress()) == 0){
                    idone[lp->source->getBaseAddress()] = std::pebil_map_type<uint64_t, BasicBlock*>();
                }
                if (idone[lp->source->getBaseAddress()].count(lp->target->getBaseAddress()) == 0){
                    idone[lp->source->getBaseAddress()][lp->target->getBaseAddress()] = initInterposeBlock(lp->flowgraph, lp->source->getIndex(), lp->target->getIndex());
                }

                bb = idone[lp->source->getBaseAddress()][lp->target->getBaseAddress()];

            } else {
                ASSERT(lp->target == NULL);
            }

            Base* pt = (Base*)bb;
            InstLocations loc = InstLocation_prior;

            // if exit block falls through, we must place the instrumentation point at the very end of the block
            if (!lp->entry && !lp->interpose){
                pt = (Base*)bb->getExitInstruction();
                if (!bb->getExitInstruction()->isReturn()){
                    loc = InstLocation_after;
                }
            }

            InstrumentationFunction* inf = functionExit;
            if (lp->entry){
                inf = functionEntry;
            }

            InstrumentationPoint* p = addInstrumentationPoint(pt, inf, InstrumentationMode_tramp, loc);
            p->setPriority(InstPriority_custom4);
            assignStoragePrior(p, f.index, site);

            delete lp;
        }
        delete v;
    }

}
void BasicBlockCounter::instrument() 
{
    InstrumentationTool::instrument();
    ASSERT(currentPhase == ElfInstPhase_user_reserve && "Instrumentation phase order must be observed"); 
    uint32_t temp32;

    LineInfoFinder* lineInfoFinder = NULL;
    if (hasLineInformation()){
        lineInfoFinder = getLineInfoFinder();
    }

    uint64_t lineArray = reserveDataOffset(getNumberOfExposedBasicBlocks() * sizeof(uint32_t));
    uint64_t fileNameArray = reserveDataOffset(getNumberOfExposedBasicBlocks() * sizeof(char*));
    uint64_t funcNameArray = reserveDataOffset(getNumberOfExposedBasicBlocks() * sizeof(char*));
    uint64_t hashCodeArray = reserveDataOffset(getNumberOfExposedBasicBlocks() * sizeof(uint64_t));
    uint64_t appName = reserveDataOffset((strlen(getApplicationName()) + 1) * sizeof(char));
    initializeReservedData(getInstDataAddress() + appName, strlen(getApplicationName()) + 1, getApplicationName());
    uint64_t instExt = reserveDataOffset((strlen(getInstSuffix()) + 1) * sizeof(char));
    initializeReservedData(getInstDataAddress() + instExt, strlen(getInstSuffix()) + 1, getInstSuffix());

    // the number blocks in the code
    uint64_t counterArrayEntries = reserveDataOffset(sizeof(uint32_t));

    // an array of counters. note that everything is passed by reference
    uint64_t counterArray = reserveDataOffset(getNumberOfExposedBasicBlocks() * sizeof(uint32_t));

    exitFunc->addArgument(counterArray);
    exitFunc->addArgument(appName);
    exitFunc->addArgument(instExt);

    InstrumentationPoint* p = addInstrumentationPoint(getProgramExitBlock(), exitFunc, InstrumentationMode_tramp);
    if (!p->getInstBaseAddress()){
        PRINT_ERROR("Cannot find an instrumentation point at the exit function");
    }

    temp32 = 0;
    for (uint32_t i = 0; i < getNumberOfExposedBasicBlocks(); i++){
        initializeReservedData(getInstDataAddress() + counterArray + i*sizeof(uint32_t), sizeof(uint32_t), &temp32);
    }

    // the number of inst points
    entryFunc->addArgument(counterArrayEntries);
    temp32 = getNumberOfExposedBasicBlocks();
    initializeReservedData(getInstDataAddress() + counterArrayEntries, sizeof(uint32_t), &temp32);

    // an array for line numbers
    entryFunc->addArgument(lineArray);
    // an array for file name pointers
    entryFunc->addArgument(fileNameArray);
    // an array for function name pointers
    entryFunc->addArgument(funcNameArray);
    // an array for hashcodes
    entryFunc->addArgument(hashCodeArray);

    p = addInstrumentationPoint(getProgramEntryBlock(), entryFunc, InstrumentationMode_tramp, FlagsProtectionMethod_full, InstLocation_prior);
    p->setPriority(InstPriority_userinit);
    if (!p->getInstBaseAddress()){
        PRINT_ERROR("Cannot find an instrumentation point at the entry block");
    }

    uint64_t noDataAddr = getInstDataAddress() + reserveDataOffset(strlen(NOSTRING) + 1);
    char* nostring = new char[strlen(NOSTRING) + 1];
    sprintf(nostring, "%s\0", NOSTRING);
    initializeReservedData(noDataAddr, strlen(NOSTRING) + 1, nostring);

    PRINT_DEBUG_MEMTRACK("There are %d instrumentation points", getNumberOfExposedBasicBlocks());
    Vector<BasicBlock*>* allBlocks = new Vector<BasicBlock*>();
    Vector<LineInfo*>* allLineInfos = new Vector<LineInfo*>();

    uint32_t noProtPoints = 0;
    uint32_t complexSelection = 0;
    for (uint32_t i = 0; i < getNumberOfExposedBasicBlocks(); i++){

        BasicBlock* bb = getExposedBasicBlock(i);
        LineInfo* li = NULL;
        if (lineInfoFinder){
            li = lineInfoFinder->lookupLineInfo(bb);
        }
        Function* f = bb->getFunction();

        (*allBlocks).append(bb);
        (*allLineInfos).append(li);

        if (i % 1000 == 0){
            PRINT_DEBUG_MEMTRACK("inst point %d", i);
            PRINT_MEMTRACK_STATS(__LINE__, __FILE__, __FUNCTION__);            
        }

        if (li){
            uint32_t line = li->GET(lr_line);
            initializeReservedData(getInstDataAddress() + lineArray + sizeof(uint32_t)*i, sizeof(uint32_t), &line);

            uint64_t filename = reserveDataOffset(strlen(li->getFileName()) + 1);
            uint64_t filenameAddr = getInstDataAddress() + filename;
            initializeReservedData(getInstDataAddress() + fileNameArray + i*sizeof(char*), sizeof(char*), &filenameAddr);
            initializeReservedData(getInstDataAddress() + filename, strlen(li->getFileName()) + 1, (void*)li->getFileName());

        } else {
            temp32 = 0;
            initializeReservedData(getInstDataAddress() + lineArray + sizeof(uint32_t)*i, sizeof(uint32_t), &temp32);
            initializeReservedData(getInstDataAddress() + fileNameArray + i*sizeof(char*), sizeof(char*), &noDataAddr);
        }
        uint64_t funcname = reserveDataOffset(strlen(f->getName()) + 1);
        uint64_t funcnameAddr = getInstDataAddress() + funcname;
        initializeReservedData(getInstDataAddress() + funcNameArray + i*sizeof(char*), sizeof(char*), &funcnameAddr);
        initializeReservedData(getInstDataAddress() + funcname, strlen(f->getName()) + 1, (void*)f->getName());

        uint64_t hashValue = bb->getHashCode().getValue();
        initializeReservedData(getInstDataAddress() + hashCodeArray + i*sizeof(uint64_t), sizeof(uint64_t), &hashValue);
        
        InstrumentationSnippet* snip = new InstrumentationSnippet();
        uint64_t counterOffset = counterArray + (i * sizeof(uint32_t));

        // snippet contents, in this case just increment a counter
        if (is64Bit()){
            snip->addSnippetInstruction(X86InstructionFactory64::emitAddImmByteToMem(1, getInstDataAddress() + counterOffset));
        } else {
            snip->addSnippetInstruction(X86InstructionFactory32::emitAddImmByteToMem(1, getInstDataAddress() + counterOffset));
        }

        // do not generate control instructions to get back to the application, this is done for
        // the snippet automatically during code generation
            
        // register the snippet we just created
        addInstrumentationSnippet(snip);            
            
        // register an instrumentation point at the function that uses this snippet
        FlagsProtectionMethods prot = FlagsProtectionMethod_light;
#ifndef NO_REG_ANALYSIS
        if (bb->getLeader()->allFlagsDeadIn()){
            prot = FlagsProtectionMethod_none;
            noProtPoints++;
        }
        for (uint32_t j = 0; j < bb->getNumberOfInstructions(); j++){
            if (bb->getInstruction(j)->allFlagsDeadIn() || bb->getInstruction(j)->allFlagsDeadOut()){
                complexSelection++;
                break;
            }
        }
#endif
        InstrumentationPoint* p = addInstrumentationPoint(bb, snip, InstrumentationMode_inline, prot);
    }
    PRINT_MEMTRACK_STATS(__LINE__, __FILE__, __FUNCTION__);
#ifdef NO_REG_ANALYSIS
    PRINT_WARN(10, "Warning: register analysis disabled");
#endif
    PRINT_INFOR("Excluding flags protection for %d/%d instrumentation points", noProtPoints, getNumberOfExposedBasicBlocks());
    //PRINT_INFOR("complex inst point selection: %d/%d instrumentation points", complexSelection, getNumberOfExposedBasicBlocks());

    printStaticFile(allBlocks, allLineInfos);

    delete[] nostring;
    delete allBlocks;
    delete allLineInfos;

    ASSERT(currentPhase == ElfInstPhase_user_reserve && "Instrumentation phase order must be observed"); 
}
Exemple #11
0
 void exit_with_code(const LineInfo& line_info, const int exit_code)
 {
     Debug::println(System::Color::error, line_info.to_string());
     cleanup_and_exit(exit_code);
 }
Exemple #12
0
void OOPLyric::OnMouseEvent(VdkMouseEvent &e) {
    switch (e.evtCode) {
    case RIGHT_UP: {
        // 拖动歌词时不要响应右键事件
        if (TestState(OLST_DRAGGING)) {
            return;
        }

        wxPoint menuPos(AbsoluteRect().GetPosition());
        menuPos.x += e.mousePos.x;
        menuPos.y += e.mousePos.y;

        m_Window->ShowContextMenu(this, menuPos);

        break;
    }

    case LEFT_DOWN: {
        m_draggDistance = e.mousePos.y;
        SetAddinState(OLST_DRAGGING_STARTED);

        break;
    }

    case DRAGGING: {
        // 不接受先在一首歌的会话中拖动歌词,然后在未释放鼠标的情况下
        // 另一首歌开始播放,继续前面的拖动事件
        if (!TestState(OLST_DRAGGING_STARTED)) {
            break;
        }

        if (!IsOk()) {
            break;
        }

        if (m_timer.IsRunning()) {
            Pause();
            SetAddinState(OLST_RUNNING_BEFORE_DRAGGING);
        }

        SetAddinState(OLST_DRAGGING);

        //======================================================

        int ystart;
        GetViewStartCoord(NULL, &ystart);

        int dY = e.mousePos.y - m_draggDistance;
        m_draggDistance = e.mousePos.y;

        // 这是一行我们手工加上去的空行
        int rowHeight = GetRowHeight();
        int upperBound =
            (*(m_parser->begin()))->GetLyric().empty() ? rowHeight : 0;

        // 无法继续将帘布向上卷(再拖下去就到下一首了)
        // 我们将拖到尽头的事件视为无效
        bool lastLine = false;

        // 情景:将虚拟画布像窗帘一样向下拖
        // 拖动尽头了,不能再把窗帘哪怕拖下一寸
        if (ystart - dY < upperBound) {
            dY = ystart - upperBound; // 加加减减的原因参照(*)
        } else {
            int maxy;
            GetMaxViewStartCoord(NULL, &maxy);

            // 将帘布向上卷,卷到尽头了,再卷下去就会导致
            // 无法完整遮住窗口
            if (ystart - dY > maxy) {
                dY = ystart - maxy; // 加加减减的原因参照(*)
                // 无效拖动事件
                lastLine = true;
            }
        }

        if (dY) {
            SetViewStart(0, ystart - dY, &e.dc);   //………………(*)
        }

        // 无效拖动事件
        if (lastLine) {
            m_draggHit = m_parser->end();
        }

        //===================================================
        // 绘制中间线段

        wxRect rc(GetAbsoluteRect());
        int y = rc.y + m_blankLinesTop * GetRowHeight();

        m_Window->ResetDcOrigin(e.dc);
        e.dc.SetPen(wxPen(m_TextColor));
        e.dc.DrawLine(rc.x, y, rc.GetRight(), y);

        break;
    }

    case NORMAL:
    case LEFT_UP: {
        if (!TestState(OLST_DRAGGING) ||
            !TestState(OLST_DRAGGING_STARTED)) {
            break;
        }

        wxASSERT(IsOk());

        //-----------------------------------------------------

        RemoveState(OLST_DRAGGING | OLST_DRAGGING_STARTED);

        // 拖到最下面了,尽头
        if (m_draggHit == m_parser->end()) {
            RefreshState(&e.dc);
        } else {
            int ystart; // 起始绘图坐标
            GetViewStartCoord(NULL, &ystart);

            LineInfo *lineDraggHit = *m_draggHit;
            size_t timeToGo = lineDraggHit->GetStartTime();

            int rowHeight = GetRowHeight();
            double linePercentage = double(ystart % rowHeight) / rowHeight ;
            timeToGo += lineDraggHit->GetMilSeconds() * linePercentage;

            // 歌词可能并不匹配正在播放的歌曲
            if (timeToGo < m_parser->GetTimeSum()) {
                m_currLine = m_draggHit;

                if (IsReadyForEvent()) {
                    FireEvent(&e.dc, (void *) timeToGo);
                }
            }
        }

        bool resume = TestState(OLST_RUNNING_BEFORE_DRAGGING);
        if (resume) {
            RemoveState(OLST_RUNNING_BEFORE_DRAGGING);
            Resume();
        }

        break;
    }

    default:

        break;
    }
}
Exemple #13
0
VdkCusdrawReturnFlag OOPLyric::DoDrawCellText
        (const VdkLcCell *cell,
         int col_index,
         int index0,
         wxDC &dc,
         VdkLcHilightState state) {
    wxASSERT(m_parser);

    // 注意:index 是不计算加入的空行的
    int index = (int) (cell->GetClientData()) - 1;
    if (index == -1) { // 此时 ClientData == NULL,是我们添加的空行
        return VCCDRF_DODEFAULT;
    }

    dc.SetTextForeground(m_TextColor);

    // 暂停时高亮当前行,情景见于用户正在拖动歌词。
    // 另外先暂停,然后拖动歌词完毕,此时假如歌词秀是以卡拉OK
    // 方式进行显示时,那么不会保持半高亮的状态,而是全高亮。
    if (TestState(OLST_PAUSED)) {
        int yStart;
        GetViewStartCoord(NULL, &yStart);

        int rowHeight = GetRowHeight();
        int dragRegion = yStart + rowHeight * m_blankLinesTop;
        int index2 = index + m_blankLinesTop;

        // 检测拖动歌词时中间线下面的一行
        if (rowHeight * index2 <= dragRegion &&
            rowHeight * (index2 + 1) > dragRegion) {
            m_draggHit = m_parser->GetLine(index);

            dc.SetTextForeground(m_HilightColor);
        }

        return VCCDRF_DODEFAULT;
    }

    LineInfo *currLine = *m_currLine;
    // TODO: 是否考虑优化?
    size_t currLineIndex = m_parser->IndexOf(m_currLine);
    int lineHasGone = m_stopWatch->Time() - currLine->GetStartTime();

    if ((index == currLineIndex - 1) && !cell->GetLabel().empty()) {
        // 使用渐变色还原上一句歌词
        if (lineHasGone < ALPHA_SHOW_LAST_LINE_MS) {
            unsigned char r, g, b;
            double alpha2 = double(lineHasGone) / ALPHA_SHOW_LAST_LINE_MS;
            double alpha1 = 1 - alpha2;

            r = m_HilightColor.Red() * alpha1 + m_TextColor.Red() * alpha2;
            g = m_HilightColor.Green() * alpha1 + m_TextColor.Green() * alpha2;
            b = m_HilightColor.Blue() * alpha1 + m_TextColor.Blue() * alpha2;

            dc.SetTextForeground(wxColour(r, g, b));
        }
    } else if (index == currLineIndex) { // 高亮当前文本行
        // 尽管这是一种很罕见的情况,但一旦出现了就会导致下面 (*) 表达式
        // 的除数为 0
        if (currLine->GetMilSeconds() == 0) {
            return VCCDRF_DODEFAULT;
        }

        if (!cell->IsEmpty()) {
            /* 经验教训:
            1. SetClippingRegiion 有叠加效应,因此在执行新的
               SetClippingRegiion 前别忘了销毁原来的 ClippingRegiion 。
            2. 关于表达式中整数与浮点数混用:注意中间运算结果会
               被强制转换成 int 然后参加下一步的运算,并不是对
               最终结果进行转换,使之成为一个浮点数。
            */

            const int rowHeight = GetRowHeight();
            int y = (currLineIndex + m_blankLinesTop) * rowHeight;
            cell->DrawLabel(dc, 0, y);

            // (*)
            double lineProgress = double(lineHasGone) / currLine->GetMilSeconds();

            // 要实现 KALA-OK 效果的文本宽度
            int w = (m_Rect.width - cell->GetX_Padding() * 2) * lineProgress;

            wxRect rc(GetAbsoluteRect());
            const int bottom = rc.y + rc.height;

            int yStart;
            VdkScrolledWindow::GetViewStartCoord(NULL, &yStart);
            rc.y += y - yStart;

            rc.width = cell->GetX_Padding() + w;
            rc.height = rowHeight;
            // 不能使 KALA-OK 效果的 ClippingRegion 超出列表窗口
            if ((rc.y + rc.height) > bottom) {
                rc.height = bottom - rc.y;
            }

            VdkDcDeviceOriginSaver saver(dc);
            dc.SetDeviceOrigin(0, 0);
            VdkDcClippingRegionDestroyer destroyer(dc, rc);

#       ifdef __WXGTK__
            dc.SetBrush(m_crossBrush1);
            dc.DrawRectangle(rc);
#       endif
            dc.SetTextForeground(m_HilightColor);

            cell->DrawLabel(dc, rc.x, rc.y);
        }

        return VCCDRF_SKIPDEFAULT;
    }

    return VCCDRF_DODEFAULT;
}