#!/usr/bin/perl
my $path = "path/to/libs"
# get the nm results for the system
@ret = `find $path | grep "\.a$" | xargs nm -A`;
#@ret = `cat data.tmp`;
# 0 = lib[object]
# 6 = DEF/UNDEF
# ./path_to_lib.a[object_in_lib.o]: [152] | 0| 0|FUNC |GLOB |0 |UNDEF | func_name_in_obj
my $count = 20;
my %defs = ();
my %connects = ();
# break appart the result and map what are uages of functions and what are definations
print " // mapping functions...\n";
foreach $line (@ret)
{
chomp($line);
@cols = split(/\|/, $line);
$file = $cols[0];
$undef = $cols[6];
$func = $cols[7];
# $file =~ s/:.*//; # for in lib object inter-dependency...
$file =~ s/\[.*//; # for lib file inter-dependency...
if( $undef =~ /UNDEF/ )
{
$connects{ $func }{ $file } = 1;
}
else
{
$defs{$func} = $file;
}
}
# now merge the usage with the definition as the file linkage
my %map = ();
print " // merging func usage to definition...\n";
foreach $func (sort keys %connects)
{
$files = $connects{$func};
$def_file = $defs{$func};
foreach $file (sort keys %$files)
{
$map{$def_file}{$file} = 1;
}
}
my %node = ();
my $node_count = 0;
print " // generating node index...\n";
foreach $src_file (sort keys %map)
{
unless( exists( $node{$src_file} ) )
{
$node{$src_file} = $node_count;
$node_count = $node_count + 1;
}
$files = $map{$src_func};
foreach $tar (sort keys %$files)
{
unless( exists( $node{$tar} ) )
{
$node{$tar} = $node_count;
$node_count = $node_count + 1;
}
}
}
print " // generating dot file...\n";
print "digraph linkmapping {\n";
foreach $key (sort keys %node)
{
$idx = $node{$key};
print " n$idx [label=\"$key\"];\n";
}
foreach $src_file (sort keys %map)
{
$files = $map{$src_func};
$src_node = $node{$src_file};
foreach $tar (sort keys %$files)
{
$tar_node = $node{$tar};
print " n$tar_node -> n$src_node;\n";
}
}
print "}";
Execute with the following (assuming you called the saved file "nm_deps.pl"
nm_deps.pl > map.dot dot map.dot -Tpng -omap.png
No comments:
Post a Comment