tools/static_dependencies.pl
changeset 80 3ab0df073c86
parent 25 f213623e3c86
child 105 96c15d318508
equal deleted inserted replaced
79:26cde9838d22 80:3ab0df073c86
    32 	close EXISTING;
    32 	close EXISTING;
    33 	}
    33 	}
    34 
    34 
    35 my %romfiles;
    35 my %romfiles;
    36 my @contents;
    36 my @contents;
       
    37 my %need_details;
    37 
    38 
    38 my $line;
    39 my $line;
    39 while ($line = <>)
    40 while ($line = <>)
    40 	{
    41 	{
    41   my ($romfile,$hostfile,$ibyfile,$package,$cmd,@columns) = split /,/, $line;		# first 5 fields are guaranteed to be simple
    42   my ($romfile,$hostfile,$ibyfile,$package,$cmd,@columns) = split /,/, $line;		# first 5 fields are guaranteed to be simple
    42 	next if (!defined $hostfile);
       
    43 	next if ($romfile eq "ROM file");		# skip header line
    43 	next if ($romfile eq "ROM file");		# skip header line
    44 	
    44 	if (!defined $hostfile)
    45 	if (lc $cmd eq "stem")
    45 		{
    46 		{
    46 		# is it perhaps a static_dependencies.txt line?
    47 		$hostfile =~ s/(\/|\\)([^\\\/]+)$/$1stem_$2/;			# use stem version instead
    47 		my $dependencies;
       
    48 		my $nothing;
       
    49 		($romfile,$hostfile,$dependencies,$nothing) = split /\t/, $line;
       
    50 		next if (defined $nothing || !defined $hostfile);
       
    51 		$cmd = "";
       
    52 		}
       
    53 	
       
    54 	if (lc $cmd eq "slim")
       
    55 		{
       
    56 		$need_details{lc $romfile} = 1;
       
    57 		$cmd = "stem";		# slim implies stem
       
    58 		}
       
    59 	if (lc $cmd eq "stem" && $hostfile !~ /stem_/)
       
    60 		{
       
    61 		push @contents, "$romfile\t$hostfile";	# calculate dependencies for the original file
       
    62 		$hostfile =~ s/(\/|\\)([^\\\/]+)$/$1stem_$2/;			# then use stem version as well
    48 		}
    63 		}
    49 	push @contents, "$romfile\t$hostfile";
    64 	push @contents, "$romfile\t$hostfile";
    50 	$romfiles{lc $romfile} = $romfile;
    65 	$romfiles{lc $romfile} = $romfile;
    51 	}
    66 	}
    52 
    67 
    67 	chomp $existingline;
    82 	chomp $existingline;
    68 	my ($romfile, $hostfile, $deps) = split /\t/, $existingline;
    83 	my ($romfile, $hostfile, $deps) = split /\t/, $existingline;
    69 	if (defined $deps)
    84 	if (defined $deps)
    70 		{
    85 		{
    71 		$romfile = canonical_romfile($romfile);
    86 		$romfile = canonical_romfile($romfile);
    72 		$outputlines{$romfile} = "$romfile\t$hostfile\t$deps";
    87 		$outputlines{"$romfile\t$hostfile"} = "$romfile\t$hostfile\t$deps";
    73 		}
    88 		}
    74 	}
    89 	}
    75 
    90 
    76 my %dependents;
    91 my %dependents;
    77 
    92 
    78 sub print_dependency($$@)
    93 sub print_dependency($$@)
    79 	{
    94 	{
    80 	my ($romfile,$hostfile,@dependencies) = @_;
    95 	my ($romfile,$hostfile,@dependencies) = @_;
    81 	$outputlines{$romfile} = "$romfile\t$hostfile\t". join(":",@dependencies);
    96 	$outputlines{"$romfile\t$hostfile"} = "$romfile\t$hostfile\t". join(":",@dependencies);
    82 	
    97 	
    83 	next unless $inverted_table;
    98 	next unless $inverted_table;
    84 	
    99 	
    85 	# Create inverted table 
   100 	# Create inverted table 
    86 	foreach my $dependent (@dependencies)
   101 	foreach my $dependent (@dependencies)
   100 			$dependents{$dependent} .= "\t$romfile";
   115 			$dependents{$dependent} .= "\t$romfile";
   101 			}
   116 			}
   102 		}
   117 		}
   103 	}
   118 	}
   104 
   119 
       
   120 sub summarise_list($)
       
   121 	{
       
   122 	my ($hashref) = @_;
       
   123 	my @summary;
       
   124 	my @list = sort {$a <=> $b} keys %$hashref;
       
   125 	my $first = shift @list;
       
   126 	my $latest = $first;
       
   127 	foreach my $number (@list)
       
   128 		{
       
   129 		if ($number == $latest + 1)
       
   130 			{
       
   131 			# extends existing range by one
       
   132 			$latest = $latest + 1;
       
   133 			next;
       
   134 			}
       
   135 		# new range
       
   136 		if ($first > -1)
       
   137 			{
       
   138 			if ($latest == $first)
       
   139 				{
       
   140 				# Range with one element
       
   141 				push @summary, $first;
       
   142 				}
       
   143 			else
       
   144 				{
       
   145 				push @summary, "$first-$latest";
       
   146 				}
       
   147 			}
       
   148 		$first = $number;
       
   149 		$latest = $number;
       
   150 		}
       
   151 	if ($latest == $first)
       
   152 		{
       
   153 		push @summary, "$first";
       
   154 		}
       
   155 	else
       
   156 		{
       
   157 		push @summary, "$first-$latest";
       
   158 		}
       
   159 	return join(".", @summary);
       
   160 	}
       
   161 
   105 sub generate_elftran_dependencies($$)
   162 sub generate_elftran_dependencies($$)
   106 	{
   163 	{
   107 	my ($romfile,$hostfile) = @_;
   164 	my ($romfile,$hostfile) = @_;
   108 	
   165 	
   109 	return if ($hostfile =~ /\/z\//); 	# data files in armv5\urel\z
   166 	return if ($hostfile =~ /\/z\//); 	# data files in armv5\urel\z
   111 
   168 
   112 	my @elftran = `elftran $hostfile`;
   169 	my @elftran = `elftran $hostfile`;
   113 	
   170 	
   114 	my $sid;
   171 	my $sid;
   115 	my @imports;
   172 	my @imports;
       
   173 	my $dll;
       
   174 	my $importing = 0;
       
   175 	my %ordinals;
       
   176 	my %exports;
   116 	foreach my $line (@elftran)
   177 	foreach my $line (@elftran)
   117 		{
   178 		{
       
   179 		#        Ordinal   318:  00010f9f
       
   180 		if ($line =~ /Ordinal\s+(\d+):\s+(ABSENT)?/)
       
   181 			{
       
   182 			$exports{$1} = 1 unless ($2 eq "ABSENT");
       
   183 			next;
       
   184 			}
       
   185 
   118 		# 2 imports from backend{00010001}[102828d5].dll
   186 		# 2 imports from backend{00010001}[102828d5].dll
   119 		# 17 imports from dfpaeabi{000a0000}.dll
   187 		# 17 imports from dfpaeabi{000a0000}.dll
   120 		if ($line =~ /imports from (\S+)\{.{8}\}(\S+)$/)
   188 		if ($line =~ /(\d+) imports from (\S+)\{.{8}\}(\S+)$/)
   121 			{
   189 			{
   122 			push @imports, $1.$2;
   190 			$dll = $2.$3;
       
   191 			my $import_count = $1;
       
   192 			my $exename = "sys\\bin\\". lc $dll;
       
   193 			$exename =~ s/\[\S+\]//;	# ignore the UID
       
   194 			if (defined $need_details{$exename})
       
   195 				{
       
   196 				# enable the tracking of the imported ordinals
       
   197 				$importing = $import_count;
       
   198 				%ordinals = ();
       
   199 				}
       
   200 			else
       
   201 				{
       
   202 				# Just report the simple reference to the imported dll
       
   203 				$importing = 0;
       
   204 				push @imports, $dll;
       
   205 				}
       
   206 			next;
       
   207 			}
       
   208 		if ($importing && $line =~ /^\s+(\d+)( offset by \d+)?$/)
       
   209 			{
       
   210 			$ordinals{$1} = 1;
       
   211 			$importing -= 1;
       
   212 			if ($importing == 0)
       
   213 				{
       
   214 				$dll = $dll. "@". summarise_list(\%ordinals);
       
   215 				push @imports, $dll;
       
   216 				}
   123 			next;
   217 			next;
   124 			}
   218 			}
   125 		if ($line =~ /^Secure ID: (\S+)$/)
   219 		if ($line =~ /^Secure ID: (\S+)$/)
   126 			{
   220 			{
   127 			$sid = $1; 	# presumably owns private/$sid  and various $sid.etxn files
   221 			$sid = $1; 	# presumably owns private/$sid  and various $sid.etxn files
   128 			next;
   222 			next;
   129 			}
   223 			}
   130 		}
   224 		}
   131 	print_dependency($romfile,$hostfile,"sid=$sid",@imports);
   225 
       
   226 	my @export_info = ();
       
   227 	if (scalar keys %exports && $need_details{lc $romfile})
       
   228 		{
       
   229 		push @export_info, "exports=".summarise_list(\%exports);
       
   230 		}
       
   231 	print_dependency($romfile,$hostfile, @export_info, "sid=$sid",@imports);
   132 	}
   232 	}
   133 
   233 
   134 sub find_exe_names_dependencies($$)
   234 sub find_exe_names_dependencies($$)
   135 	{
   235 	{
   136 	my ($romfile,$hostfile) = @_;
   236 	my ($romfile,$hostfile) = @_;