/*
 * Copyright (c) 2006-2009 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#include "base/cp_annotate.hh"

#include "arch/generic/linux/threadinfo.hh"
#include "arch/utility.hh"
#include "base/callback.hh"
#include "base/loader/object_file.hh"
#include "base/output.hh"
#include "base/trace.hh"
#include "config/the_isa.hh"
#include "cpu/thread_context.hh"
#include "debug/Annotate.hh"
#include "debug/AnnotateVerbose.hh"
#include "sim/arguments.hh"
#include "sim/core.hh"
#include "sim/sim_exit.hh"
#include "sim/system.hh"

struct CPAIgnoreSymbol
{
    const char *symbol;
    size_t len;
};
#define CPA_IGNORE_SYMBOL(sym) { #sym, sizeof(#sym) }

CPAIgnoreSymbol ignoreSymbols[] = {
    CPA_IGNORE_SYMBOL("m5a_"),
    CPA_IGNORE_SYMBOL("ret_from_sys_call"),
    CPA_IGNORE_SYMBOL("ret_from_reschedule"),
    CPA_IGNORE_SYMBOL("_spin_"),
    CPA_IGNORE_SYMBOL("local_bh_"),
    CPA_IGNORE_SYMBOL("restore_all"),
    CPA_IGNORE_SYMBOL("Call_Pal_"),
    CPA_IGNORE_SYMBOL("pal_post_interrupt"),
    CPA_IGNORE_SYMBOL("rti_to_"),
    CPA_IGNORE_SYMBOL("sys_int_2"),
    CPA_IGNORE_SYMBOL("sys_interrupt"),
    CPA_IGNORE_SYMBOL("normal_int"),
    CPA_IGNORE_SYMBOL("TRAP_INTERRUPT_10_"),
    CPA_IGNORE_SYMBOL("Trap_Interrupt"),
    CPA_IGNORE_SYMBOL("do_entInt"),
    CPA_IGNORE_SYMBOL("__do_softirq"),
    CPA_IGNORE_SYMBOL("_end"),
    CPA_IGNORE_SYMBOL("entInt"),
    CPA_IGNORE_SYMBOL("entSys"),
    {0,0}
};
#undef CPA_IGNORE_SYMBOL

using namespace std;
using namespace TheISA;

bool CPA::exists;
CPA *CPA::_cpa;

class AnnotateDumpCallback : public Callback
{

  private:
    CPA *cpa;
  public:
    virtual void process();
    AnnotateDumpCallback(CPA *_cpa)
        : cpa(_cpa)
    {}
};

void
AnnotateDumpCallback::process()
{
    cpa->dump(true);
    cpa->dumpKey();
}


CPA::CPA(Params *p)
    : SimObject(p), numSm(0), numSmt(0), numSys(0), numQs(0), conId(0)
{
    if (exists)
        fatal("Multiple annotation objects found in system");
    exists = true;

    _enabled = p->enabled;
    _cpa = this;

    vector<string>::iterator i;
    i = p->user_apps.begin();

    while (i != p->user_apps.end()) {
        ObjectFile *of = createObjectFile(*i);
        string sf;
        if (!of)
            fatal("Couldn't load symbols from file: %s\n", *i);
        sf = *i;
        sf.erase(0, sf.rfind('/') + 1);;
        DPRINTFN("file %s short: %s\n", *i, sf);
        userApp[sf] = new SymbolTable;
        bool result1 = of->loadGlobalSymbols(userApp[sf]);
        bool result2 = of->loadLocalSymbols(userApp[sf]);
        if (!result1 || !result2)
            panic("blah");
        assert(result1 && result2);
        i++;
    }
}

void
CPA::startup()
{
    osbin = simout.create("annotate.bin", true);
    // MAGIC version number 'M''5''A'N' + version/capabilities
    ah.version = 0x4D35414E00000101ULL;
    ah.num_recs = 0;
    ah.key_off = 0;
    osbin->write((char*)&ah, sizeof(AnnotateHeader));

    registerExitCallback(new AnnotateDumpCallback(this));
}

uint64_t
CPA::getFrame(ThreadContext *tc)
{
    // This code is ISA specific and will need to be changed
    // if the annotation code is used for something other than Alpha
    return (tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23) &
            ~ULL(0x3FFF));

}

void
CPA::swSmBegin(ThreadContext *tc)
{
    if (!enabled())
        return;

    Arguments args(tc);
    std::string st;
    Addr junk;
    char sm[50];
    if (!TheISA::inUserMode(tc))
        debugSymbolTable->findNearestSymbol(
            tc->readIntReg(ReturnAddressReg), st, junk);

    tc->getVirtProxy().readString(sm, args[0], 50);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());

    if (!sm[0])
        warn("Got null SM at tick %d\n", curTick());

    int sysi = getSys(sys);
    int smi = getSm(sysi, sm, args[1]);
    DPRINTF(Annotate,  "Starting machine: %s(%d) sysi: %d id: %#x\n", sm,
            smi, sysi, args[1]);
    DPRINTF(Annotate, "smMap[%d] = %d, %s, %#x\n", smi,
            smMap[smi-1].first, smMap[smi-1].second.first,
            smMap[smi-1].second.second);

    uint64_t frame = getFrame(tc);
    StackId sid = StackId(sysi, frame);

    // check if we need to link to the previous state machine
    int flags = args[2];
    if (flags & FL_LINK) {
        if (smStack[sid].size()) {
            int prev_smi = smStack[sid].back();
            DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
                    prev_smi, sm, smi, args[1]);

            if (lnMap[smi])
                DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
                        smi, lnMap[smi]);
            assert(lnMap[smi] == 0);
            lnMap[smi] =  prev_smi;

            add(OP_LINK, FL_NONE, tc->contextId(), prev_smi, smi);
        } else {
            DPRINTF(Annotate, "Not Linking to state machine %s(%d) [%#x]\n",
                    sm, smi, args[1]);
        }
    }


    smStack[sid].push_back(smi);

    DPRINTF(Annotate, "Stack Now (%#X):\n", frame);
    for (int x = smStack[sid].size()-1; x >= 0; x--)
        DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);

    // reset the sw state exculsion to false
    if (swExpl[sid])
        swExpl[sid] = false;


    Id id = Id(sm, frame);
    if (scLinks[sysi-1][id]) {
        AnnDataPtr an = scLinks[sysi-1][id];
        scLinks[sysi-1].erase(id);
        an->stq = smi;
        an->dump = true;
        DPRINTF(Annotate,
                "Found prev unknown linking from %d to state machine %s(%d)\n",
                an->sm, sm, smi);

        if (lnMap[smi])
            DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
                    smi, lnMap[smi]);
        assert(lnMap[smi] == 0);
        lnMap[smi] =  an->sm;
    }

    // add a new begin ifwe have that info
    if (st != "") {
        DPRINTF(Annotate, "st: %s smi: %d stCache.size %d\n", st,
                smi, stCache.size());
        int sti = getSt(sm, st);
        lastState[smi] = sti;
        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
    }
}

void
CPA::swSmEnd(ThreadContext *tc)
{
    if (!enabled())
        return;

    Arguments args(tc);
    char sm[50];
    tc->getVirtProxy().readString(sm, args[0], 50);
    System *sys = tc->getSystemPtr();
    doSwSmEnd(sys, tc->contextId(), sm, getFrame(tc));
}

void
CPA::doSwSmEnd(System *sys, int cpuid, string sm, uint64_t frame)
{
    int sysi = getSys(sys);
    StackId sid = StackId(sysi, frame);


    // reset the sw state exculsion to false
    if (swExpl[sid])
        swExpl[sid] = false;


    int smib = smStack[sid].back();
    StringWrap name(sys->name());
    DPRINTF(Annotate, "Ending machine: %s[%d, %#x] (%d?)\n", sm, sysi,
            frame, smib);

    if (!smStack[sid].size() || smMap[smib-1].second.first != sm) {
        DPRINTF(Annotate, "State Machine not unwinding correctly. sid: %d, %#x"
                " top of stack: %s Current Stack:\n",
                sysi, frame, smMap[smib-1].second.first);
        for (int x = smStack[sid].size()-1; x >= 0; x--)
            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
        DPRINTF(Annotate, "Ending machine: %s; end stack: %s\n", sm,
                smMap[smib-1].second.first);

        warn("State machine stack not unwinding correctly at %d\n", curTick());
    } else {
        DPRINTF(Annotate,
                "State machine ending:%s sysi:%d id:%#x back:%d getSm:%d\n",
                sm, sysi, smMap[smib-1].second.second, smStack[sid].back(),
                getSm(sysi, sm, smMap[smib-1].second.second));
        assert(getSm(sysi, sm, smMap[smib-1].second.second) ==
                smStack[sid].back());

        int smi = smStack[sid].back();
        smStack[sid].pop_back();

        if (lnMap[smi]) {
            DPRINTF(Annotate, "Linking %d back to %d\n", smi, lnMap[smi]);
            add(OP_LINK, FL_NONE, cpuid, smi, lnMap[smi]);
            lnMap.erase(smi);
        }

        if (smStack[sid].size()) {
            add(OP_BEGIN, FL_NONE, cpuid, smi, lastState[smi]);
        }

        DPRINTF(Annotate, "Stack Now:\n");
        for (int x = smStack[sid].size()-1; x >= 0; x--)
            DPRINTF(Annotate, "-- %d\n", smStack[sid][x]);
    }
}


void
CPA::swExplictBegin(ThreadContext *tc)
{
    if (!enabled())
        return;

    Arguments args(tc);
    char st[50];
    tc->getVirtProxy().readString(st, args[1], 50);

    StringWrap name(tc->getSystemPtr()->name());
    DPRINTF(Annotate, "Explict begin of state %s\n", st);
    uint32_t flags = args[0];
    if (flags & FL_BAD)
        warn("BAD state encountered: at cycle %d: %s\n", curTick(), st);
    swBegin(tc->getSystemPtr(), tc->contextId(), st, getFrame(tc), true, args[0]);
}

void
CPA::swAutoBegin(ThreadContext *tc, Addr next_pc)
{
    if (!enabled())
        return;

    string sym;
    Addr sym_addr = 0;

    if (!TheISA::inUserMode(tc)) {
        debugSymbolTable->findNearestSymbol(next_pc, sym, sym_addr);
    } else {
        Linux::ThreadInfo ti(tc);
        string app = ti.curTaskName();
        if (userApp.count(app))
            userApp[app]->findNearestSymbol(next_pc, sym, sym_addr);
    }

    if (sym_addr)
        swBegin(tc->getSystemPtr(), tc->contextId(), sym, getFrame(tc));
}

void
CPA::swBegin(System *sys, int cpuid, std::string st, uint64_t frame, bool expl,
        int flags)
{
    int x = 0;
    int len;
    while (ignoreSymbols[x].len)
    {
        len = ignoreSymbols[x].len;
        if (!st.compare(0,len, ignoreSymbols[x].symbol, len))
            return;
        x++;
    }

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, frame);
    // if expl is true suspend symbol table based states
    if (!smStack[sid].size())
        return;
    if (!expl && swExpl[sid])
        return;
    if (expl)
        swExpl[sid] = true;
    DPRINTFS(AnnotateVerbose, sys, "SwBegin: %s sysi: %d\n", st, sysi);
    int smi = smStack[sid].back();
    int sti = getSt(smMap[smi-1].second.first, st);
    if (lastState[smi] != sti) {
        lastState[smi] = sti;
        add(OP_BEGIN, flags, cpuid, smi, sti);
    }
}

void
CPA::swEnd(ThreadContext *tc)
{
    if (!enabled())
        return;

    std::string st;
    Addr junk;
    if (!TheISA::inUserMode(tc))
        debugSymbolTable->findNearestSymbol(
            tc->readIntReg(ReturnAddressReg), st, junk);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size()) {
        DPRINTF(Annotate, "Explict end of State: %s IGNORED\n",  st);
        return;
    }
    DPRINTF(Annotate, "Explict end of State: %s\n",  st);
    // return back to symbol table based states
    swExpl[sid] = false;
    int smi = smStack[sid].back();
    if (st != "") {
        int sti = getSt(smMap[smi-1].second.first, st);
        lastState[smi] = sti;
        add(OP_BEGIN, FL_NONE, tc->contextId(), smi, sti);
    }
}

void
CPA::swQ(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    int32_t count = args[2];
    System *sys = tc->getSystemPtr();

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    if (swExpl[sid])
        swExpl[sid] = false;
    int qi = getQ(sysi, q, id);
    if (count == 0) {
        //warn("Tried to queue 0 bytes in %s, ignoring\n", q);
        return;
    }
    DPRINTFS(AnnotateQ, sys,
            "swQ: %s[%#x] cur size %d %d bytes: %d adding: %d\n",
            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
    doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
}

void
CPA::swDq(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    int32_t count = args[2];
    System *sys = tc->getSystemPtr();

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    if (swExpl[sid])
        swExpl[sid] = false;
    DPRINTFS(AnnotateQ, sys,
            "swDq: %s[%#x] cur size %d %d bytes: %d removing: %d\n",
            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);
    assert(count != 0);

    doDq(sys, FL_NONE, tc->contextId(), smi, q, qi, count);
}

void
CPA::swPq(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    int32_t count = args[2];

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    if (swExpl[sid])
        swExpl[sid] = false;
    DPRINTFS(AnnotateQ, sys,
            "swPq: %s [%#x] cur size %d %d bytes: %d peeking: %d\n",
            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);

    assert(count != 0);
    if (qBytes[qi-1] < count) {
        dump(true);
        dumpKey();
        fatal("Queue %s peeking with not enough bytes available in queue!\n", q);
    }

    add(OP_PEEK, FL_NONE, tc->contextId(), smi, qi, count);
}

void
CPA::swRq(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    int32_t count = args[2];

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    if (swExpl[sid])
        swExpl[sid] = false;
    DPRINTFS(AnnotateQ, sys,
            "swRq: %s [%#x] cur size %d %d bytes: %d reserve: %d\n",
            q, id, qSize[qi-1], qData[qi-1].size(), qBytes[qi-1], count);

    assert(count != 0);

    add(OP_RESERVE, FL_NONE, tc->contextId(), smi, qi, count);
}


void
CPA::swWf(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    int32_t count = args[3];

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    add(OP_WAIT_FULL, FL_NONE, tc->contextId(), smi, qi, count);

    if (!!args[2]) {
        char sm[50];
        tc->getVirtProxy().readString(sm, args[2], 50);
        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
    }
}

void
CPA::swWe(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    int32_t count = args[3];

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    add(OP_WAIT_EMPTY, FL_NONE, tc->contextId(), smi, qi, count);

    if (!!args[2]) {
        char sm[50];
        tc->getVirtProxy().readString(sm, args[2], 50);
        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
    }
}

void
CPA::swSq(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());
    int32_t size = args[2];
    int flags = args[3];

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int qi = getQ(sysi, q, id);
    DPRINTF(AnnotateQ, "swSq: %s [%#x] cur size: %d bytes: %d, new size: %d\n",
             q, id, qSize[qi-1], qBytes[qi-1], size);

    if (FL_RESET & flags) {
        DPRINTF(AnnotateQ, "Resetting Queue %s\n", q);
        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, 0);
        qData[qi-1].clear();
        qSize[qi-1] = 0;
        qBytes[qi-1] = 0;
    }

    if (qBytes[qi-1] < size)
        doQ(sys, FL_NONE, tc->contextId(), smi, q, qi, size - qBytes[qi-1]);
    else if (qBytes[qi-1] > size) {
        DPRINTF(AnnotateQ, "removing for resize of queue %s\n", q);
        add(OP_SIZE_QUEUE, FL_NONE, tc->contextId(), smi, qi, size);
        if (size <= 0) {
            qData[qi-1].clear();
            qSize[qi-1] = 0;
            qBytes[qi-1] = 0;
            return;
        }
        int need = qBytes[qi-1] - size;
        qBytes[qi-1] = size;
        while (need > 0) {
            int32_t tail_bytes = qData[qi-1].back()->data;
            if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
                dump(true);
                dumpKey();
                fatal("Queue %s had inconsistancy when doing size queue!\n", q);
            }
            if (tail_bytes > need) {
                qData[qi-1].back()->data -= need;
                need = 0;
            } else if (tail_bytes == need) {
                qData[qi-1].pop_back();
                qSize[qi-1]--;
                need = 0;
            } else {
                qData[qi-1].pop_back();
                qSize[qi-1]--;
                need -= tail_bytes;
            }
        }
    }
}

void
CPA::swAq(ThreadContext *tc)
{
    if (!enabled())
        return;

    char q[50];
    Arguments args(tc);
    uint64_t id = args[0];
    tc->getVirtProxy().readString(q, args[1], 50);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());
    int32_t size = args[2];

    int sysi = getSys(sys);
    int qi = getQ(sysi, q, id);
    if (qBytes[qi-1] != size) {
        DPRINTF(AnnotateQ, "Queue %s [%#x] has inconsintant size\n", q, id);
        //dump(true);
        //dumpKey();
        std::list<AnnDataPtr>::iterator ai = qData[qi-1].begin();
        int x = 0;
        while (ai != qData[qi-1].end()) {
            DPRINTF(AnnotateQ, "--Element %d size %d\n", x, (*ai)->data);
            ai++;
            x++;
        }

        warn("%d: Queue Assert: SW said there should be %d byte(s) in %s,"
                "however there are %d byte(s)\n",
            curTick(), size, q, qBytes[qi-1]);
        DPRINTF(AnnotateQ, "%d: Queue Assert: SW said there should be %d"
                " byte(s) in %s, however there are %d byte(s)\n",
            curTick(), size, q, qBytes[qi-1]);
    }
}

void
CPA::swLink(ThreadContext *tc)
{
    if (!enabled())
        return;

    char lsm[50];
    Arguments args(tc);
    tc->getVirtProxy().readString(lsm, args[0], 50);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());

    int sysi = getSys(sys);
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();
    int lsmi = getSm(sysi, lsm, args[1]);

    DPRINTF(Annotate, "Linking from %d to state machine %s(%d) [%#x]\n",
            smi, lsm, lsmi, args[1]);

    if (lnMap[lsmi])
        DPRINTF(Annotate, "LnMap already contains entry for %d of %d\n",
                lsmi, lnMap[lsmi]);
    assert(lnMap[lsmi] == 0);
    lnMap[lsmi] =  smi;

    add(OP_LINK, FL_NONE, tc->contextId(), smi, lsmi);

    if (!!args[2]) {
        char sm[50];
        tc->getVirtProxy().readString(sm, args[2], 50);
        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
    }
}

void
CPA::swIdentify(ThreadContext *tc)
{
    if (!enabled())
        return;

    Arguments args(tc);
    int sysi = getSys(tc->getSystemPtr());
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        return;
    int smi = smStack[sid].back();

    DPRINTFS(Annotate, tc->getSystemPtr(), "swIdentify: id %#X\n", args[0]);

    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, args[0]);
}

uint64_t
CPA::swGetId(ThreadContext *tc)
{
    if (!enabled())
        return 0;

    uint64_t id = ++conId;
    int sysi = getSys(tc->getSystemPtr());
    StackId sid = StackId(sysi, getFrame(tc));
    if (!smStack[sid].size())
        panic("swGetId called without a state machine stack!");
    int smi = smStack[sid].back();

    DPRINTFS(Annotate, tc->getSystemPtr(), "swGetId: id %#X\n", id);

    add(OP_IDENT, FL_NONE, tc->contextId(), smi, 0, id);
    return id;
}


void
CPA::swSyscallLink(ThreadContext  *tc)
{
    if (!enabled())
        return;

    char lsm[50];
    Arguments args(tc);
    tc->getVirtProxy().readString(lsm, args[0], 50);
    System *sys = tc->getSystemPtr();
    StringWrap name(sys->name());
    int sysi = getSys(sys);

    Id id = Id(lsm, getFrame(tc));
    StackId sid = StackId(sysi, getFrame(tc));

    if (!smStack[sid].size())
        return;

    int smi = smStack[sid].back();

    DPRINTF(Annotate, "Linking from %d to state machine %s(UNKNOWN)\n",
            smi, lsm);

    if (scLinks[sysi-1][id])
        DPRINTF(Annotate,
                "scLinks already contains entry for system %d %s[%x] of %d\n",
                sysi, lsm, getFrame(tc), scLinks[sysi-1][id]);
    assert(scLinks[sysi-1][id] == 0);
    scLinks[sysi-1][id] = add(OP_LINK, FL_NONE, tc->contextId(), smi, 0xFFFF);
    scLinks[sysi-1][id]->dump = false;

    if (!!args[1]) {
        char sm[50];
        tc->getVirtProxy().readString(sm, args[1], 50);
        doSwSmEnd(tc->getSystemPtr(), tc->contextId(), sm, getFrame(tc));
    }
}

CPA::AnnDataPtr
CPA::add(int t, int f, int c, int sm, int stq, int32_t d)
{
    AnnDataPtr an = std::make_shared<AnnotateData>();
    an->time = curTick();
    an->data = d;
    an->orig_data = d;
    an->op = t;
    an->flag = f;
    an->sm = sm;
    an->stq = stq;
    an->cpu = c;
    an->dump = true;

    data.push_back(an);

    DPRINTF(AnnotateVerbose, "Annotate: op: %d flags: 0x%x sm: %d state: %d time: %d, data: %d\n",
            an->op, an->flag, an->sm, an->stq, an->time, an->data);

    // Don't dump Links because we might be setting no-dump on it
    if (an->op != OP_LINK)
        dump(false);

    return an;
}

void
CPA::dumpKey()
{
    std::streampos curpos = osbin->tellp();
    ah.key_off = curpos;

    // Output the various state machines and their corresponding states
    *osbin << "# Automatically generated state machine descriptor file" << endl;

    *osbin << "sms = {}" << endl << endl;
    vector<string> state_machines;
    state_machines.resize(numSmt+1);

    // State machines, id -> states
    SCache::iterator i = smtCache.begin();
    while (i != smtCache.end()) {
        state_machines[i->second] = i->first;
        i++;
    }

    for (int x = 1; x < state_machines.size(); x++) {
        vector<string> states;
        states.resize(numSt[x-1]+1);
        assert(x-1 < stCache.size());
        SCache::iterator i = stCache[x-1].begin();
        while (i != stCache[x-1].end()) {
            states[i->second] = i->first;
            i++;
        }
        *osbin << "sms[\"" << state_machines[x] << "\"] = [\"NULL\"";
        for (int y = 1; y < states.size(); y++)
            *osbin << ", \"" << states[y] << "\"";
        *osbin << "]" << endl;
    }

    *osbin << endl << endl << endl;

    // state machine number -> system, name, id
    *osbin << "smNum = [\"NULL\"";
    for (int x = 0; x < smMap.size(); x++)
        *osbin << ", (" << smMap[x].first << ", \"" << smMap[x].second.first <<
            "\", " << smMap[x].second.second << ")";
    *osbin << "]" << endl;

    *osbin << endl << endl << endl;

    // Output the systems
    vector<string> systems;
    systems.resize(numSys+1);
    NameCache::iterator i2 = nameCache.begin();
    while (i2 != nameCache.end()) {
        systems[i2->second.second] = i2->second.first;
        i2++;
    }

    *osbin << "sysNum = [\"NULL\"";
    for (int x = 1; x < systems.size(); x++) {
        *osbin << ", \"" << systems[x] << "\"";
    }
    *osbin << "]" << endl;

    // queue number -> system, qname, qid
    *osbin << "queues = [\"NULL\"";
    for (int x = 0; x < qMap.size(); x++)
        *osbin << ", (" << qMap[x].first << ", \"" << qMap[x].second.first <<
            "\", " << qMap[x].second.second << ")";
    *osbin << "]" << endl;

    *osbin << "smComb = [s for s in [(i,r) for i in xrange(1,len(sysNum)) "
           << "for r in xrange (1,len(smNum))]]" << endl;
    ah.key_len = osbin->tellp() - curpos;

    // output index
    curpos = osbin->tellp();
    ah.idx_off = curpos;

    for (int x = 0; x < annotateIdx.size(); x++)
        osbin->write((char*)&annotateIdx[x], sizeof(uint64_t));
    ah.idx_len = osbin->tellp() - curpos;

    osbin->seekp(0);
    osbin->write((char*)&ah, sizeof(AnnotateHeader));
    osbin->flush();

}

void
CPA::dump(bool all)
{

    list<AnnDataPtr>::iterator i;

    i = data.begin();

    if (i == data.end())
        return;

    // Dump the data every
    if (!all && data.size() < 10000)
        return;

    DPRINTF(Annotate, "Writing %d\n", data.size());
    while (i != data.end()) {
        AnnDataPtr an = *i;

        // If we can't dump this record, hold here
        if (!an->dump && !all)
            break;

        ah.num_recs++;
        if (ah.num_recs % 100000 == 0)
            annotateIdx.push_back(osbin->tellp());


        osbin->write((char*)&(an->time), sizeof(an->time));
        osbin->write((char*)&(an->orig_data), sizeof(an->orig_data));
        osbin->write((char*)&(an->sm), sizeof(an->sm));
        osbin->write((char*)&(an->stq), sizeof(an->stq));
        osbin->write((char*)&(an->op), sizeof(an->op));
        osbin->write((char*)&(an->flag), sizeof(an->flag));
        osbin->write((char*)&(an->cpu), sizeof(an->cpu));
        i++;
    }
    if (data.begin() != i)
        data.erase(data.begin(), i);

    if (all)
        osbin->flush();
}

void
CPA::doQ(System *sys, int flags, int cpuid, int sm,
              string q, int qi, int count)
{
    qSize[qi-1]++;
    qBytes[qi-1] += count;
    if (qSize[qi-1] > 2501 || qBytes[qi-1] > 2000000000)
        warn("Queue %s is %d elements/%d bytes, "
                "maybe things aren't being removed?\n",
                q, qSize[qi-1], qBytes[qi-1]);
    if (flags & FL_QOPP)
        qData[qi-1].push_front(add(OP_QUEUE, flags, cpuid, sm, qi, count));
    else
        qData[qi-1].push_back(add(OP_QUEUE, flags, cpuid, sm, qi, count));
    DPRINTFS(AnnotateQ, sys, "Queing in queue %s size now %d/%d\n",
            q, qSize[qi-1], qBytes[qi-1]);
    assert(qSize[qi-1] >= 0);
    assert(qBytes[qi-1] >= 0);
}


void
CPA::doDq(System *sys, int flags, int cpuid, int sm,
               string q, int qi, int count)
{

    StringWrap name(sys->name());
    if (count == -1) {
        add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
        qData[qi-1].clear();
        qSize[qi-1] = 0;
        qBytes[qi-1] = 0;
        DPRINTF(AnnotateQ, "Dequeing all data in queue %s size now %d/%d\n",
                q, qSize[qi-1], qBytes[qi-1]);
        return;
    }

    assert(count > 0);
    if (qSize[qi-1] <= 0 || qBytes[qi-1] <= 0 || !qData[qi-1].size()) {
        dump(true);
        dumpKey();
        fatal("Queue %s dequing with no data available in queue!\n",
                q);
    }
    assert(qSize[qi-1] >= 0);
    assert(qBytes[qi-1] >= 0);
    assert(qData[qi-1].size());

    int32_t need = count;
    qBytes[qi-1] -= count;
    if (qBytes[qi-1] < 0) {
        dump(true);
        dumpKey();
        fatal("Queue %s dequing with no bytes available in queue!\n",
                q);
    }

    while (need > 0) {
        int32_t head_bytes = qData[qi-1].front()->data;
        if (qSize[qi-1] <= 0 || qBytes[qi-1] < 0) {
            dump(true);
            dumpKey();
            fatal("Queue %s dequing with nothing in queue!\n",
                q);
        }

        if (head_bytes > need) {
            qData[qi-1].front()->data -= need;
            need = 0;
        } else if (head_bytes == need) {
            qData[qi-1].pop_front();
            qSize[qi-1]--;
            need = 0;
        } else {
            qData[qi-1].pop_front();
            qSize[qi-1]--;
            need -= head_bytes;
        }
    }

    add(OP_DEQUEUE, flags, cpuid, sm, qi, count);
    DPRINTF(AnnotateQ, "Dequeing in queue %s size now %d/%d\n",
            q, qSize[qi-1], qBytes[qi-1]);
}



void
CPA::serialize(CheckpointOut &cp) const
{

    SERIALIZE_SCALAR(numSm);
    SERIALIZE_SCALAR(numSmt);
    arrayParamOut(os, "numSt", numSt);
    arrayParamOut(os, "numQ", numQ);
    SERIALIZE_SCALAR(numSys);
    SERIALIZE_SCALAR(numQs);
    SERIALIZE_SCALAR(conId);
    arrayParamOut(os, "qSize", qSize);
    arrayParamOut(os, "qSize", qSize);
    arrayParamOut(os, "qBytes", qBytes);

    SCache::iterator i;
    int x = 0, y = 0;

    // smtCache (SCache)
    x = 0;
    y = 0;
    i = smtCache.begin();
    while (i != smtCache.end()) {
        paramOut(os, csprintf("smtCache%d.str", x), i->first);
        paramOut(os, csprintf("smtCache%d.int", x), i->second);
        x++; i++;
    }

    // stCache  (StCache)
    for (x = 0; x < stCache.size(); x++) {
        i = stCache[x].begin();
        y = 0;
        while (i != stCache[x].end()) {
            paramOut(os, csprintf("stCache%d_%d.str", x, y), i->first);
            paramOut(os, csprintf("stCache%d_%d.int", x, y), i->second);
            y++; i++;
        }
    }

    // qCache (IdCache)
    IdHCache::iterator idi;
    for (x = 0; x < qCache.size(); x++) {
        idi = qCache[x].begin();
        y = 0;
        while (idi != qCache[x].end()) {
            paramOut(os, csprintf("qCache%d_%d.str", x, y), idi->first.first);
            paramOut(os, csprintf("qCache%d_%d.id", x, y), idi->first.second);
            paramOut(os, csprintf("qCache%d_%d.int", x, y), idi->second);
            y++; idi++;
        }
    }

    // smCache (IdCache)
    for (x = 0; x < smCache.size(); x++) {
        idi = smCache[x].begin();
        y = 0;
        paramOut(os, csprintf("smCache%d", x), smCache[x].size());
        while (idi != smCache[x].end()) {
            paramOut(os, csprintf("smCache%d_%d.str", x, y), idi->first.first);
            paramOut(os, csprintf("smCache%d_%d.id", x, y), idi->first.second);
            paramOut(os, csprintf("smCache%d_%d.int", x, y), idi->second);
            y++; idi++;
        }
    }

    // scLinks (ScCache) -- data not serialize


    // namecache (NameCache)
    NameCache::iterator ni;

    ni = nameCache.begin();
    x = 0;
    while (ni != nameCache.end()) {
        paramOut(os, csprintf("nameCache%d.name", x), ni->first->name());
        paramOut(os, csprintf("nameCache%d.str", x), ni->second.first);
        paramOut(os, csprintf("nameCache%d.int", x), ni->second.second);
        x++; ni++;
    }

    // smStack (SmStack)
    SmStack::iterator si;
    si = smStack.begin();
    x = 0;
    paramOut(os, "smStackIdCount", smStack.size());
    while (si != smStack.end()) {
        paramOut(os, csprintf("smStackId%d.sys", x), si->first.first);
        paramOut(os, csprintf("smStackId%d.frame", x), si->first.second);
        paramOut(os, csprintf("smStackId%d.count", x), si->second.size());
        for (y = 0; y < si->second.size(); y++)
            paramOut(os, csprintf("smStackId%d_%d", x, y), si->second[y]);
        x++; si++;
    }

    // lnMap (LinkMap)
    x = 0;
    LinkMap::iterator li;
    li = lnMap.begin();
    paramOut(os, "lnMapSize", lnMap.size());
    while (li != lnMap.end()) {
        paramOut(os, csprintf("lnMap%d.smi", x), li->first);
        paramOut(os, csprintf("lnMap%d.lsmi", x), li->second);
        x++; li++;
    }

    // swExpl (vector)
    SwExpl::iterator swexpli;
    swexpli = swExpl.begin();
    x = 0;
    paramOut(os, "swExplCount", swExpl.size());
    while (swexpli != swExpl.end()) {
        paramOut(os, csprintf("swExpl%d.sys", x), swexpli->first.first);
        paramOut(os, csprintf("swExpl%d.frame", x), swexpli->first.second);
        paramOut(os, csprintf("swExpl%d.swexpl", x), swexpli->second);
        x++; swexpli++;
    }

    // lastState (IMap)
    x = 0;
    IMap::iterator ii;
    ii = lastState.begin();
    paramOut(os, "lastStateSize", lastState.size());
    while (ii != lastState.end()) {
        paramOut(os, csprintf("lastState%d.smi", x), ii->first);
        paramOut(os, csprintf("lastState%d.sti", x), ii->second);
        x++; ii++;
    }

    // smMap (IdMap)
    for (x = 0; x < smMap.size(); x++) {
        paramOut(os, csprintf("smMap%d.sys", x), smMap[x].first);
        paramOut(os, csprintf("smMap%d.smname", x), smMap[x].second.first);
        paramOut(os, csprintf("smMap%d.id", x), smMap[x].second.second);
    }

    // qMap (IdMap)
    for (x = 0; x < qMap.size(); x++) {
        paramOut(os, csprintf("qMap%d.sys", x), qMap[x].first);
        paramOut(os, csprintf("qMap%d.qname", x), qMap[x].second.first);
        paramOut(os, csprintf("qMap%d.id", x), qMap[x].second.second);
    }

    // qData (vector<AnnotateList>)
    for (x = 0; x < qData.size(); x++) {
        if (!qData[x].size())
            continue;
        y = 0;
        for (auto &ann : qData[x]) {
            ann->serializeSection(os, csprintf("Q%d_%d", x, y));
            y++;
        }
    }
}

void
CPA::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(numSm);
    UNSERIALIZE_SCALAR(numSmt);
    UNSERIALIZE_CONTAINER(numSt);
    UNSERIALIZE_CONTAINER(numQ);
    UNSERIALIZE_SCALAR(numSys);
    UNSERIALIZE_SCALAR(numQs);
    UNSERIALIZE_SCALAR(conId);
    UNSERIALIZE_CONTAINER(qSize);
    UNSERIALIZE_CONTAINER(qBytes);


    // smtCache (SCache
    string str;
    int smi;
    for (int x = 0;  x < numSmt; x++) {
        paramIn(cp, csprintf("smtCache%d.str", x), str);
        paramIn(cp, csprintf("smtCache%d.int", x), smi);
        smtCache[str] = smi;
    }

    // stCache  (StCache)
    stCache.resize(numSmt);
    for (int x = 0;  x < numSmt; x++) {
        for (int y = 0; y < numSt[x]; y++) {
            paramIn(cp, csprintf("stCache%d_%d.str", x,y), str);
            paramIn(cp, csprintf("stCache%d_%d.int", x,y), smi);
            stCache[x][str] = smi;
        }
    }

    // qCache (IdCache)
    uint64_t id;
    qCache.resize(numSys);
    for (int x = 0;  x < numSys; x++) {
        for (int y = 0; y < numQ[x]; y++) {
            paramIn(cp, csprintf("qCache%d_%d.str", x,y), str);
            paramIn(cp, csprintf("qCache%d_%d.id", x,y), id);
            paramIn(cp, csprintf("qCache%d_%d.int", x,y), smi);
            qCache[x][Id(str,id)] = smi;
        }
    }

    // smCache (IdCache)
    smCache.resize(numSys);
    for (int x = 0;  x < numSys; x++) {
        int size;
        paramIn(cp, csprintf("smCache%d", x), size);
        for (int y = 0; y < size; y++) {
            paramIn(cp, csprintf("smCache%d_%d.str", x,y), str);
            paramIn(cp, csprintf("smCache%d_%d.id", x,y), id);
            paramIn(cp, csprintf("smCache%d_%d.int", x,y), smi);
            smCache[x][Id(str,id)] = smi;
        }
    }

    // scLinks (ScCache) -- data not serialized, just creating one per sys
    for (int x = 0; x < numSys; x++)
        scLinks.push_back(ScHCache());

    // nameCache (NameCache)
    for (int x = 0; x < numSys; x++) {
        System *sys;
        SimObject *sptr;
        string str;
        int sysi;

        objParamIn(cp, csprintf("nameCache%d.name", x), sptr);
        sys = dynamic_cast<System*>(sptr);

        paramIn(cp, csprintf("nameCache%d.str", x), str);
        paramIn(cp, csprintf("nameCache%d.int", x), sysi);
        nameCache[sys] = std::make_pair(str, sysi);
    }

    //smStack (SmStack)
    int smStack_size;
    paramIn(cp, "smStackIdCount", smStack_size);
    for (int x = 0; x < smStack_size; x++) {
        int sysi;
        uint64_t frame;
        int count;
        paramIn(cp, csprintf("smStackId%d.sys", x), sysi);
        paramIn(cp, csprintf("smStackId%d.frame", x), frame);
        paramIn(cp, csprintf("smStackId%d.count", x), count);
        StackId sid = StackId(sysi, frame);
        for (int y = 0; y < count; y++) {
            paramIn(cp, csprintf("smStackId%d_%d", x, y), smi);
            smStack[sid].push_back(smi);
        }
    }

    // lnMap (LinkMap)
    int lsmi;
    int lnMap_size;
    paramIn(cp, "lnMapSize", lnMap_size);
    for (int x = 0;  x < lnMap_size; x++) {
        paramIn(cp, csprintf("lnMap%d.smi", x), smi);
        paramIn(cp, csprintf("lnMap%d.lsmi", x), lsmi);
        lnMap[smi] = lsmi;
    }

    // swExpl (vector)
    int swExpl_size;
    paramIn(cp, "swExplCount", swExpl_size);
    for (int x = 0; x < swExpl_size; x++) {
        int sysi;
        uint64_t frame;
        bool b;
        paramIn(cp, csprintf("swExpl%d.sys", x), sysi);
        paramIn(cp, csprintf("swExpl%d.frame", x), frame);
        paramIn(cp, csprintf("swExpl%d.swexpl", x), b);
        StackId sid = StackId(sysi, frame);
        swExpl[sid] = b;
    }

    // lastState (IMap)
    int sti;
    int lastState_size;
    paramIn(cp, "lastStateSize", lastState_size);
    for (int x = 0;  x < lastState_size; x++) {
        paramIn(cp, csprintf("lastState%d.smi", x), smi);
        paramIn(cp, csprintf("lastState%d.sti", x), sti);
        lastState[smi] = sti;
    }


    //smMap (IdMap)
    smMap.resize(numSm);
    for (int x = 0; x < smMap.size(); x++) {
        paramIn(cp, csprintf("smMap%d.sys", x), smMap[x].first);
        paramIn(cp, csprintf("smMap%d.smname", x), smMap[x].second.first);
        paramIn(cp, csprintf("smMap%d.id", x), smMap[x].second.second);
    }

    //qMap (IdMap)
    qMap.resize(numQs);
    for (int x = 0; x < qMap.size(); x++) {
        paramIn(cp, csprintf("qMap%d.sys", x), qMap[x].first);
        paramIn(cp, csprintf("qMap%d.qname", x), qMap[x].second.first);
        paramIn(cp, csprintf("qMap%d.id", x), qMap[x].second.second);
    }


    // qData (vector<AnnotateList>)
    qData.resize(qSize.size());
    for (int x = 0; x < qSize.size(); x++) {
        if (!qSize[x])
            continue;
        for (int y = 0; y < qSize[x]; y++) {
            AnnDataPtr a = std::make_shared<AnnotateData>();
            a->unserializeSection(cp, csprintf("Q%d_%d", x, y));
            data.push_back(a);
            qData[x].push_back(a);
        }
    }
}

void
CPA::AnnotateData::serialize(CheckpointOut &cp) const
{
    SERIALIZE_SCALAR(time);
    SERIALIZE_SCALAR(data);
    SERIALIZE_SCALAR(sm);
    SERIALIZE_SCALAR(stq);
    SERIALIZE_SCALAR(op);
    SERIALIZE_SCALAR(flag);
    SERIALIZE_SCALAR(cpu);
}

void
CPA::AnnotateData::unserialize(CheckpointIn &cp)
{
    UNSERIALIZE_SCALAR(time);
    UNSERIALIZE_SCALAR(data);
    orig_data = data;
    UNSERIALIZE_SCALAR(sm);
    UNSERIALIZE_SCALAR(stq);
    UNSERIALIZE_SCALAR(op);
    UNSERIALIZE_SCALAR(flag);
    UNSERIALIZE_SCALAR(cpu);
    dump = true;
}

CPA*
CPAParams::create()
{
    return new CPA(this);
}

