Wednesday, September 1, 2010

graphviz map of the linkage between .a files

This hacked up piece of perl script will generate a dot compatible piece of text that will display the mapping of the libs in a project.

#!/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