Merge zizzer:/bk/newmem
[gem5.git] / util / statetrace / statetrace.cc
1 /*
2 * Copyright (c) 2006-2007 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Gabe Black
29 */
30
31 #include <iostream>
32 #include <fstream>
33 #include <string>
34 #include <sys/types.h>
35 #include <sys/wait.h>
36 #include <sys/ptrace.h>
37 #include <unistd.h>
38
39 #include "tracechild.hh"
40 #include "printer.hh"
41
42 using namespace std;
43
44 void printUsage(const char * execName)
45 {
46 cout << execName << " -f <output format file> | -h | -r -- <command> <arguments>" << endl;
47 }
48
49 int main(int argc, char * argv[], char * envp[])
50 {
51 TraceChild * child = genTraceChild();
52 NestingPrinter printer(child);
53 string args;
54 int startProgramArgs;
55
56 //Parse the command line arguments
57 bool formatStringSet = false;
58 bool printInitial = false;
59 bool printTrace = true;
60 string format;
61 for(int x = 1; x < argc; x++)
62 {
63 if(!strcmp(argv[x], "-f"))
64 {
65 if(formatStringSet)
66 {
67 cerr << "Attempted to set format twice!"
68 << endl;
69 printUsage(argv[0]);
70 return 1;
71 }
72 formatStringSet = true;
73 x++;
74 if(x >= argc)
75 {
76 cerr << "Incorrect usage.\n" << endl;
77 printUsage(argv[0]);
78 return 1;
79 }
80 ifstream formatFile(argv[x]);
81 if(!formatFile)
82 {
83 cerr << "Problem opening file "
84 << argv[x] << "." << endl;
85 return 1;
86 }
87 format = "";
88 while(formatFile)
89 {
90 string line;
91 getline(formatFile, line);
92 if(formatFile.eof())
93 {
94 format += line;
95 break;
96 }
97 if(!formatFile)
98 {
99 cerr << "Problem reading from file "
100 << argv[x] << "." << endl;
101 return 1;
102 }
103 format += line + '\n';
104 }
105 }
106 else if(!strcmp(argv[x], "-h"))
107 {
108 printUsage(argv[0]);
109 return 0;
110 }
111 else if(!strcmp(argv[x], "-r"))
112 {
113 cout << "Legal register names:" << endl;
114 int numRegs = child->getNumRegs();
115 for(unsigned int x = 0; x < numRegs; x++)
116 {
117 cout << "\t" << child->getRegName(x) << endl;
118 }
119 return 0;
120 }
121 else if(!strcmp(argv[x], "-i"))
122 {
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 {
150 cout << "Adding argument " << argv[x];
151 args += string(" ") + argv[x];
152 }*/
153 if(!child->startTracing(argv[startProgramArgs],
154 argv + startProgramArgs))
155 {
156 cerr << "Couldn't start target program" << endl;
157 return 1;
158 }
159 if(printInitial)
160 {
161 child->outputStartState(cout);
162 }
163 if(printTrace)
164 {
165 if(!formatStringSet)
166 {
167 cerr << "No output format set!" << endl;
168 child->stopTracing();
169 printUsage(argv[0]);
170 return 1;
171 }
172 if(!printer.configure(format))
173 {
174 cerr << "Problem in the output format" << endl;
175 child->stopTracing();
176 return 1;
177 }
178 child->step();
179 while(child->isTracing())
180 {
181 cout << printer;
182 child->step();
183 }
184 cout << printer;
185 }
186 if(!child->stopTracing())
187 {
188 cerr << "Couldn't stop child" << endl;
189 return 1;
190 }
191 return 0;
192 }
193