HPCToolkit
Args.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // $HeadURL$
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 //************************* System Include Files ****************************
61 
62 #include <iostream>
63 using std::cerr;
64 using std::endl;
65 
66 #include <string>
67 using std::string;
68 
69 #ifdef NO_STD_CHEADERS
70 # include <stdlib.h>
71 #else
72 # include <cstdlib>
73 using std::strtol; // For compatibility with non-std C headers
74 #endif
75 
76 #include <errno.h>
77 
78 //*************************** User Include Files ****************************
79 
80 #include <include/hpctoolkit-config.h>
81 
82 #include "Args.hpp"
83 
85 #include <lib/support/Trace.hpp>
86 
87 //*************************** Forward Declarations **************************
88 
89 // Cf. DIAG_Die.
90 #define ARG_ERROR(streamArgs) \
91  { std::ostringstream WeIrDnAmE; \
92  WeIrDnAmE << streamArgs /*<< std::ends*/; \
93  printError(std::cerr, WeIrDnAmE.str()); \
94  exit(1); }
95 
96 //***************************************************************************
97 
98 static const char* version_info = HPCTOOLKIT_VERSION_STRING;
99 
100 static const char* usage_summary =
101 "[options] <loadmodule>\n";
102 
103 static const char* usage_details = "\
104 Load module dump. Dumps selected contents of <loadmodule> to stdout.\n\
105 <loadmodule> may be either an executable or DSO.\n\
106 \n\
107 By default instruction types are emitted.\
108 \n\
109 Options:\n\
110  --long Long dump: include symbol table.\n\
111  --short Short dump: no instructions.\n\
112  --decode Decode instructions.\n\
113  --old Old symbolic dump.\n\
114  -l <addr>, load-addr <addr>\n\
115  'Load' DSOs at address <addr> rather than 0x0.\n\
116  Addresses may be in base 10, 8 (prefix '0') or 16\n\
117  (prefix '0x'). [NOT FULLY IMPLEMENTED]\n\
118  -V, --version Print version information.\n\
119  -h, --help Print this help.\n\
120  --debug [<n>] Debug: use debug level <n>. {1}\n";
121 
122 
123 
124 #define CLP CmdLineParser
125 
126 // Note: Changing the option name requires changing the name in Parse()
128 
129  // Options
130  { 0 , "long", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
131  { 0 , "short", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
132  { 0 , "decode", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
133  { 0 , "old", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
134 
135  { 'l', "load-addr", CLP::ARG_REQ , CLP::DUPOPT_CLOB, NULL, NULL },
136 
137  { 'V', "version", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
138  { 'h', "help", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
139  { 0 , "debug", CLP::ARG_OPT, CLP::DUPOPT_CLOB, NULL, CLP::isOptArg_long }, // hidden
140  CmdLineParser_OptArgDesc_NULL_MACRO // SGI's compiler requires this version
141 };
142 
143 #undef CLP
144 
145 
146 //***************************************************************************
147 // Args
148 //***************************************************************************
149 
151 {
152  Ctor();
153 }
154 
155 Args::Args(int argc, const char* const argv[])
156 {
157  Ctor();
158  parse(argc, argv);
159 }
160 
161 void
163 {
164  dumpLong = false;
165  dumpShort = false;
166  dumpDecode = false;
167  dumpOld = false;
168  loadVMA = 0x0;
169  debugLevel = 0;
170 }
171 
172 
174 {
175 }
176 
177 
178 void
179 Args::printVersion(std::ostream& os) const
180 {
181  os << getCmd() << ": " << version_info << endl;
182 }
183 
184 
185 void
186 Args::printUsage(std::ostream& os) const
187 {
188  os << "Usage: " << getCmd() << " " << usage_summary << endl
189  << usage_details << endl;
190 }
191 
192 
193 void
194 Args::printError(std::ostream& os, const char* msg) const
195 {
196  os << getCmd() << ": " << msg << endl
197  << "Try '" << getCmd() << " --help' for more information." << endl;
198 }
199 
200 void
201 Args::printError(std::ostream& os, const std::string& msg) const
202 {
203  printError(os, msg.c_str());
204 }
205 
206 
207 void
208 Args::parse(int argc, const char* const argv[])
209 {
210  try {
211 
212  // -------------------------------------------------------
213  // Parse the command line
214  // -------------------------------------------------------
215  parser.parse(optArgs, argc, argv);
216 
217  // -------------------------------------------------------
218  // Sift through results, checking for semantic errors
219  // -------------------------------------------------------
220 
221  // Special options that should be checked first
222  trace = debugLevel = 0;
223 
224  if (parser.isOpt("debug")) {
225  trace = debugLevel = 1;
226  if (parser.isOptArg("debug")) {
227  const string& arg = parser.getOptArg("debug");
228  trace = debugLevel = (int)CmdLineParser::toLong(arg);
229  }
230  }
231  if (parser.isOpt("help")) {
232  printUsage(std::cerr);
233  exit(1);
234  }
235  if (parser.isOpt("version")) {
236  printVersion(std::cerr);
237  exit(1);
238  }
239 
240  // Check for other options
241  int numDumpOptions = 0;
242  if (parser.isOpt("long")) {
243  dumpLong = true;
244  numDumpOptions++;
245  }
246  if (parser.isOpt("short")) {
247  dumpShort = true;
248  numDumpOptions++;
249  }
250  if (parser.isOpt("decode")) {
251  dumpDecode = true;
252  if (dumpShort) {
253  ARG_ERROR("--decode not valid with --short!");
254  }
255  }
256  if (parser.isOpt("old")) {
257  dumpOld = true;
258  numDumpOptions++;
259  }
260  if (numDumpOptions > 1) {
261  ARG_ERROR("At most one dump option may be given!");
262  }
263 
264  if (parser.isOpt("load-addr")) {
265  const string& arg = parser.getOptArg("load-addr");
267 
268 #if 0
269  errno = 0;
270  long l = strtol(str.c_str(), NULL, 0 /* base: dec, hex, or oct */);
271  if (l <= 0 || errno != 0) {
272  ARG_ERROR("Invalid address given to -r\n");
273  exit(1);
274  }
275  loadVMA = (VMA)l;
276 #endif
277  }
278 
279  // Check for required arguments
280  if (parser.getNumArgs() != 1) {
281  ARG_ERROR("Incorrect number of arguments!");
282  }
283  inputFile = parser.getArg(0);
284  }
285  catch (const CmdLineParser::ParseError& x) {
286  ARG_ERROR(x.what());
287  }
288  catch (const CmdLineParser::Exception& x) {
289  DIAG_EMsg(x.message());
290  exit(1);
291  }
292 }
293 
294 
295 void
296 Args::dump(std::ostream& os) const
297 {
298  os << "Args.cmd= " << getCmd() << endl;
299  os << "Args.debugLevel= " << debugLevel << endl;
300  os << "Args.inputFile= " << inputFile << endl;
301  os << "::trace " << ::trace << endl;
302 }
303 
304 void
305 Args::ddump() const
306 {
307  dump(std::cerr);
308 }
bool dumpLong
Definition: Args.hpp:105
bool dumpOld
Definition: Args.hpp:108
~Args()
Definition: Args.cpp:173
bool dumpDecode
Definition: Args.hpp:107
bool isOpt(const char swShort) const
void printUsage(std::ostream &os) const
Definition: Args.cpp:186
const std::string & getOptArg(const char swShort) const
bfd_vma VMA
Definition: ISATypes.hpp:79
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
virtual const std::string & what() const
Definition: Exception.hpp:126
static const char * version_info
Definition: Args.cpp:98
bool isOptArg(const char swShort) const
void Ctor()
Definition: Args.cpp:162
void parse(const OptArgDesc *optArgDescs, int argc, const char *const argv[])
CmdLineParser parser
Definition: Args.hpp:120
unsigned int getNumArgs() const
void printVersion(std::ostream &os) const
Definition: Args.cpp:179
void parse(int argc, const char *const argv[])
Definition: Args.cpp:208
virtual std::string message() const
Definition: Exception.hpp:134
exit
Definition: names.cpp:1
int debugLevel
Definition: Args.hpp:110
int trace
Definition: Trace.cpp:57
static const char * usage_summary
Definition: Args.cpp:100
std::string inputFile
Definition: Args.hpp:113
Args()
Definition: Args.cpp:150
void ddump() const
Definition: Args.cpp:305
#define CmdLineParser_OptArgDesc_NULL_MACRO
bool dumpShort
Definition: Args.hpp:106
void printError(std::ostream &os, const char *msg) const
Definition: Args.cpp:194
VMA loadVMA
Definition: Args.hpp:109
static CmdLineParser::OptArgDesc optArgs[]
Definition: Args.hpp:119
const std::string & getArg(unsigned int i) const
#define NULL
Definition: ElfHelper.cpp:85
#define ARG_ERROR(streamArgs)
Definition: Args.cpp:90
const std::string & getCmd() const
Definition: Args.hpp:102
void dump(std::ostream &os=std::cerr) const
Definition: Args.cpp:296
static const char * usage_details
Definition: Args.cpp:103
static long toLong(const std::string &str)