nlist() in perl

Tom Christiansen tchrist at convexe.uucp
Wed Nov 8 17:12:52 AEST 1989


Here's an nlist() function in perl.  I'm not entirely sure
what someone would use it for, since perl is optimized for
processing of text not binary data, but someone asked for 
it, so here it is, along with a test program as a wrapper.
Read the comments for details.  Requires version 3 of perl.
It calls 'nm -p' and expects a certain output from that command.

--tom

#!/usr/local/bin/perl
#
# sample nlist wrapper program

@nlist = ('_get.*', 'bogus', '_read', '.*exit');

for $file (@ARGV) {
    %nlist = &nlist($file, at nlist);
    @nlist = keys %nlist;
    if ($#nlist < $[) {
	printf stderr "nlist on %s failed\n", $file;
	next;
    } 
    foreach $symbol (sort @nlist) {
	printf "%s: %-25s @ %08x\n", $file, $symbol, $nlist{$symbol};
    }
}
exit 0;

###########################################################################
# cut here and place in 'nlist.pl' 
#
# nlist()
#
# written by Tom Christiansen <tchrist at convex.com>
#	     7 November 1989
#
#
#   passed a binary name to run nm on and a list of symbols you're
#   interested in (actually rexprs) and returning an associative array of
#   whose keys are the names of what rexprs matches and whose values are
#   the symbols' addresses.  if you don't pass it any symbol rexprs, you
#   get them all.  
#
# examples:
#    %nlist = &nlist($file, at nlist);
#    %nlist = &nlist($file, '_get.*', 'bogus', '_read', '.*exit');
#    %nlist = &nlist($file);
#
# warning: your nm may have a differently formatted output than 
#	   this routine expects, which is something like this:
#
#		80007188  D __ctype_
#	   
#          this is NOT recommended for kernel lookups, as they
#          take a LONG time to load due to the number of symbols,
#	   and your program space can swell tremendously if you
#	   ask for all of them.
#
sub nlist {
    local($binary, @symbols) = @_;
    local($addr,$type,$pipe,$symbol, at list);

    open(_nlist_pipe, "nm -p $binary|") || die "pipe failed";

    while (<_nlist_pipe>) {
	next if /\.o$/;
	($addr, $type, $name) = /^([0-9a-f]+)\s+(\w+)\s+(\w+)/;
	if ( $#symbols < $[ ) {
	    push (@list, $name, hex($addr));
	    next;
	} 
	foreach $symbol (@symbols) {
	    if ( $name =~ /^$symbol$/ ) {
		push (@list, $name, hex($addr));
		last;
	    }
	}
    } 
    close _nlist_pipe;
    return @list;
}


    Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
    Convex Computer Corporation                            tchrist at convex.COM
		 "EMACS belongs in <sys/errno.h>: Editor too big!"



More information about the Alt.sources mailing list