<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf8">
<title>/usr/web/sources/contrib/de0u/blame - Plan 9 from Bell Labs</title>
<!-- THIS FILE IS AUTOMATICALLY GENERATED. -->
<!-- EDIT sources.tr INSTEAD. -->
</meta>
</head>
<body>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"><a href="/plan9/">Plan 9 from Bell Labs</a>&rsquo;s /usr/web/sources/contrib/de0u/blame</span></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
Copyright © 2009 Alcatel-Lucent.<br />
Distributed under the
<a href="/plan9/license.html">Lucent Public License version 1.02</a>.
<br />
<a href="/plan9/download.html">Download the Plan 9 distribution.</a>
</font>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<table width="100%" cellspacing=0 border=0><tr><td align="center">
<table cellspacing=0 cellpadding=5 bgcolor="#eeeeff"><tr><td align="left">
<pre>
<!-- END HEADER -->
#!/bin/rc

# Dave Eckhardt, 2009-04-12

rfork ne

fn usage {
	msg='usage: '^`{basename $0}^' [-b] executable-file [object-file|library...]'
	echo $msg
	echo '	-b includes BSS (present in memory but absent from executable file)'
	echo '	-f report blame by file, not by symbol (you must provide objs/libs)'
	exit $msg
}
fn missing { msg=$1^': not found'; echo $msg; exit $msg }

~ $#* 0 &amp;&amp; usage

# Plan
#
# Parse command line into flags, objects, libraries, and one executable.
# Inventory objects and libraries into a symbol-&gt;origin hash.
# For each executable symbol, compute size and origin, building blame hash.
# Print blame hash.

libs=() ; objs = () ; execf = ()

for (arg) {
	switch ($arg) {
	case -b
		dobss=1
	case -f
		blamefiles=1
	case -*
		usage
	case *.a
		test -r $arg || missing $arg
		libs=($libs $arg)
	case *.? *.a?
		test -r $arg || missing $arg
		objs=($objs $arg)
	case *
		test -r $arg || missing $arg
		execf=($execf $arg)
	}
}

# Exactly one executable file.
~ $#execf 1 || usage

# If we have only one intermediate file, nm will helpfully
# omit to print the file name in its output.  So double it.
~ $#objs 1 &amp;&amp; objs=($objs $objs)

BSSawk='BEGIN { dobss = 0 }'
~ $#dobss 1 &amp;&amp; BSSawk='BEGIN { dobss = 1}'

BLAMEawk='BEGIN { blamefiles = 0 }'
~ $#blamefiles 1 &amp;&amp; BLAMEawk='BEGIN { blamefiles = 1 }'

# Ok, enough meditation.  Let's get to work.

sizeoutput=(`{size $execf})
size=$sizeoutput(7)

# We run nm manually multiple times so we can decorate
# member names with the name of the library.  Note that
# we trim out symbol references here via grep to save awk
# some work.  Also, the order of these steps matters:  the
# executable must be last and sorted numerically.

{
	for (lib in $libs) {
		# Instead of saying that chatty9p comes from "thread.8",
		# rewrite to say it comes from "lib9p(thread.8)".
		b=`{basename $lib | sed -e 's/\.a//'}
		nm $lib | sed -e 's/(^[^:]*):/'^$b'(\1):/'
	}

	~ $#objs 0 || nm $objs

	nm -n $execf
} | grep -v ' U '  | \
	\
awk 'BEGIN { totalsize = sprintf("%x",'^$size^') }' ^ ' ' ^ $"BSSawk ^ $"BLAMEawk ^ '
	BEGIN {
		for (i=0; i&lt;16; i++)
			_unhex[sprintf("%x", i)] = _unhex[sprintf("%X", i)] = i
		got1origin = 0;
	}
	function unhex(s, i, v) {
		v = 0
		for (i=1; i &lt;= length(s); i++)
			v = v*16 + _unhex[substr(s,i,1)]
		return v
	}
	function originates(sym, file) {
		origin[sym] = file;
		got1origin = 1;
	}
	function entity(sym, start, end, kind, mysize, myfile) {		
		# Ignore "small" things - ints in header files are "defined" multiply, but are only noise for our purposes
		if ((mysize = unhex(end) - unhex(start)) &lt;= 64)
			return;
		if (!dobss &amp;&amp; (kind == "b" || kind == "B"))
			return;
		if ((myfile = origin[sym]) == "") {
			myfile = "???"
		}
		if (blamefiles) {
			blame[myfile] += mysize
		} else {
			if (got1origin)
				print mysize, sym, myfile;
			else
				print mysize, sym;
		}
	}
	# First we expect to see lines like this:
	# xalloc.8: T xsummary
	# We key off the colon.
	(($1 ~ /^..*:$/) &amp;&amp; (NF == 3)) {
		originates($3, substr($1,1,length($1)-1));
	}
	# Then we expect lines like this:
	# f0100020 T _startKADDR
	(($1 ~ /^[a-z0-9][a-z0-9]*$/) &amp;&amp; (NF == 3)) {
		if (!donefirst) {
			# "fill pipe"
			oldhex = $1; oldkind = $2; oldsymbol = $3;
			donefirst = 1;
		} else {
			entity(oldsymbol, oldhex, $1, oldkind);
			oldhex = $1; oldkind = $2; oldsymbol = $3;
		}
	}
	

	END {
		# first flush last symbol from pipe
		entity(oldsymbol, oldhex, totalsize, oldkind);

		if (blamefiles) {
			for (file in blame) {
				print blame[file], file;
			}
		}
	}
	'

# awk code for unhex due to Russ Cox

exit ''


<!-- BEGIN TAIL -->
</pre>
</td></tr></table>
</td></tr></table>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<p style="line-height: 1.2em; margin-left: 1.00in; text-indent: 0.00in; margin-right: 1.00in; margin-top: 0; margin-bottom: 0; text-align: center;">
<span style="font-size: 10pt"></span></p>
<p style="margin-top: 0; margin-bottom: 0.50in"></p>
<p style="margin-top: 0; margin-bottom: 0.33in"></p>
<center><table border="0"><tr>
<td valign="middle"><a href="http://www.alcatel-lucent.com/"><img border="0" src="/plan9/img/logo_ft.gif" alt="Bell Labs" />
</a></td>
<td valign="middle"><a href="http://www.opensource.org"><img border="0" alt="OSI certified" src="/plan9/img/osi-certified-60x50.gif" />
</a></td>
<td><img style="padding-right: 45px;" alt="Powered by Plan 9" src="/plan9/img/power36.gif" />
</td>
</tr></table></center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center>
<span style="font-size: 10pt">(<a href="/plan9/">Return to Plan 9 Home Page</a>)</span>
</center>
<p style="margin-top: 0; margin-bottom: 0.17in"></p>
<center><font size=-1>
<span style="font-size: 10pt"><a href="http://www.lucent.com/copyright.html">Copyright</a></span>
<span style="font-size: 10pt">© 2009 Alcatel-Lucent.</span>
<span style="font-size: 10pt">All Rights Reserved.</span>
<br />
<span style="font-size: 10pt">Comments to</span>
<span style="font-size: 10pt"><a href="mailto:webmaster@plan9.bell-labs.com">webmaster@plan9.bell-labs.com</a>.</span>
</font></center>
</body>
</html>

