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