statetrace.cc revision 7414
12207SN/A/*
22207SN/A * Copyright (c) 2006-2007 The Regents of The University of Michigan
32207SN/A * All rights reserved.
42207SN/A *
52207SN/A * Redistribution and use in source and binary forms, with or without
62207SN/A * modification, are permitted provided that the following conditions are
72207SN/A * met: redistributions of source code must retain the above copyright
82207SN/A * notice, this list of conditions and the following disclaimer;
92207SN/A * redistributions in binary form must reproduce the above copyright
102207SN/A * notice, this list of conditions and the following disclaimer in the
112207SN/A * documentation and/or other materials provided with the distribution;
122207SN/A * neither the name of the copyright holders nor the names of its
132207SN/A * contributors may be used to endorse or promote products derived from
142207SN/A * this software without specific prior written permission.
152207SN/A *
162207SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172207SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182207SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192207SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202207SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212207SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222207SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232207SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242207SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252207SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262207SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Gabe Black
292665Ssaidi@eecs.umich.edu */
302207SN/A
312207SN/A#include <cstring>
3211793Sbrandon.potter@amd.com#include <errno.h>
3311793Sbrandon.potter@amd.com#include <fstream>
342972Sgblack@eecs.umich.edu#include <iostream>
358229Snate@binkert.org#include <netdb.h>
362454SN/A#include <netinet/in.h>
372454SN/A#include <stdio.h>
382680Sktlim@umich.edu#include <string>
398232Snate@binkert.org#include <sys/ptrace.h>
405759Shsul@eecs.umich.edu#include <sys/socket.h>
4111854Sbrandon.potter@amd.com#include <sys/types.h>
427678Sgblack@eecs.umich.edu#include <sys/wait.h>
435759Shsul@eecs.umich.edu#include <unistd.h>
4411800Sbrandon.potter@amd.com
452474SN/A#include "printer.hh"
462207SN/A#include "tracechild.hh"
472474SN/A
482474SN/Ausing namespace std;
492474SN/A
5011851Sbrandon.potter@amd.comvoid printUsage(const char * execName)
5111851Sbrandon.potter@amd.com{
522474SN/A    cout << execName << " <options> -- <command> <arguments>" << endl;
532474SN/A    cout << "options:" << endl;
5410318Sandreas.hansson@arm.com    cout << "         -h          print this help" << endl;
552474SN/A    cout << "         --host      remote m5 host to connect to" << endl;
562474SN/A    cout << "         -r          print register names" << endl;
572474SN/A    cout << "         -i          print initial stack state" << endl;
582474SN/A    cout << "         -nt         don't print an instruction trace" << endl;
592474SN/A}
602474SN/A
612474SN/Aint main(int argc, char * argv[], char * envp[])
6211386Ssteve.reinhardt@amd.com{
632474SN/A    TraceChild * child = genTraceChild();
642474SN/A    string args;
652474SN/A    int startProgramArgs;
662474SN/A
672474SN/A    //Parse the command line arguments
682474SN/A    bool printInitial = false;
692474SN/A    bool printTrace = true;
7011851Sbrandon.potter@amd.com    string host = "localhost";
715759Shsul@eecs.umich.edu
7211389Sbrandon.potter@amd.com    if (argc == 1) {
7311389Sbrandon.potter@amd.com        printUsage(argv[0]);
7411389Sbrandon.potter@amd.com        return 0;
755759Shsul@eecs.umich.edu    }
765759Shsul@eecs.umich.edu    for(int x = 1; x < argc; x++)
775771Shsul@eecs.umich.edu    {
785759Shsul@eecs.umich.edu        if(!strcmp(argv[x], "-h"))
795759Shsul@eecs.umich.edu        {
805759Shsul@eecs.umich.edu            printUsage(argv[0]);
8111321Ssteve.reinhardt@amd.com            return 0;
825759Shsul@eecs.umich.edu        }
8311320Ssteve.reinhardt@amd.com        if(!strcmp(argv[x], "--host"))
845759Shsul@eecs.umich.edu        {
855759Shsul@eecs.umich.edu            x++;
865759Shsul@eecs.umich.edu            if(x >= argc)
875759Shsul@eecs.umich.edu            {
885759Shsul@eecs.umich.edu                cerr << "Incorrect usage.\n" << endl;
895759Shsul@eecs.umich.edu                printUsage(argv[0]);
905759Shsul@eecs.umich.edu                return 1;
9110318Sandreas.hansson@arm.com            }
925759Shsul@eecs.umich.edu            host = argv[x];
935759Shsul@eecs.umich.edu        }
945759Shsul@eecs.umich.edu        else if(!strcmp(argv[x], "-r"))
955759Shsul@eecs.umich.edu        {
9611389Sbrandon.potter@amd.com            cout << "Legal register names:" << endl;
9711389Sbrandon.potter@amd.com            int numRegs = child->getNumRegs();
9811389Sbrandon.potter@amd.com            for(unsigned int x = 0; x < numRegs; x++)
9911389Sbrandon.potter@amd.com            {
1005759Shsul@eecs.umich.edu                cout << "\t" << child->getRegName(x) << endl;
1015759Shsul@eecs.umich.edu            }
1025759Shsul@eecs.umich.edu            return 0;
1035759Shsul@eecs.umich.edu        }
1045759Shsul@eecs.umich.edu        else if(!strcmp(argv[x], "-i"))
1055759Shsul@eecs.umich.edu        {
1065759Shsul@eecs.umich.edu            printInitial = true;
1075759Shsul@eecs.umich.edu        }
1085759Shsul@eecs.umich.edu        else if(!strcmp(argv[x], "-nt"))
1095759Shsul@eecs.umich.edu        {
1105759Shsul@eecs.umich.edu            printTrace = false;
1115759Shsul@eecs.umich.edu        }
1125759Shsul@eecs.umich.edu        else if(!strcmp(argv[x], "--"))
1135759Shsul@eecs.umich.edu        {
1146227Snate@binkert.org            x++;
1155759Shsul@eecs.umich.edu            if(x >= argc)
1165759Shsul@eecs.umich.edu            {
1175759Shsul@eecs.umich.edu                cerr << "Incorrect usage.\n" << endl;
1186227Snate@binkert.org                printUsage(argv[0]);
1195759Shsul@eecs.umich.edu                return 1;
1205759Shsul@eecs.umich.edu            }
1215759Shsul@eecs.umich.edu            startProgramArgs = x;
1225759Shsul@eecs.umich.edu            break;
12311320Ssteve.reinhardt@amd.com        }
12411320Ssteve.reinhardt@amd.com        else
1255759Shsul@eecs.umich.edu        {
12611320Ssteve.reinhardt@amd.com            cerr << "Incorrect usage.\n" << endl;
1275759Shsul@eecs.umich.edu            printUsage(argv[0]);
1285759Shsul@eecs.umich.edu            return 1;
1295759Shsul@eecs.umich.edu        }
1305759Shsul@eecs.umich.edu    }
1315759Shsul@eecs.umich.edu    if(!child->startTracing(argv[startProgramArgs],
1325759Shsul@eecs.umich.edu                argv + startProgramArgs))
1335759Shsul@eecs.umich.edu    {
1345759Shsul@eecs.umich.edu        cerr << "Couldn't start target program" << endl;
1355759Shsul@eecs.umich.edu        return 1;
1365759Shsul@eecs.umich.edu    }
1375759Shsul@eecs.umich.edu    child->step();
1388601Ssteve.reinhardt@amd.com    if(printInitial)
1395759Shsul@eecs.umich.edu    {
1405759Shsul@eecs.umich.edu        child->outputStartState(cout);
1415759Shsul@eecs.umich.edu    }
1425759Shsul@eecs.umich.edu    if(printTrace)
1435759Shsul@eecs.umich.edu    {
1445759Shsul@eecs.umich.edu        // Connect to m5
1455759Shsul@eecs.umich.edu        bool portSet = false;
1465759Shsul@eecs.umich.edu        int port;
1475759Shsul@eecs.umich.edu        int sock = socket(AF_INET, SOCK_STREAM, 0);
1485759Shsul@eecs.umich.edu        if(sock < 0)
1495759Shsul@eecs.umich.edu        {
1505759Shsul@eecs.umich.edu            cerr << "Error opening socket! " << strerror(errno) << endl;
1515759Shsul@eecs.umich.edu            return 1;
1525759Shsul@eecs.umich.edu        }
1535759Shsul@eecs.umich.edu        struct hostent *server;
1545759Shsul@eecs.umich.edu        server = gethostbyname(host.c_str());
1555759Shsul@eecs.umich.edu        if(!server)
1568852Sandreas.hansson@arm.com        {
1575759Shsul@eecs.umich.edu            cerr << "Couldn't get host ip! " << strerror(errno) << endl;
1585759Shsul@eecs.umich.edu            return 1;
1595759Shsul@eecs.umich.edu        }
1605759Shsul@eecs.umich.edu        struct sockaddr_in serv_addr;
1615759Shsul@eecs.umich.edu        bzero((char *)&serv_addr, sizeof(serv_addr));
1626227Snate@binkert.org        serv_addr.sin_family = AF_INET;
1638852Sandreas.hansson@arm.com        bcopy((char *)server->h_addr,
1645759Shsul@eecs.umich.edu                (char *)&serv_addr.sin_addr.s_addr,
1658852Sandreas.hansson@arm.com                server->h_length);
1665759Shsul@eecs.umich.edu        serv_addr.sin_port = htons(8000);
1675759Shsul@eecs.umich.edu        if(connect(sock, (sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
1685759Shsul@eecs.umich.edu        {
1695759Shsul@eecs.umich.edu            cerr << "Couldn't connect to server! " << strerror(errno) << endl;
1705759Shsul@eecs.umich.edu            return 1;
1715958Sgblack@eecs.umich.edu        }
1725958Sgblack@eecs.umich.edu        while(child->isTracing())
1735759Shsul@eecs.umich.edu        {
1745759Shsul@eecs.umich.edu                if(!child->sendState(sock))
17511389Sbrandon.potter@amd.com                    break;
1765759Shsul@eecs.umich.edu                child->step();
1775759Shsul@eecs.umich.edu        }
1785759Shsul@eecs.umich.edu    }
17911851Sbrandon.potter@amd.com    if(!child->stopTracing())
1802474SN/A    {
1816820SLisa.Hsu@amd.com            cerr << "Couldn't stop child" << endl;
18211801Sbrandon.potter@amd.com            return 1;
1837532Ssteve.reinhardt@amd.com    }
1846820SLisa.Hsu@amd.com    return 0;
1855183Ssaidi@eecs.umich.edu}
1867532Ssteve.reinhardt@amd.com
18711851Sbrandon.potter@amd.com