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) = @_; |