[PATCH] Fix operf to read unit mask in hex and document unit mask spec requirements

This patch has been pushed upstream, but review comments are welcome.

Signed-off-by: Maynard Johnson <maynardj@us.ibm.com>
---
 doc/operf.1.in         |   15 ++++++++++++++-
 doc/oprofile.xml       |   17 +++++++++++++----
 pe_profiling/operf.cpp |    5 +++--
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/doc/operf.1.in b/doc/operf.1.in
index b4f6376..7bbb0c6 100644
--- a/doc/operf.1.in
+++ b/doc/operf.1.in
@@ -121,10 +121,23 @@ for profiling. Each event spec is of the form:
 .br
 .I "   name:count[:unitmask[:kernel[:user]]]"
 .br
+When specifying a unit mask value, it may be either a hexadecimal value (which
+.I must
+begin with "0x") or a string (i.e, symbolic name) which matches the first word in
+the unit mask description. Specifying a symbolic name for the unit mask is valid only
+for unit masks having "extra:" parameters, as shown by the output of
+.B ophelp.
+Unit masks with "extra:" parameters
+.I must
+be specified using the symbolic name.
+.P
+.RS
 When no event specification is given, the default event for the running
-processor type will be used for profiling.  Use
+processor type will be used for profiling.
+Use
 .BI ophelp
 to list the available events for your processor type.
+.RE
 .br
 .TP
 .BI "--separate-thread / -t"
diff --git a/doc/oprofile.xml b/doc/oprofile.xml
index 2a1ef4d..9cd8c7a 100644
--- a/doc/oprofile.xml
+++ b/doc/oprofile.xml
@@ -1046,10 +1046,11 @@ The event specification is a colon-separated string of the form
 as described in the table below.
 </para>
 <para>
-If no event specs are passed to <command>operf</command>, it will use the default
-event for profiling. With <command>opcontrol</command>, if you want to
-revert to the default event, use <option>--event=default</option>. Use of this
-option overrides all previous event selections that have been cached.
+If no event specs are passed to <command>operf</command> or <command>opcontrol</command>,
+the default event will be used for profiling. With <command>opcontrol</command>, if you have
+previously specified some non-default event but want to revert to the default event, use
+<option>--event=default</option>. Use of this option overrides all previous event selections
+that have been cached.
 </para>
 <para>
 <note>OProfile will allocate hardware counters as necessary, but some processor
@@ -1077,6 +1078,14 @@ The last three values are optional, if you omit them (e.g. <option>--event=DATA_
 they will be set to the default values (a unit mask of 0, and profiling both kernel and
 userspace code). Note that some events require a unit mask.
 </para>
+<para>
+When specifying a unit mask value, it may be either a hexadecimal value (which
+<emphasis>must</emphasis> begin with "0x") or a string (i.e, symbolic name) which matches
+the first word in the unit mask description. Specifying a symbolic name for
+the unit mask is valid only for unit masks having "extra:" parameters, as
+shown by the output of <command>ophelp</command>.  Unit masks with "extra:" parameters must be
+specified using the symbolic name.
+</para>
 <note><para>
 When using legacy mode <command>opcontrol</command> on PowerPC platforms, all events specified must be in the same group;
 i.e., the group number appended to the event name (e.g. <constant>&lt;<emphasis>some-event-name</emphasis>&gt;_GRP9
diff --git a/pe_profiling/operf.cpp b/pe_profiling/operf.cpp
index 33aabac..a8f41a7 100644
--- a/pe_profiling/operf.cpp
+++ b/pe_profiling/operf.cpp
@@ -1064,7 +1064,8 @@ static void _process_events_list(void)
 		while ((info = strtok(NULL, ":"))) {
 			switch (place) {
 			case _OP_UM:
-				event.evt_um = atoi(info);
+				event.evt_um = strtoul(info, NULL, 0);
+				cerr << "strtoul of UM is " << hex << event.evt_um << endl;
 				break;
 			case _OP_KERNEL:
 				if (atoi(info) == 0)
@@ -1373,7 +1374,7 @@ static int _process_operf_and_app_args(int argc, char * const argv[])
 			break;
 		case 'p':
 			operf_options::pid = strtol(optarg, &endptr, 10);
-			if (endptr == optarg)
+			if ((endptr >= optarg) && (endptr <= (optarg + strlen(optarg) - 1)))
 				__print_usage_and_exit("operf: Invalid numeric value for --pid option.");
 			break;
 		case 'e':
-- 
1.6.2.rc2