unstack, sort: cleanup and improvement
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
This commit is contained in:
parent
2cdbb3041d
commit
c595699ca7
3 changed files with 56 additions and 36 deletions
|
@ -96,6 +96,7 @@ typedef struct {
|
||||||
BOOL fold_case;
|
BOOL fold_case;
|
||||||
BOOL ascii;
|
BOOL ascii;
|
||||||
BOOL numeric;
|
BOOL numeric;
|
||||||
|
BOOL hexmode;
|
||||||
} FIELD;
|
} FIELD;
|
||||||
|
|
||||||
/* Field declarations. A total of FILEDS_LIMIT is allowed */
|
/* 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 compare(char *el1, char *el2);
|
||||||
int cmp(unsigned char *el1, unsigned char *el2, FIELD * field);
|
int cmp(unsigned char *el1, unsigned char *el2, FIELD * field);
|
||||||
int digits(char *str1, char *str2, BOOL check_sign);
|
int digits(char *str1, char *str2, BOOL check_sign);
|
||||||
|
int hexits(char *str1, char *str2);
|
||||||
void files_merge(int file_cnt);
|
void files_merge(int file_cnt);
|
||||||
void merge(int start_file, int limit_file);
|
void merge(int start_file, int limit_file);
|
||||||
void put_line(char *line);
|
void put_line(char *line);
|
||||||
|
@ -250,6 +252,10 @@ register FIELD *field;
|
||||||
field->numeric = TRUE;
|
field->numeric = TRUE;
|
||||||
field->blanks = TRUE;
|
field->blanks = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
field->hexmode = TRUE;
|
||||||
|
field->blanks = TRUE;
|
||||||
|
break;
|
||||||
case 'r': /* Reverse comparisons */
|
case 'r': /* Reverse comparisons */
|
||||||
field->reverse = TRUE;
|
field->reverse = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -761,6 +767,8 @@ FIELD *field;
|
||||||
}
|
}
|
||||||
if (field->numeric) /* Compare numeric */
|
if (field->numeric) /* Compare numeric */
|
||||||
return digits((char *) el1, (char *) el2, TRUE);
|
return digits((char *) el1, (char *) el2, TRUE);
|
||||||
|
if (field->hexmode) /* Compare hex */
|
||||||
|
return hexits((char *) el1, (char *) el2);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (*el1 == *el2) {
|
while (*el1 == *el2) {
|
||||||
|
@ -811,6 +819,24 @@ FIELD *field;
|
||||||
/* NOTREACHED */
|
/* 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
|
* Digits compares () the two strings that point to a number of digits followed
|
||||||
* by an optional decimal point.
|
* by an optional decimal point.
|
||||||
|
|
|
@ -3,17 +3,23 @@
|
||||||
# Look at /usr/pkg/bin first in case there is an old nm in /usr/bin
|
# Look at /usr/pkg/bin first in case there is an old nm in /usr/bin
|
||||||
PATH=/usr/pkg/bin:$PATH:/usr/gnu/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
|
# Check usage
|
||||||
if [ $# -lt 1 ]
|
if [ $# -lt 1 ]
|
||||||
then echo "Usage: unstack <executable> [0x... [0x... ] ]"
|
then echo "Usage: unstack <executable> [0x... [0x... ] ]"
|
||||||
echo " datasizes <executable>"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check invocation mode
|
# Check invocation mode
|
||||||
case "`basename $0`" in
|
case "`basename $0`" in
|
||||||
datasizes)
|
datasizes)
|
||||||
mode=data
|
echo "datasizes is obsolete; please use nm --size-sort instead."
|
||||||
|
exit 1
|
||||||
;;
|
;;
|
||||||
unstack)
|
unstack)
|
||||||
mode=stack
|
mode=stack
|
||||||
|
@ -28,46 +34,31 @@ esac
|
||||||
executable=$1
|
executable=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
# gnu nm can be gnm or nm
|
if ! which gawk >/dev/null 2>&1
|
||||||
if which gnm >/dev/null 2>&1
|
then echo "Please install gawk."
|
||||||
then GNM=gnm
|
exit 1
|
||||||
else GNM=nm
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Invoke gnu nm or ack nm?
|
# Invoke binutils nm or ack nm?
|
||||||
if file $executable | grep NSYM >/dev/null 2>&1
|
if file $executable | grep ELF >/dev/null 2>&1
|
||||||
then NM="$GNM --radix=d"
|
then NM="nm"
|
||||||
elif file $executable | grep ELF >/dev/null 2>&1
|
else NM="acknm"
|
||||||
then NM="$GNM --radix=d"
|
|
||||||
else NM="acknm -d"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Invoked as unstack?
|
SYMLIST=/tmp/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
|
|
||||||
|
|
||||||
exit 0
|
# store sorted, filtered nm output once
|
||||||
fi
|
( $NM $executable ; $EXTRANM ) | sed 's/^/0x/' | sort -x | grep ' [Tt] [^.]' >$SYMLIST
|
||||||
|
|
||||||
# Invoked as datasizes?
|
while [ $# -gt 0 ]
|
||||||
if [ $mode = data ]
|
do gawk <$SYMLIST --non-decimal-data -v symoffset=$1 '
|
||||||
then
|
{ if($1 > symoffset) { printf "%s+0x%x\n", name, symoffset-prevoffset; exit }
|
||||||
$NM -n $executable |
|
name=$3; prevoffset=$1;
|
||||||
grep ' [bBdD] [^.]' | awk '{ if (lastpos) printf "%10ld kB %s\n", ($1-lastpos)/1024, lastname; lastpos=$1; lastname=$3 }' | sort -n
|
}'
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
exit 0
|
rm -f $SYMLIST
|
||||||
fi
|
|
||||||
|
|
||||||
# Can't happen.
|
|
||||||
echo "Impossible invocation."
|
|
||||||
|
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,10 @@ sort \- sort a file of ASCII lines
|
||||||
# Merge presorted files
|
# Merge presorted files
|
||||||
.TP 5
|
.TP 5
|
||||||
.B \-n
|
.B \-n
|
||||||
# Numeric sort order
|
# Numeric sort order (decimal)
|
||||||
|
.TP 5
|
||||||
|
.B \-x
|
||||||
|
# Numeric sort order (hex)
|
||||||
.TP 5
|
.TP 5
|
||||||
.B \-o
|
.B \-o
|
||||||
# Next argument is output file
|
# Next argument is output file
|
||||||
|
|
Loading…
Reference in a new issue