blob: 816d620868d114842197838da7baefd0743c646e [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* TCMQuery.pl
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This script is used to get symbol, object, and section information from sym file
48#*
49#*
50#* Author:
51#* -------
52#* Carl Kao (mtk08237)
53#*
54#*------------------------------------------------------------------------------
55#* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
56#*============================================================================
57#****************************************************************************/
58#****************************************************************************
59# Included Modules
60#****************************************************************************
61use strict;
62BEGIN { push @INC, "./" , '../', './tools/', './tools/MemoryUtility/' }
63use LinkerOutputParser;
64use File::Basename;
65use POSIX;
66
67my $TCMQuery_VERNO = " LR12_v0.03";
68 # LR12_v0.03 , 2016/01/25, Memory Utility Refinement for LR12
69 # LR12_v0.02 , 2016/12/15, fix memory utility .map file parsing feature for LR12 (64bit address)
70 # LR12_v0.01 , 2016/10/26, add GrepSymbolByInputSection feature to memory utility
71 # u0.01 , 2015/01/19, Initial revision for Memory Utility Refinement for LR11
72
73&Usage() if (($#ARGV != 2) && ($#ARGV != 3));
74
75my ($option, $region, $file1, $file2) = @ARGV;
76
77$file1 =~ s/\\/\\\\/;
78$file2 =~ s/\\/\\\\/;
79
80if(($option eq "-Q") || ($option eq "-q"))
81{
82 &TCMQuery($region, $file1);
83}
84elsif(($option eq "-C") || ($option eq "-c"))
85{
86 &TCMCompare($region, $file1, $file2);
87}
88elsif(($option eq "-S") || ($option eq "-s"))
89{
90 my @SymbolInfo; #[[SymbolName, address, size], ...] sorted by address
91 GetSymbolBySection($file1, $region, \@SymbolInfo);
92 ListAllSymbolInfo(\@SymbolInfo);
93}
94elsif(($option eq "-IS") || ($option eq "-is"))
95{
96 my @SymbolInfo; #[[SymbolName, Address, ObjectName, LibName, OutputSectionName, InputSectionName, InputSectionSize, SymbolSize], ...] sorted by address
97 GetSymbolByOutputSection($file1, $file2, $region, \@SymbolInfo);
98 ListAllSymbolAsMachineReadable(\@SymbolInfo, $region);
99}
100elsif(($option eq "-SC") || ($option eq "-sc"))
101{
102 my @SymbolInfo1; #[[SymbolName, address, size], ...] sorted by address
103 GetSymbolBySection($file1, $region, \@SymbolInfo1);
104 my @SymbolInfo2; #[[SymbolName, address, size], ...] sorted by address
105 GetSymbolBySection($file2, $region, \@SymbolInfo2);
106 my $diff_href = DiffSymbolInfo(\@SymbolInfo1, \@SymbolInfo2);
107 ListDiffSymbolInfo($diff_href, 0);
108}
109elsif(($option eq "-SCE") || ($option eq "-sce")) # section compare only in empty symbol
110{
111 my @SymbolInfo1; #[[SymbolName, address, size], ...] sorted by address
112 GetSymbolBySection($file1, $region, \@SymbolInfo1);
113 my @SymbolInfo2; #[[SymbolName, address, size], ...] sorted by address
114 GetSymbolBySection($file2, $region, \@SymbolInfo2);
115 my $diff_href = DiffSymbolInfo(\@SymbolInfo1, \@SymbolInfo2);
116 ListDiffSymbolInfo($diff_href, 1);
117}
118elsif(($option eq "-SO") || ($option eq "-so")) # parse symbols in specific lib
119{
120 my @SymbolInfo;
121 my $str_obj = $region;
122 GetSymbolByObj($file1,$file2,$str_obj,\@SymbolInfo);
123 ListAllSymbolAsMachineReadable(\@SymbolInfo,$str_obj);
124}
125elsif(($option eq "-SL") || ($option eq "-sl")) # parse symbols in specific obj
126{
127 my @SymbolInfo;
128 my $str_lib = $region;
129 GetSymbolByLib($file1,$file2,$str_lib,\@SymbolInfo);
130 ListAllSymbolAsMachineReadable(\@SymbolInfo,$str_lib);
131}
132elsif(($option eq "-ST") || ($option eq "-st")) # parse symbols whose size greater than specific size.
133{
134 my @SymbolInfo;
135 my $sym_size = $region;
136 GetSymbolByThreshold($file1,$file2,$sym_size,\@SymbolInfo);
137 ListAllSymbolAsMachineReadable(\@SymbolInfo,$sym_size);
138}
139elsif(($option eq "-SF") || ($option eq "-sf")) # parse fill info
140{
141 my $FillInfo_href;
142 &LinkerOutputParser::FileParse($region);
143 $FillInfo_href = &LinkerOutputParser::GetFillInfo();
144 ListFillInfo($FillInfo_href);
145}
146else
147{
148 &Usage();
149}
150
151sub GetSymbolBySection
152{
153 my ($symfile, $strSection, $SymbolInfo_aref) = @_;
154 LinkerOutputParser::FileParse($symfile);
155 my @regions = split(/\,/, $strSection);
156 foreach my $section (@regions)
157 {
158 if($section =~ /SPRAM/i or $section eq "L2SRAM")
159 {
160 my $exeregion_aref = &LinkerOutputParser::ListAllExeRegion(1);
161 if (defined $exeregion_aref)
162 {
163 foreach my $temp(@$exeregion_aref)
164 {
165 if ($temp =~ /$section/i)
166 {
167 my $temp1_aref = LinkerOutputParser::GrepSymbolBySection($temp);
168 push @$SymbolInfo_aref, @$temp1_aref;
169 }
170 }
171 }
172 }
173 else
174 {
175 my $temp_aref = LinkerOutputParser::GrepSymbolBySection($section);
176 push(@$SymbolInfo_aref , @$temp_aref);
177 }
178 }
179}
180
181sub GetSymbolByOutputSection
182{
183 my ($mapfile, $symfile, $strSectionNameInRegularExp, $SymbolInfo_aref) = @_;
184 my $temp_aref;
185
186 LinkerOutputParser::FileParse($symfile);
187
188 #list all symbol
189 if($strSectionNameInRegularExp =~ /^all$/)
190 {
191 $temp_aref = GetAllSymbol($symfile);
192 }
193 else
194 {
195 $temp_aref = LinkerOutputParser::GrepSymbolByOutputSection($strSectionNameInRegularExp);
196 }
197
198 # remove inline functions
199 my $idx=0;
200 foreach (@{$temp_aref})
201 {
202 delete @{$temp_aref}[$idx] if(@$_[3] eq "00000000");
203 $idx++;
204 }
205 @{$temp_aref} = grep { defined($_) } @{$temp_aref};
206
207 # append symbol obj/lib name to array if symbol exist in map file
208 AppendLibAttriToSymbol($mapfile,$temp_aref);
209 push @$SymbolInfo_aref, @$temp_aref;
210}
211
212sub GetSymbolByObj{
213 my ($mapfile, $symfile, $str_obj, $SymbolInfo_aref) = @_;
214
215 my $symbol_aref = GetAllSymbol($symfile);
216 AppendLibAttriToSymbol($mapfile, $symbol_aref);
217
218 #list all symbol
219 if($str_obj =~ /^all$/)
220 {
221 push(@$SymbolInfo_aref,@$symbol_aref);
222 }
223 else
224 {
225 my %obj = map{$_.".obj" => 1} split(/\,/, $str_obj);
226 foreach(@{$symbol_aref})
227 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName,$strLibName]
228 push(@$SymbolInfo_aref,$_) if($_->[5] && $obj{$_->[5]});
229 }
230 }
231}
232
233sub GetSymbolByLib{
234 my ($mapfile, $symfile, $str_lib, $SymbolInfo_aref) = @_;
235
236 my $symbol_aref = GetAllSymbol($symfile);
237 AppendLibAttriToSymbol($mapfile, $symbol_aref);
238
239 #list all symbol
240 if($str_lib =~ /^all$/)
241 {
242 push(@$SymbolInfo_aref,@$symbol_aref);
243 }
244 else
245 {
246 my %lib = map{$_.".a" => 1} split(/\,/, $str_lib);
247 foreach(@$symbol_aref)
248 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName,$strLibName]
249 push(@$SymbolInfo_aref,$_) if($_->[6] && $lib{$_->[6]});
250 }
251 }
252}
253
254sub GetSymbolByThreshold{
255 my ($mapfile, $symfile, $sym_size, $SymbolInfo_aref) = @_;
256
257 my $symbol_aref = GetAllSymbol($symfile);
258 AppendLibAttriToSymbol($mapfile, $symbol_aref);
259
260 #list all symbol
261 foreach(@$symbol_aref)
262 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName,$strLibName]
263 push(@$SymbolInfo_aref,$_) if($_->[4] >= $sym_size);
264 }
265}
266
267sub DiffSymbolInfo
268{
269 my ($SymInfo1_aref, $SymInfo2_aref) = @_;
270 my %diff;
271 foreach my $item (@$SymInfo1_aref)
272 {
273 if(!exists $diff{$item->[SymTable::Name]})
274 {
275 $diff{$item->[SymTable::Name]} = [ $item->[SymTable::Size] , -1, $item->[SymTable::Region]];
276 }
277 else
278 {
279 $diff{$item->[SymTable::Name]."+"} = [ $item->[SymTable::Size] , -1, $item->[SymTable::Region]];
280 }
281 }
282 foreach my $item (@$SymInfo2_aref)
283 {
284 if(exists $diff{$item->[SymTable::Name]})
285 {
286 $diff{$item->[SymTable::Name]}[1] = $item->[SymTable::Size];
287 }
288 else
289 {
290 $diff{$item->[SymTable::Name]} = [ -1, $item->[SymTable::Size], $item->[SymTable::Region]];
291 }
292 }
293 return \%diff;
294}
295
296sub ListDiffSymbolInfo
297{
298 my ($diff_href, $bListEmptyOnly) = @_;
299 print " $file1 \nvs. $file2\n";
300 print "SymbolName Size1 Size2\n";
301 print "*********************************************************************************************************************\n";
302 my $strRegion;
303 my ($nTotalSize1, $nTotalSize2) = (0,0);
304 foreach my $key (sort keys %$diff_href)
305 {
306 my $strSize1 = $diff_href->{$key}[0] eq "-1" ? "" : $diff_href->{$key}[0];
307 my $strSize2 = $diff_href->{$key}[1] eq "-1" ? "" : $diff_href->{$key}[1];
308 next if(($strSize1 eq $strSize2));
309 if($bListEmptyOnly)
310 {
311 next if(!($diff_href->{$key}[0] eq "-1" or $diff_href->{$key}[1] eq "-1"));
312 }
313 $nTotalSize1 += $strSize1;
314 $nTotalSize2 += $strSize2;
315 $~ = "DIFF";
316 format DIFF =
317@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<@<<<<<<<<<
318$key,$strSize1,$strSize2
319.
320write;
321 }
322 print "*********************************************************************************************************************\n";
323 $~ = "TOTALDIFF";
324 format TOTALDIFF =
325@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<@<<<<<<<<<
326'Total',$nTotalSize1,$nTotalSize2
327.
328write;
329}
330
331sub ListAllSymbolInfo
332{
333 my ($SymInfo_aref) = @_;
334 print "[Section]\n";
335 print "Address Size Group Symbol Name\n";
336 print "*********************************************************************************************************************\n";
337 my $strSection;
338 my $nNextAddress = 0;
339 my $nIndex = 0;
340 foreach my $item (@$SymInfo_aref)
341 {
342 if($item->[SymTable::Region] ne $strSection)
343 {
344 $strSection = $item->[SymTable::Region];
345 print "[$strSection]\n";
346 }
347
348 my $nSize = $item->[SymTable::Size];
349 my $strSize = $nSize;
350 if($nSize == 0)
351 {
352 if($nIndex+1 < scalar(@$SymInfo_aref) and $SymInfo_aref->[$nIndex+1][SymTable::Region] eq $strSection)
353 {
354 $nSize = hex($SymInfo_aref->[$nIndex+1][SymTable::Addr]) - hex($item->[SymTable::Addr]) ;
355 }
356 else
357 {
358 $nSize = "--";
359 }
360 $strSize = "0($nSize)";
361 }
362 $~ = "SYMBOLS";
363 format SYMBOLS =
364@<<<<<<<<<<<<<@<<<<<<<<<@<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
365$item->[SymTable::Addr],$strSize,$item->[SymTable::Group],$item->[SymTable::Name],
366.
367write;
368 $nIndex++;
369 }
370}
371
372sub ListAllSymbolInfoBySpecify
373{
374 my ($SymInfo_aref, $str_specify) = @_;
375
376 #calculate each string elements' max length
377 my @maxLengAry = ( length("SymbolName"), length("Address"), length("Attr"), length("OutputSectionName"), length("SymbolSize"), length("ObjectName"), length("LibName") );
378 CalStringMaxLength($SymInfo_aref, \@maxLengAry);
379 my $totalAryLength = 0;
380 my $strFormatStr = "";
381
382 for ( @maxLengAry )
383 {
384 $_ += 4;
385 $totalAryLength += $_;
386 }
387
388 my $nTotalSize = 0;
389
390 print "Specified parameter: $str_specify\n";
391
392 print "LibName" . " " x ($maxLengAry[6]-length("LibName")) . # libc.a
393 "ObjectName" . " " x ($maxLengAry[5]-length("ObjectName")) . # lib_a-memcpy.o
394 "Address" . " " x ($maxLengAry[1]-length("Address")) . # 0x943a0000
395 "Attr" . " " x ($maxLengAry[2]-length("Attr")) . # gF
396 "OutputSectionName" . " " x ($maxLengAry[3]-length("OutputSectionName")) . # CACHED_EXTSRAM_L2CACHE_LOCK_DATA
397 "SymbolSize" . " " x ($maxLengAry[4]-length("SymbolSize")) . # 924
398 "SymbolName" . " " x ($maxLengAry[0]-length("SymbolName")) . "\n"; # memcpy
399
400 print "*" x $totalAryLength . "\n";
401
402 foreach (sort{ $a->[6] cmp $b->[6] #sort by lib
403 or $a->[5] cmp $b->[5] #sort by obj
404 or $a->[1] cmp $b->[1] #sort by address
405 } @$SymInfo_aref)
406 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize, $strObjName, $strLibName];
407 next if ($_->[4] == 0);#skip symbol whose size is 0.
408 printf("%-${maxLengAry[6]}s", "@$_[6]"); #LibName
409 printf("%-${maxLengAry[5]}s", "@$_[5]"); #ObjectName
410 printf("%-${maxLengAry[1]}s", "@$_[1]"); #Address
411 printf("%-${maxLengAry[2]}s", "@$_[2]"); #Attr
412 printf("%-${maxLengAry[3]}s", "@$_[3]"); #OutputSectionName
413 printf("%-${maxLengAry[4]}s", "@$_[4]"); #SymbolSize
414 printf("%-${maxLengAry[0]}s", "@$_[0]"); #SymbolName
415 print "\n";
416 $nTotalSize += @$_[4];
417 }
418 print "*" x $totalAryLength . "\n";
419 printf("Total size: %d bytes, %.3f KB\n\n\n", $nTotalSize, $nTotalSize/1024);
420}
421
422
423sub ListAllSymbolAsMachineReadable
424{
425
426 my ($SymInfo_aref, $str_specify) = @_;
427 #my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
428 #my $now = sprintf("%04d-%02d-%02d %02d:%02d:%06s", $year+1900, $mon+1, $mday, $hour, $min, $sec.".000");
429
430 print "LibName,ObjectName,Address,Attr,OutputSectionName,SymbolSize,SymbolName\n";
431
432 foreach (sort{ $a->[6] cmp $b->[6] #sort by lib
433 or $a->[5] cmp $b->[5] #sort by obj
434 or $a->[1] cmp $b->[1] #sort by address
435 or $a->[0] cmp $b->[0] #sort by symbol name
436 } @$SymInfo_aref)
437 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize, $strObjName, $strLibName];
438 next if ($_->[4] == 0); #skip symbol whose size is 0.
439 #printf("%s,",$now); #timestamp
440 printf("%s,", "@$_[6]"); #LibName
441 printf("%s,", "@$_[5]"); #ObjectName
442 printf("%s,", "@$_[1]"); #Address
443 printf("%s,", "@$_[2]"); #Attr
444 printf("%s,", "@$_[3]"); #OutputSectionName
445 printf("%s,", "@$_[4]"); #SymbolSize
446 printf("%s", "@$_[0]"); #SymbolName
447 print "\n";
448 }
449}
450
451sub ListFillInfo
452{
453 my ($FillInfo_href) = @_;
454
455 print "Address,Fill_Size,Attr,Object_Info,Libinfo\n";
456
457 foreach (sort{$$FillInfo_href{$a}->[0] cmp $$FillInfo_href{$b}->[0]} keys %{$FillInfo_href})
458 {
459 printf("%s,", $$FillInfo_href{$_}->[0]);
460 printf("%s,", $$FillInfo_href{$_}->[1]);
461 printf("%s,", $$FillInfo_href{$_}->[2]);
462 printf("%s,", $$FillInfo_href{$_}->[3]);
463 printf("%s", $$FillInfo_href{$_}->[4]) if $$FillInfo_href{$_}->[4];
464 print "\n";
465 }
466}
467
468sub TCMQuery
469{
470 my ($ExeRegion, $file) = @_;
471
472 my ($objs_aref, $RO_href, $RW_href, $ZI_href) = &GetAllOBJ($ExeRegion, $file);
473 print "Object_Name RO_Size RW_Size ZI_Size\n";
474 print "***********************************************************************************************\n";
475
476 my $total_RO;
477 my $total_RW;
478 my $total_ZI;
479
480 foreach my $temp(sort @$objs_aref)
481 {
482 $~ = "LIS_QUERY";
483 format LIS_QUERY =
484@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<
485$temp,$$RO_href{$temp},$$RW_href{$temp},$$ZI_href{$temp}
486.
487
488write;
489 $total_RO += $$RO_href{$temp};
490 $total_RW += $$RW_href{$temp};
491 $total_ZI += $$ZI_href{$temp};
492 }
493 $~ = "LIS_QUERY_TOTAL";
494 format LIS_QUERY_TOTAL =
495@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<
496"Total",$total_RO,$total_RW,$total_ZI
497.
498
499write;
500
501 print "***********************************************************************************************\n";
502}
503
504sub TCMCompare
505{
506 my ($ExeRegion, $file1, $file2) = @_;
507 my ($objs1_aref, $RO_1_href, $RW_1_href, $ZI_1_href, $objs2_aref, $RO_2_href, $RW_2_href, $ZI_2_href);
508
509 ($objs1_aref, $RO_1_href, $RW_1_href, $ZI_1_href) = &GetAllOBJ($ExeRegion, $file1);
510 ($objs2_aref, $RO_2_href, $RW_2_href, $ZI_2_href) = &GetAllOBJ($ExeRegion, $file2);
511
512 my @objs1 = @$objs1_aref;
513 my @objs2 = @$objs2_aref;
514
515 my %objs1 = map{$_ => 1} @objs1;
516 my %objs2 = map{$_ => 1} @objs2;
517 my @arr = map{$_ => 1} @objs1;
518
519 my @inter = grep {$objs1{$_}} @objs2;
520
521 my %merge = map {$_ => 1} @objs1,@objs2;
522 my @merge = sort keys (%merge);
523
524 my @objs1_only = grep {!$objs2{$_}} @merge;
525 my @objs2_only = grep {!$objs1{$_}} @merge;
526
527 print "Compare result as below:\n";
528
529
530 print "**************************************************************************************************************************************\n";
531 print " Codebase1 Codebase2 Diff\n";
532 print "ObjectName ROSize;RWSize;ZISize ROSize;RWSize;ZISize ROSize;RWSize;ZISize\n";
533 print "**************************************************************************************************************************************\n";
534
535 my $total_RO_1 = 0;
536 my $total_RW_1 = 0;
537 my $total_ZI_1 = 0;
538 my $total_RO_2 = 0;
539 my $total_RW_2 = 0;
540 my $total_ZI_2 = 0;
541 my $total_RO_diff = 0;
542 my $total_RW_diff = 0;
543 my $total_ZI_diff = 0;
544 my $total_codebase1;
545 my $total_codebase2;
546 my $total_diff;
547
548 foreach my $obj(@merge)
549 {
550 $$RO_2_href{$obj} = 0 if(!defined $$RO_2_href{$obj});
551 $$RO_1_href{$obj} = 0 if(!defined $$RO_1_href{$obj});
552 $$RW_2_href{$obj} = 0 if(!defined $$RW_2_href{$obj});
553 $$RW_1_href{$obj} = 0 if(!defined $$RW_1_href{$obj});
554 $$ZI_2_href{$obj} = 0 if(!defined $$ZI_2_href{$obj});
555 $$ZI_1_href{$obj} = 0 if(!defined $$ZI_1_href{$obj});
556
557 my $RO_diff = $$RO_2_href{$obj} - $$RO_1_href{$obj};
558 my $RW_diff = $$RW_2_href{$obj} - $$RW_1_href{$obj};
559 my $ZI_diff = $$ZI_2_href{$obj} - $$ZI_1_href{$obj};
560
561 my $codebase1 = $$RO_1_href{$obj}.";".$$RW_1_href{$obj}.";".$$ZI_1_href{$obj};
562 my $codebase2 = $$RO_2_href{$obj}.";".$$RW_2_href{$obj}.";".$$ZI_2_href{$obj};
563 my $diff = $RO_diff.";".$RW_diff.";".$ZI_diff;
564
565 $total_RO_1 += $$RO_1_href{$obj};
566 $total_RW_1 += $$RW_1_href{$obj};
567 $total_ZI_1 += $$ZI_1_href{$obj};
568
569 $total_RO_2 += $$RO_2_href{$obj};
570 $total_RW_2 += $$RW_2_href{$obj};
571 $total_ZI_2 += $$ZI_2_href{$obj};
572
573 $total_RO_diff += $RO_diff;
574 $total_RW_diff += $RW_diff;
575 $total_ZI_diff += $ZI_diff;
576
577 $~ = "LIS_COMPARE";
578 format LIS_COMPARE =
579@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
580$obj,$codebase1,$codebase2,$diff
581.
582
583write;
584 }
585
586 $total_codebase1 = $total_RO_1.";".$total_RW_1.";".$total_ZI_1;
587 $total_codebase2 = $total_RO_2.";".$total_RW_2.";".$total_ZI_2;
588 $total_diff = $total_RO_diff.";".$total_RW_diff.";".$total_ZI_diff;
589
590 $~ = "LIS_TOTAL";
591 format LIS_TOTAL =
592@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
593"Total",$total_codebase1,$total_codebase2,$total_diff
594.
595
596write;
597
598 print "**************************************************************************************************************************************\n";
599}
600
601sub GetAllOBJ
602{
603 my ($ExeRegion, $file) = @_;
604 my $symfile = $file;
605 my $exeregion_aref;
606
607 if($file =~ /\.map$/)
608 {
609 $symfile =~ s/map/sym/;
610 if(!-f $symfile)
611 {
612 my $file = basename($symfile);
613 my $dirname = dirname($symfile);
614 $symfile = $dirname."\/dummy_$file";
615 }
616 &LinkerOutputParser::FileParse($symfile);
617 }
618 &LinkerOutputParser::FileParse($file);
619 $exeregion_aref = &LinkerOutputParser::ListAllExeRegion(1);
620
621 my %objs;
622 my @uni_objs;
623 my %count;
624 my %RO_Size;
625 my %RW_Size;
626 my %ZI_Size;
627 my $nSectionCount=0;
628 my $strListSections = "List of Sections:\n";
629 my $strLast = "";
630 if (defined $exeregion_aref)
631 {
632 foreach my $temp(@$exeregion_aref)
633 {
634 next if ($temp !~ /$ExeRegion/i);
635 if (($ExeRegion =~ /[D|I].+\d$/i) && ($temp =~ /DYNAMIC_SECTION/i))
636 { # add this confition for query DSPRAM0 + DSPRAM0_ZI. User treat them as single section
637 $strLast .= "no overlap (dynamic loading) section: $temp\n";
638 next;
639 }
640 my $obj_aref = &LinkerOutputParser::GetObjByExeRegion($temp);
641 if (defined $obj_aref)
642 {
643 map { $objs{$_} = 1} @$obj_aref;
644 }
645 $strListSections .= sprintf("\tSection %3d: %s", $nSectionCount++, $temp);
646 $strListSections .= (($temp =~ /DYNAMIC_SECTION/i) ? sprintf(" (overlap section)\n") : "\n");
647 }
648 }
649 print $strListSections.$strLast."\n\n";
650
651 foreach my $obj(keys %objs)
652 {
653 push (@uni_objs, $obj);
654 my ($nRO_Size, $nRW_Size, $nZI_Size);
655 if (defined $exeregion_aref)
656 {
657 foreach my $temp(@$exeregion_aref)
658 {
659 next if ($temp !~ /$ExeRegion/i);
660
661 if($file =~ /\.map$/)
662 {
663 if ($obj =~ /\.o|\*\S*\*|stub/) #(/\*fill\*\s+(0x\w+)\s+(0x\w+)/)
664 {
665 $nRO_Size = &LinkerOutputParser::GetObjSizeByCatExeRegion($temp, $obj, "RO");
666 $nRW_Size = &LinkerOutputParser::GetObjSizeByCatExeRegion($temp, $obj, "RW");
667 $nZI_Size = &LinkerOutputParser::GetObjSizeByCatExeRegion($temp, $obj, "ZI");
668 _UpdateSize(\%RO_Size, $obj, $nRO_Size);
669 _UpdateSize(\%RW_Size, $obj, $nRW_Size);
670 _UpdateSize(\%ZI_Size, $obj, $nZI_Size);
671 }
672 }
673 }
674 }
675
676 }
677
678 return (\@uni_objs, \%RO_Size, \%RW_Size, \%ZI_Size);
679}
680
681#calculate each element in the array's max length
682#input: [[str1_1, str2_1, str3_1, ...], [str1_2, str2_2, str3_2, ...], ...]
683#output: [max_length_str1, max_length_str2, max_length_str3, ...]
684sub CalStringMaxLength
685{
686 my ($CaluAry_aref, $MaxLengthAry_aref) = @_;
687
688 foreach my $curAry_aref (@{$CaluAry_aref})
689 {
690 for (my $i=0 ; $i <= $#$MaxLengthAry_aref ; $i++)
691 {
692 my $curStrLength = length(@$curAry_aref[$i]);
693 $MaxLengthAry_aref->[$i] = $curStrLength if $curStrLength > $MaxLengthAry_aref->[$i];
694 }
695 }
696}
697
698sub _UpdateSize
699{
700 my ($href, $strKey, $nSize) = @_;
701 if(exists $href->{$strKey})
702 {
703 $href->{$strKey} += $nSize;
704 }
705 else
706 {
707 $href->{$strKey} = $nSize;
708 }
709}
710
711sub GetAllSymbol{
712
713 my ($symfile) = @_;
714
715 LinkerOutputParser::FileParse($symfile);
716 my $symbol_aref = &LinkerOutputParser::GetSymbolTable();
717
718 return $symbol_aref;
719}
720
721sub AppendLibAttriToSymbol{
722
723 my ($mapfile, $symbol_aref) = @_;
724
725 # append symbol obj/lib name to array if symbol exist in map file
726 LinkerOutputParser::FileParse($mapfile);
727 my $region_attr = LinkerOutputParser::GetExeRegionAttr();
728
729 foreach (@{$symbol_aref})
730 { #[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName]
731 my @symbol_info = LinkerOutputParser::GetSymbolInfo($_->[1].".".$_->[0]);
732 my $strLibName = undef;
733 my $obj_lib_by_addr = undef;
734
735 $_->[2] = _updateAttr($_->[2], $region_attr->{$_->[3]});
736
737 if (@symbol_info)
738 {
739 #get non-static symbol info
740 #[$SymbolName, $strAddress, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize]
741 $_->[4] = $symbol_info[6] > $_->[4] ? $symbol_info[6] : $_->[4];#update symbol size
742 $_->[5] = $symbol_info[2];# obj name
743 $_->[6] = $symbol_info[3];# lib name
744 }
745 elsif(@{$obj_lib_by_addr = LinkerOutputParser::ListObjLibByAddr($_->[1])})
746 {#[$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName];
747 if($#$_ == 4 && $_->[0] !~ /^_ZN/)
748 {
749 $_->[4] = 0;
750 }
751 $_->[5] = $obj_lib_by_addr->[0];# obj name
752 $_->[6] = $obj_lib_by_addr->[1];# lib name
753 }
754 elsif($#$_ == 5 && @{$strLibName = LinkerOutputParser::ListLibByObj($_->[-1])})
755 {
756 next if ($#$strLibName > 1);
757 $_->[6] = $strLibName->[0];# lib name
758 }
759 }
760 return $symbol_aref;
761}
762
763sub _updateAttr
764{
765 my ($attr_group, $attr_sec) = @_;
766
767 if($attr_sec =~ /RO/ && $attr_group =~ /F/)
768 {
769 return "RO_CODE";
770 }
771 elsif($attr_sec =~ /RO/ && $attr_group =~ /O/)
772 {
773 return "RO_DATA";
774 }
775 else
776 {
777 return $attr_sec;
778 }
779}
780
781sub Usage
782{
783 print <<"__EOFUSAGE";
784
785usage: perl TCMQuery.pl -Q INTSRAM map_file_path
786 perl TCMQuery.pl -q INTSRAM map_file_path
787 perl TCMQuery.pl -C INTSRAM map_file_path1 map_file_path2
788 perl TCMQuery.pl -c INTSRAM map_file_path1 map_file_path2
789 perl TCMQuery.pl -S INTSRAM sym_file_path
790 perl TCMQuery.pl -s INTSRAM sym_file_path
791
792map_file_path1: map file path for codebase1 you want to compare
793map_file_path2: map file path for codebase2 you want to compare
794
795e.g.
796perl TCMQuery.pl -Q INTSRAM "E:\\mtk80506\\MT6280_EVB_R7R8_PCB01_hspa_MT6280_S00\\MT6280_EVB_R7R8_PCB01_hspa_MT6280_S00.map"
797perl TCMQuery.pl -C INTSRAM "E:\\mtk80506\MT6280_EVB_R7R8_PCB01_hspa_MT6280_S00\\MT6280_EVB_R7R8_PCB01_hspa_MT6280_S00.map" "E:\\mtk80506\\MT6280_EVB_R7R8_PCB01_hspa_MT6280_S00.map"
798
799__EOFUSAGE
800 exit 1;
801}