statetrace.cc revision 3115
11758SN/A/*
21762SN/A * Copyright (c) 2006 The Regents of The University of Michigan
31758SN/A * All rights reserved.
41758SN/A *
51758SN/A * Redistribution and use in source and binary forms, with or without
61758SN/A * modification, are permitted provided that the following conditions are
71758SN/A * met: redistributions of source code must retain the above copyright
81758SN/A * notice, this list of conditions and the following disclaimer;
91758SN/A * redistributions in binary form must reproduce the above copyright
101758SN/A * notice, this list of conditions and the following disclaimer in the
111758SN/A * documentation and/or other materials provided with the distribution;
121758SN/A * neither the name of the copyright holders nor the names of its
131758SN/A * contributors may be used to endorse or promote products derived from
141758SN/A * this software without specific prior written permission.
151758SN/A *
161758SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
171758SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
181758SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
191758SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
201758SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
211758SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
221758SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
231758SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241758SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
251758SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
261758SN/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 */
302665Ssaidi@eecs.umich.edu
311758SN/A#include <iostream>
322SN/A#include <fstream>
331147SN/A#include <string>
341147SN/A#include <sys/types.h>
352SN/A#include <sys/wait.h>
361858SN/A#include <sys/ptrace.h>
372107SN/A#include <unistd.h>
381858SN/A
395566Snate@binkert.org#include "tracechild.hh"
402107SN/A#include "printer.hh"
411858SN/A
421147SN/Ausing namespace std;
43924SN/A
441147SN/Avoid printUsage(const char * execName)
45924SN/A{
46924SN/A        cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
471147SN/A}
481147SN/A
491147SN/Aint main(int argc, char * argv[], char * envp[])
501147SN/A{
511147SN/A        TraceChild * child = genTraceChild();
521147SN/A        NestingPrinter printer(child);
531147SN/A        string args;
541147SN/A        int startProgramArgs;
55924SN/A
561858SN/A        //Parse the command line arguments
571147SN/A        bool formatStringSet = false;
581147SN/A        bool printInitial = false;
59924SN/A        bool printTrace = true;
601147SN/A        string format;
611147SN/A        for(int x = 1; x < argc; x++)
62924SN/A        {
631147SN/A                if(!strcmp(argv[x], "-f"))
641147SN/A                {
651147SN/A                        if(formatStringSet)
661147SN/A                        {
671147SN/A                                cerr << "Attempted to set format twice!"
681805SN/A                                        << endl;
691805SN/A                                printUsage(argv[0]);
701858SN/A                                return 1;
711805SN/A                        }
721805SN/A                        formatStringSet = true;
731805SN/A                        x++;
741805SN/A                        if(x >= argc)
751805SN/A                        {
761805SN/A                                cerr << "Incorrect usage.\n" << endl;
771805SN/A                                printUsage(argv[0]);
78924SN/A                                return 1;
791147SN/A                        }
801147SN/A                        ifstream formatFile(argv[x]);
811147SN/A                        if(!formatFile)
821147SN/A                        {
831147SN/A                                cerr << "Problem opening file "
841147SN/A                                        << argv[x] << "." << endl;
851147SN/A                                return 1;
861147SN/A                        }
871147SN/A                        format = "";
882SN/A                        while(formatFile)
891147SN/A                        {
901147SN/A                                string line;
911147SN/A                                getline(formatFile, line);
921147SN/A                                if(formatFile.eof())
931147SN/A                                {
941147SN/A                                        format += line;
951147SN/A                                        break;
961147SN/A                                }
972SN/A                                if(!formatFile)
981147SN/A                                {
992SN/A                                        cerr << "Problem reading from file "
1001147SN/A                                                << argv[x] << "." << endl;
1011147SN/A                                        return 1;
1021147SN/A                                }
1032SN/A                                format += line + '\n';
1041147SN/A                        }
1051147SN/A                }
1061147SN/A                else if(!strcmp(argv[x], "-h"))
1072SN/A                {
1081147SN/A                        printUsage(argv[0]);
1091147SN/A                        return 0;
1101147SN/A                }
1111147SN/A                else if(!strcmp(argv[x], "-r"))
1121147SN/A                {
1131147SN/A                        cout << "Legal register names:" << endl;
1141147SN/A                        int numRegs = child->getNumRegs();
1151147SN/A                        for(unsigned int x = 0; x < numRegs; x++)
1162SN/A                        {
1171147SN/A                                cout << "\t" << child->getRegName(x) << endl;
1181147SN/A                        }
1192SN/A                        return 0;
1205566Snate@binkert.org                }
1212SN/A                else if(!strcmp(argv[x], "-i"))
1221147SN/A                {
123                    printInitial = true;
124                }
125                else if(!strcmp(argv[x], "-nt"))
126                {
127                    printTrace = false;
128                }
129                else if(!strcmp(argv[x], "--"))
130                {
131                        x++;
132                        if(x >= argc)
133                        {
134                                cerr << "Incorrect usage.\n" << endl;
135                                printUsage(argv[0]);
136                                return 1;
137                        }
138                        startProgramArgs = x;
139                        break;
140                }
141                else
142                {
143                        cerr << "Incorrect usage.\n" << endl;
144                        printUsage(argv[0]);
145                        return 1;
146                }
147        }
148        for(unsigned int x = startProgramArgs; x < argc; x++)
149            args += argv[x];
150        if(!child->startTracing(argv[startProgramArgs], args.c_str()))
151        {
152                cerr << "Couldn't start target program" << endl;
153                return 1;
154        }
155        if(printInitial)
156        {
157            child->outputStartState(cout);
158        }
159        if(printTrace)
160        {
161            if(!formatStringSet)
162            {
163                    cerr << "No output format set!" << endl;
164                    child->stopTracing();
165                    printUsage(argv[0]);
166                    return 1;
167            }
168            if(!printer.configure(format))
169            {
170                    cerr << "Problem in the output format" << endl;
171                    child->stopTracing();
172                    return 1;
173            }
174            child->step();
175            while(child->isTracing())
176            {
177                    cout << printer;
178                    child->step();
179            }
180            cout << printer;
181        }
182        if(!child->stopTracing())
183        {
184                cerr << "Couldn't stop child" << endl;
185                return 1;
186        }
187        return 0;
188}
189
190