#!/usr/bin/perl

$last = 0;
open (MAP, shift(@ARGV)) || die "can't open map file";
while (<MAP>) {
	chomp;
	($addr, $type, $name) = split;
	$addr = hex($addr);
	if ($name =~ /^_text$/) {
		$store = 1;
		$start = $addr;
	} elsif ($name =~ /^_end$/) {
		$store = 0;
		$end = $addr;
	} elsif ($store == 1) {
		push @addrs, $addr;
		$map{$addr} = $name;
		$size{$last} = $addr - $last;
	}
	if ($name =~ /^_etext$/) {
		$etext = $addr;
	}
	$last = $addr;
}
close(MAP);

@addrs = sort(@addrs);

while (<>) {
	chomp;
	@words = split(/\W/, $_);
	foreach $word (@words) {
		if ($word =~ /^[0-9a-fA-F]+$/) {
			$addr = hex($word);
			if (($addr > $start) && ($addr < $end)) {
				$prevaddr = findbelow($addr);
				$size = $size{$prevaddr};
				if ($addr < $etext) {
					print " [<$word>] $map{$prevaddr}+";
				} else {
					print "                       $word   $map{$prevaddr}+";
				}
				#print "($prevaddr $size)";
				$offset = $addr - $prevaddr;
				printf("%lx/%lx ", $offset, $size);
				printf("(%ld/%ld)\n", $offset, $size);
			}
		}
	}
}

# should use binary chop search, but I'm too idle to write it.
# pass me a binary value, not a hex one.
sub findbelow
{
	my ($search) = @_;
	my $addr; my $last = $start;

	foreach $addr (@addrs) {
		if ($addr > $search) {
			return $last;
		}
		$last = $addr;
	}
}