// Replay the image log.
// We run this before the each instruction of the code as an analysis routine.
// So we eat up the image loads one instruction at a time!
// We can also call it before PIN_StartProgram, to check that queuing
// the replay calls up works.
//
static void ReplayImageEntry()
{
    if (feof(imgLog))
        exit(0);

    char tag = fgetc(imgLog);
    switch (tag)
    {
        case 'L':
            {
                string imageName;
                ADDRINT offset;

                ParseImageLoadLine(imageName, &offset);
                if (KnobVerbose)
                    fprintf (trace, "Replaying load for %s\n", imageName.c_str());
                // And, finally, inform Pin that it is all there, which will invoke
                // image load callbacks.
                PIN_LockClient();
                // Tag the first image as the main program
                PIN_ReplayImageLoad(imageName.c_str(), imageName.c_str(), offset, replayedImageCount++==0);
                PIN_UnlockClient();

                break;
            }
        case 'U':
            {
                string imageName;
                ParseImageUnloadLine(imageName);
                
                IMG img = FindNamedImg(imageName);
                if (KnobVerbose)
                    fprintf (trace, "Replaying unload for %s\n", imageName.c_str());
                // And, finally, inform Pin that it has gone, which will invoke
                // image unload callbacks.
                PIN_LockClient();
                PIN_ReplayImageUnload(img);
                PIN_UnlockClient();
                break;
            }            
        default:
            fprintf (trace, "Unexpected line in log file starting with '%c'\n", tag);
            exit(0);
    }
}
// Replay the image log.
// We run this before the each instruction of the code as an analysis routine.
// So we eat up the image loads one instruction at a time!
// We can also call it before PIN_StartProgram, to check that queuing
// the replay calls up works.
//
static void ReplayImageEntry()
{
    if (feof(imgLog))
        return;

    char tag = fgetc(imgLog);
    switch (tag)
    {
        case 'L':
            {
                string imageName;
                ADDRINT startAddr;
                ADDRINT offset;
                USIZE size;
                BOOL mainExe;
                vector<RTN_INFO> rtns;

                ParseImageLoadLine(imageName, &startAddr, &size, &offset, &mainExe, &rtns);
                if (KnobVerbose)
                    fprintf (stderr, "Replaying load for %s, address: %llx offset: %llx, size: %lx\n", imageName.c_str(), (unsigned long long)startAddr, (unsigned long long)offset, (long)size);
                
                // Create a temporary IMG object
                IMG img = IMG_CreateAt(imageName.c_str(), startAddr, size, offset, mainExe);
                ASSERT(IMG_Valid(img), "IMG_CreateAt for " + imageName + " is invalid");

                // Populate the IMG object with recorded RTNs
                PIN_LockClient();

                for (vector<RTN_INFO>::iterator it = rtns.begin(); it < rtns.end(); it++)
                {
                    RTN rtn = RTN_CreateAt(it->startAddr, it->name);
                    ASSERT(RTN_Valid(rtn), "Failed to create RTN " + it->name + " at address " + hexstr(it->startAddr));
                }

                // And, finally, inform Pin that it is all there, which will invoke
                // image load callbacks.
                IMG_ReplayImageLoad(img);

                PIN_UnlockClient();
                break;
            }
        case 'U':
            {
                string imageName;
                ParseImageUnloadLine(imageName);
                
                IMG img = FindNamedImg(imageName);
                if (KnobVerbose)
                    fprintf (stderr, "Replaying unload for %s\n", imageName.c_str());
                // And, finally, inform Pin that it has gone, which will invoke
                // image unload callbacks.
                PIN_LockClient();
                PIN_ReplayImageUnload(img);
                PIN_UnlockClient();
                break;
            }            
        default:
            fprintf (trace, "Unexpected line in log file starting with '%c'\n", tag);
            exit(1);
    }
}