]> Zhao Yanbai Git Server - minix.git/commitdiff
unstack, sort: cleanup and improvement
authorBen Gras <ben@minix3.org>
Wed, 26 Sep 2012 16:29:11 +0000 (18:29 +0200)
committerBen Gras <ben@minix3.org>
Wed, 26 Sep 2012 16:44:55 +0000 (18:44 +0200)
lets unstack
(a) know about in-kernel ipc entry points and
(b) be able handle >2GB symbol offsets.

. sort: add -x for hex numerical sort
. unstack: gnm is obsolete
. unstack: datasizes is obsolete (use nm --size-sort instead)
. unstack: add ipc entry points read from procfs (hex)
. unstack: use sort -x to sort symbol order so the procfs ones are
  sorted independent of position and original ordering

commands/sort/sort.c
commands/unstack/unstack.sh
man/man1/sort.1

index e8497d43345b9147a81a28cba8f8a6331a093fb4..5481d277932e536d256b6e1490b67230ff383034 100644 (file)
@@ -96,6 +96,7 @@ typedef struct {
   BOOL fold_case;
   BOOL ascii;
   BOOL numeric;
+  BOOL hexmode;
 } FIELD;
 
 /* Field declarations. A total of FILEDS_LIMIT is allowed */
@@ -150,6 +151,7 @@ char *skip_fields(char *str, int nf);
 int compare(char *el1, char *el2);
 int cmp(unsigned char *el1, unsigned char *el2, FIELD * field);
 int digits(char *str1, char *str2, BOOL check_sign);
+int hexits(char *str1, char *str2);
 void files_merge(int file_cnt);
 void merge(int start_file, int limit_file);
 void put_line(char *line);
@@ -250,6 +252,10 @@ register FIELD *field;
        field->numeric = TRUE;
        field->blanks = TRUE;
        break;
+      case 'x':
+       field->hexmode = TRUE;
+       field->blanks = TRUE;
+       break;
       case 'r':                        /* Reverse comparisons */
        field->reverse = TRUE;
        break;
@@ -761,6 +767,8 @@ FIELD *field;
   }
   if (field->numeric)          /* Compare numeric */
        return digits((char *) el1, (char *) el2, TRUE);
+  if (field->hexmode)          /* Compare hex */
+       return hexits((char *) el1, (char *) el2);
 
   for (;;) {
        while (*el1 == *el2) {
@@ -811,6 +819,24 @@ FIELD *field;
   /* NOTREACHED */
 }
 
+int hexits(char *str1, char *str2)
+{
+       unsigned long v1, v2;
+       int r1, r2;
+       r1 = sscanf(str1, "0x%lx", &v1);
+       r2 = sscanf(str2, "0x%lx", &v2);
+
+       /* ordering based on reasonable hex number */
+       if(r1 == 1 && r2 != 1) return HIGHER;
+       if(r1 != 1 && r2 == 1) return LOWER;
+       if(r1 != 1 && r2 != 1) return SAME;
+
+       if(v1 > v2) return HIGHER;
+       if(v1 < v2) return LOWER;
+
+       return SAME;
+}
+
 /*
  * Digits compares () the two strings that point to a number of digits followed
  * by an optional decimal point.
index bb781c624ab8e3d8f0d6158e264e3b1c2142b354..118913216108577f992459d0c2e25f5811c939b7 100644 (file)
@@ -3,17 +3,23 @@
 # Look at /usr/pkg/bin first in case there is an old nm in /usr/bin
 PATH=/usr/pkg/bin:$PATH:/usr/gnu/bin
 
+# Does procfs give us some extra 'symbols'?
+IPCVECS=/proc/ipcvecs
+if [ -f $IPCVECS ]
+then   EXTRANM="cat $IPCVECS"
+fi
+
 # Check usage
 if [ $# -lt 1 ]
 then   echo "Usage: unstack <executable> [0x... [0x... ] ]"
-       echo "       datasizes <executable>"
        exit 1
 fi
 
 # Check invocation mode
 case "`basename $0`" in
        datasizes)
-               mode=data
+               echo "datasizes is obsolete; please use nm --size-sort instead."
+               exit 1
                ;;
        unstack)
                mode=stack
@@ -28,46 +34,31 @@ esac
 executable=$1
 shift
 
-# gnu nm can be gnm or nm
-if which gnm >/dev/null 2>&1
-then   GNM=gnm
-else   GNM=nm
+if ! which gawk >/dev/null 2>&1
+then   echo "Please install gawk."
+       exit 1
 fi
 
-# Invoke gnu nm or ack nm?
-if file $executable | grep NSYM >/dev/null 2>&1
-then   NM="$GNM --radix=d"
-elif file $executable | grep ELF >/dev/null 2>&1
-then   NM="$GNM --radix=d"
-else   NM="acknm -d"
+# Invoke binutils nm or ack nm?
+if file $executable | grep ELF >/dev/null 2>&1
+then   NM="nm"
+else   NM="acknm"
 fi
 
-# Invoked as unstack?
-if [ $mode = stack ]
-then
-       while [ $# -gt 0 ]
-       do      dec="`printf %d $1`"
-               $NM -n $executable | grep ' [Tt] [^.]' | awk '
-                 {  if($1 > '$dec') { printf "%s+0x%x\n", name, '$dec'-offset; exit }
-                    name=$3; offset=$1
-                 }'
-               shift
-       done
+SYMLIST=/tmp/unstack.$$
 
-       exit 0
-fi
-
-# Invoked as datasizes?
-if [ $mode = data ]
-then
-       $NM -n $executable |
-               grep ' [bBdD] [^.]' | awk '{ if (lastpos) printf "%10ld kB  %s\n", ($1-lastpos)/1024, lastname; lastpos=$1; lastname=$3 }' | sort -n
+# store sorted, filtered nm output once
+( $NM $executable ; $EXTRANM ) | sed 's/^/0x/' | sort -x | grep ' [Tt] [^.]' >$SYMLIST
 
-       exit 0
-fi
+while [ $# -gt 0 ]
+do      gawk <$SYMLIST --non-decimal-data -v symoffset=$1 '
+         {  if($1 > symoffset) { printf "%s+0x%x\n", name, symoffset-prevoffset; exit }
+            name=$3; prevoffset=$1;
+         }'
+       shift
+done
 
-# Can't happen.
-echo "Impossible invocation."
+rm -f $SYMLIST
 
 exit 1
 
index 1bc30edd99c01379e3029b8468bfb3af8413a0ee..9d276ae9cd9a65844f3324df0163b498ec3df173 100644 (file)
@@ -35,7 +35,10 @@ sort \- sort a file of ASCII lines
 # Merge presorted files
 .TP 5
 .B \-n
-# Numeric sort order
+# Numeric sort order (decimal)
+.TP 5
+.B \-x
+# Numeric sort order (hex)
 .TP 5
 .B \-o
 # Next argument is output file