blob: 3cf60e3efd233b29059aed276bd26529be7b7503 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001use strict;
2BEGIN{push(@INC,'../', './tools/', './tools/MemoryUtility/')};
3use CommonUtility;
4
5#****************************************************************************
6# Constants
7#****************************************************************************
8package LoadRegion;
9use constant Base => 1;
10use constant Size => 2;
11use constant MaxSize => 3;
12use constant Attr => 4;
13
14package ExecutionRegion;
15use constant ExeRegionName => 0;
16use constant Base => 1;
17use constant Size => 2;
18use constant MaxSize => 3;
19use constant Type => 3;
20use constant Attr => 4;
21use constant SectionAttr => 5;
22use constant ObjName => 6;
23use constant LibName => 7;
24
25package LisFileParser;
26
27my $g_LISPath;
28# Load Region
29my %g_LoadRegion;
30my $g_LoadRegionCount = 0;
31my %g_LoadRegionLookUpTable; # RegionName -> Index
32# Execution Region
33my %g_ExeRegion;
34my $g_ExeRegionCount = 0;
35my %g_ExeRegionLookUpTable; # RegionName -> Index
36my %g_VeneerLookUpTable;
37
38# InputSection:
39my %g_InputSectionDetails; # {nIndex} => [0. strExecutionRegionName,
40 # 1. strBaseAddress,
41 # 2. strSize,
42 # 3. strType,
43 # 4. strAttr,
44 # 5. strSectionName,
45 # 6. strObjectName,
46 # 7. strLibName]
47 # nIndex starts from 0
48my %g_InputSections; # {strExecutionRegionName} => [nIndex, ...]
49my $g_InputSectionCount = 0;
50my %debugInfoSize;
51my %ObjSummary;
52my %LibSummary;
53
54my %child;
55my %parent;
56
57# Total Size
58my $g_nTotalROSize = 0;
59my $g_nTotalRWZISize = 0;
60my $g_nTotalROMSize = 0;
61
62my @LoadRegions;
63my @ExeRegions;
64
65#****************************************************************************
66# oo >>> Finished
67#****************************************************************************
68# return 1;
69
70#****************************************************************************
71# subroutine: LIS_die
72# sample code: (message, __FILE__, __LINE__)
73# input: $error_msg, $file, $line_no
74#****************************************************************************
75sub LIS_die
76{
77 my ($error_msg, $file, $line_no) = (@_);
78 &CommonUtil::error_handler($error_msg, $file, $line_no, 'LIS');
79}
80#****************************************************************************
81# subroutine: ParseLIS
82# input: LIS Path string
83# output: x
84#****************************************************************************
85sub ParseLIS
86{
87 ($g_LISPath) = (@_);
88
89 %g_LoadRegion = undef;
90 $g_LoadRegionCount = 0;
91 %g_LoadRegionLookUpTable = undef;
92 %g_ExeRegion = undef;
93 $g_ExeRegionCount = 0;
94 %g_ExeRegionLookUpTable = undef;
95 %g_VeneerLookUpTable = undef;
96 %g_InputSectionDetails = undef;
97 %g_InputSections = undef;
98 $g_InputSectionCount = 0;
99 %debugInfoSize = undef;
100 %ObjSummary = undef;
101 %LibSummary = undef;
102 %child = undef;
103 %parent = undef;
104 $g_nTotalROSize = 0;
105 $g_nTotalRWZISize = 0;
106 $g_nTotalROMSize = 0;
107 @LoadRegions = undef;
108 @ExeRegions = undef;
109
110 if(defined $g_LISPath and -e $g_LISPath)
111 {
112 open (FILE_HANDLE, "<$g_LISPath") or &LIS_die("$g_LISPath: file error!", __FILE__, __LINE__);
113 my $strPreExeRegionName = undef;
114 my $strObjDebug = 0;
115 my $strLibDebug = 0;
116 while (<FILE_HANDLE>)
117 {
118 my $strLine = $_;
119
120 if(/\s+(\S+)\..*\((\S+)\)\srefers\s\S*\s*to\s(\S+)\..*\((\S+)\)\sfor\s(\S+)\s*/)
121 { ### arm_unaligned.obj(i.memcpy) refers to rt_memcpy_w.o(.text) for __aeabi_memcpy4
122 my $parent = $2;
123 my $child = $5;
124 $parent =~ s/i\.//;
125 push(@{$child{$parent}}, $child);
126 push(@{$parent{$child}}, $parent);
127 }
128 elsif(/Veneer to (\w+)\s+(0x\w+)/)
129 {
130 $g_VeneerLookUpTable{$2} = $1;
131 ## Long ARM to Thumb Veneer to ASSERT 0x5000005c ARM Code 8 anon$$obj.o(Veneer$$Code)
132 }
133 elsif(/\s+Load Region\s(\w+)\s\(Base:\s(0x\w+)\,\sSize:\s(0x\w+),\sMax:\s(0x\w+),\s(\w+)\)/)
134 { # Load Region READ_ONLY (Base: 0x40000900, Size: 0x00004114, Max: 0xffffffff, ABSOLUTE)
135 #$1=Region name, $2=nBaseAddress, $3=nActualSize, $4=nMaxSize, $5=strAttribute
136 $g_LoadRegion{++$g_LoadRegionCount}= [$1, hex($2), hex($3), hex($4), $5];
137 #print "Index=$g_LoadRegionCount, LoadRegionName=$1, BaseAddress=$2, MaxSize=$3, ActualSize=$4, Attribute=$5\n";
138 $g_LoadRegionLookUpTable{$1} = $g_LoadRegionCount; ### use load region name to query load region id
139 $strPreExeRegionName = undef;
140 push(@LoadRegions, $1);
141 }
142 elsif (/\s+Execution Region\s(\w+)\s\(Base:\s(0x\w+)\,\sSize:\s(0x\w+),\sMax:\s(0x\w+),\s(\w+)(.*)\)/)
143 {
144 #$1=Region name, $2=nBaseAddress, $3=nActualSize, $4=nMaxSize, $5=strAttribute
145 $g_ExeRegion{++$g_ExeRegionCount}= [$1, hex($2), hex($3), hex($4), $5];
146 #print "Index=$g_ExeRegionCount, ExeRegionName=$1, BaseAddress=$2, Size=$3, ActualSize=$4, Attribute=$5\n";
147 $g_ExeRegionLookUpTable{$1} = $g_ExeRegionCount;
148 # For parsing Input sections
149 $strPreExeRegionName = $1;
150 $g_InputSections{$strPreExeRegionName} = [];
151 push(@ExeRegions, $1);
152 }
153 elsif (/=========/)
154 {
155 $strPreExeRegionName = undef;
156 }
157 elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Object Name/)
158 { ## Code (inc. data) RO Data RW Data ZI Data Debug Object Name
159 $strObjDebug = 1;
160 }
161 elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Library Member Name/)
162 {
163 $strObjDebug = 1;
164 }
165 elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Library Name/)
166 { ## Code (inc. data) RO Data RW Data ZI Data Debug Library Name
167 $strLibDebug = 1;
168 }
169 elsif (/Total RO Size \(Code \+ RO Data\)\s+(\S+)/)
170 {
171 $g_nTotalROSize = $1;
172 }
173 elsif (/Total RW Size \(RW Data \+ ZI Data\)\s+(\S+)/)
174 {
175 $g_nTotalRWZISize = $1;
176 }
177 elsif (/Total ROM Size \(Code \+ RO Data \+ RW Data\)\s+(\S+)/)
178 {
179 $g_nTotalROMSize = $1;
180 }
181 &ParseInputSection($strPreExeRegionName, $strLine) if(defined $strPreExeRegionName);
182 &ParseDebugInfo($strObjDebug, $strLine) if ($strObjDebug);
183 &GetObjSummaryInfo($strObjDebug, $strLine) if ($strObjDebug);
184 &GetLibSummaryInfo($strLibDebug, $strLine) if ($strLibDebug);
185 }
186 close FILE_HANDLE;
187 }
188 else
189 {
190 &LIS_die("LIS Path($g_LISPath) doesn't exist", __FILE__, __LINE__);
191 }
192}
193
194#****************************************************************************
195# subroutine: StoreIntoTempFile
196# input: N/A
197# output: temp files which contain perl data structure
198#****************************************************************************
199use Storable qw/lock_nstore/;
200sub StoreIntoTempFile
201{
202 my ($strPath) = @_;
203 my $file = $strPath."\\LisParser_Temp.dat";
204 my %tempfile;
205 $tempfile{"parent_reference"} = \%parent;
206 $tempfile{"child_reference"} = \%child;
207 $tempfile{"debug_size"} = \%debugInfoSize;
208 $tempfile{"execution_region"} = \%g_ExeRegion;
209 $tempfile{"load_region"} = \%g_LoadRegion;
210 $tempfile{"symbol_info"} = \%g_InputSectionDetails;
211 $tempfile{"obj_summary"} = \%ObjSummary;
212 $tempfile{"lib_summary"} = \%LibSummary;
213
214 lock_nstore \%tempfile, $file;
215}
216
217#****************************************************************************
218# subroutine: GetParentOfSymbol
219# input: symbol name
220# output: parent symbol array reference
221#****************************************************************************
222sub GetParentOfSymbol
223{
224 my ($strSymbolName) = @_;
225 foreach my $key (keys %parent)
226 {
227 next if ($strSymbolName ne $key);
228 my $parent = $parent{$key};
229
230 return $parent;
231 }
232}
233
234#****************************************************************************
235# subroutine: GetChildOfSymbol
236# input: symbol name
237# output: child symbol array reference
238#****************************************************************************
239sub GetChildOfSymbol
240{
241 my ($strSymbolName) = @_;
242 foreach my $key (keys %child)
243 {
244 next if ($strSymbolName ne $key);
245 my $child = $child{$key};
246
247 return $child;
248 }
249}
250
251#****************************************************************************
252# subroutine: ListAllExeRegion
253# input: N/A
254# output: execution region array reference
255#****************************************************************************
256sub ListAllExeRegion
257{
258 $#ExeRegions = $#ExeRegions + 1;
259 return \@ExeRegions;
260}
261
262#****************************************************************************
263# subroutine: ListAllLoadRegion
264# input: N/A
265# output: load region array reference
266#****************************************************************************
267sub ListAllLoadRegion
268{
269 $#LoadRegions = $#LoadRegions + 1;
270 return \@LoadRegions;
271}
272#****************************************************************************
273# subroutine: ParseInputSection used by ParseLIS
274# to parse input sections
275# parsing format:
276# Base Addr Size Type Attr Idx E Section Name Object
277# 1. 0x70008230 0x00000020 Code RO 18 * VECTOR_TBL bl_BOOTARM.obj(bootloader.lib)
278# 2. 0x1007bb30 0x00000008 Ven RO 402248 Veneer$$Code anon$$obj.o
279# 3. 0x106f9c72 0x00000002 PAD
280# we don't need Idx(Index) and E(Entry)
281# input: 1. Execution Name, 2. $strLine
282# output: x
283#****************************************************************************
284sub ParseInputSection
285{
286 my ($strExeRegionName, $strLine) = @_;
287 return if(!defined $strExeRegionName); ### setting for $strExeRegionName = undef
288
289 my ($strBaseAddress, $strSize, $strType, $strAttr, $strInputSection, $strObjName, $strLibName)
290 = (undef, undef, undef, undef, undef, undef, undef);
291 my $bMatchInputSection = 0;
292 chomp($strLine);
293 if($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)\s+(\w+)\s+\d+\s+\**\s+(\S+)\s+(\S+)\((\S+)\)/)
294 {
295 # Base Addr Size Type Attr Idx E Section Name Object
296 # 0x70008230 0x00000020 Code RO 18 * VECTOR_TBL bl_BOOTARM.obj(bootloader.lib)
297 $strBaseAddress = $1;
298 $strSize = $2;
299 $strType = $3;
300 $strAttr = $4;
301 $strInputSection = $5;
302 $strObjName = $6;
303 $strLibName = $7;
304 #print "[Pattern 1]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType, [Attr]$strAttr, [InputAttr]$strInputSection, [ObjName]$strObjName, [LibName]$strLibName\n";
305 $bMatchInputSection = 1;
306 }
307 elsif($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)\s+(\w+)\s+\d+\s+\**\s+(\S+)\s+(\S+)/)
308 {
309 # Base Addr Size Type Attr Idx E Section Name Object
310 # 0x1007bb30 0x00000008 Ven RO 402248 Veneer$$Code anon$$obj.o
311 $strBaseAddress = $1;
312 $strSize = $2;
313 $strType = $3;
314 $strAttr = $4;
315 $strInputSection = $5;
316 $strObjName = $6;
317 #print "[Pattern 2]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType, [Attr]$strAttr, [InputAttr]$strInputSection, [ObjName]$strObjName, [LibName]x\n";
318 $bMatchInputSection = 1;
319 }
320 elsif($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)/)
321 {
322 # Base Addr Size Type Attr Idx E Section Name Object
323 # 0x106f9c72 0x00000002 PAD
324 $strBaseAddress = $1;
325 $strSize = $2;
326 $strType = $3;
327 #print "[Pattern 3]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType\n";
328 $bMatchInputSection = 1;
329 }
330 if($bMatchInputSection == 1)
331 {
332 $g_InputSectionDetails{$g_InputSectionCount} = [$strExeRegionName, $strBaseAddress, $strSize,
333 $strType, $strAttr, $strInputSection,
334 $strObjName, $strLibName];
335 push (@{$g_InputSections{$strExeRegionName}}, $g_InputSectionCount);
336 $g_InputSectionCount++;
337 }
338}
339
340#****************************************************************************
341# subroutine: ListPadInfo
342# input: N/A
343# output: array reference
344# for lis file, array content:[array1,array2,...]
345# array1:[strPadBaseAddress,strPreSymName,strPreSymAddress,strPostSymName,strPostSymAddress]
346#****************************************************************************
347sub ListPadInfo
348{
349 my @padstring;
350 foreach my $key (sort keys %g_InputSectionDetails)
351 {
352 my $type = $g_InputSectionDetails{$key}->[3];
353 next if ($type ne "PAD");
354 my $base_address = $g_InputSectionDetails{$key}->[1];
355 my $pre_address = $g_InputSectionDetails{$key-1}->[1];
356 my $pre_symbol = $g_InputSectionDetails{$key-1}->[5];
357 my $post_address = $g_InputSectionDetails{$key+1}->[1];
358 my $post_symbol = $g_InputSectionDetails{$key+1}->[5];
359
360 my @padinfo = [$base_address,$pre_symbol,$pre_address,$post_symbol,$post_address];
361 push (@padstring, @padinfo);
362 }
363 return \@padstring;
364}
365
366#****************************************************************************
367# subroutine: ParseDebugInfo
368# input: $strObjDebug, $strLine
369# output: N/A
370#****************************************************************************
371sub ParseDebugInfo
372{
373 my ($strObjDebug, $strLine) = @_;
374 return if(!$strObjDebug);
375 ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
376 chomp($strLine);
377 if($strLine =~ /\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+(\S+\.obj$|\S+\.o$)/)
378 {
379 $debugInfoSize{$2} = $1;
380 }
381}
382
383#****************************************************************************
384# subroutine: GetObjSummaryInfo
385# input: flag $strObjDebug, $strLine
386# output: N/A
387#****************************************************************************
388sub GetObjSummaryInfo
389{
390 my ($strObjDebug, $strLine) = @_;
391 return if(!$strObjDebug);
392 ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
393 chomp($strLine);
394 if($strLine =~ /\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+\.obj$|\S+\.o$)/)
395 {
396 $ObjSummary{$7} = [$1,$2,$3,$4,$5,$6];
397 }
398}
399
400#****************************************************************************
401# subroutine: GetLibSummaryInfo
402# input: flag $strLibDebug, $strLine
403# output: N/A
404#****************************************************************************
405sub GetLibSummaryInfo
406{
407 my ($strLibDebug, $strLine) = @_;
408 return if(!$strLibDebug);
409 ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
410 chomp($strLine);
411 if($strLine =~ /\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+\.lib$|\S+\.l$|\S+\.a$)/)
412 {
413 $LibSummary{$7} = [$1,$2,$3,$4,$5,$6];
414 }
415}
416
417#****************************************************************************
418# subroutine: ListObjSummaryInfo
419# input: obj name, flag represents which column to show
420# flag = "Code"
421# = "inc.data"
422# = "RO Data"
423# = "RW Data"
424# = "ZI Data"
425# = "Debug"
426# output: Code/inc.data/RO Data/RW Data/ZI Data/Debug size for given obj
427#****************************************************************************
428sub ListObjSummaryInfo
429{
430 my ($strObjName, $flag) = @_;
431 foreach my $key (keys %ObjSummary)
432 {
433 next if ($strObjName ne $key);
434 my $ObjSummaryInfo = $ObjSummary{$key};
435 if ($flag eq "Code")
436 {
437 return @$ObjSummaryInfo[0];
438 }
439 elsif ($flag eq "inc.data")
440 {
441 return @$ObjSummaryInfo[1];
442 }
443 elsif ($flag eq "RO Data")
444 {
445 return @$ObjSummaryInfo[2];
446 }
447 elsif ($flag eq "RW Data")
448 {
449 return @$ObjSummaryInfo[3];
450 }
451 elsif ($flag eq "ZI Data")
452 {
453 return @$ObjSummaryInfo[4];
454 }
455 elsif ($flag eq "Debug")
456 {
457 return @$ObjSummaryInfo[5];
458 }
459 }
460}
461
462#****************************************************************************
463# subroutine: ListLibSummaryInfo
464# input: lib name, flag represents which column to show
465# flag = "Code"
466# = "inc.data"
467# = "RO Data"
468# = "RW Data"
469# = "ZI Data"
470# = "Debug"
471# output: Code/inc.data/RO Data/RW Data/ZI Data/Debug size for given lib
472#****************************************************************************
473sub ListLibSummaryInfo
474{
475 my ($strLibName, $flag) = @_;
476 foreach my $key (keys %LibSummary)
477 {
478 next if ($strLibName ne $key);
479 my $LibSummaryInfo = $LibSummary{$key};
480 if ($flag eq "Code")
481 {
482 return @$LibSummaryInfo[0];
483 }
484 elsif ($flag eq "inc.data")
485 {
486 return @$LibSummaryInfo[1];
487 }
488 elsif ($flag eq "RO Data")
489 {
490 return @$LibSummaryInfo[2];
491 }
492 elsif ($flag eq "RW Data")
493 {
494 return @$LibSummaryInfo[3];
495 }
496 elsif ($flag eq "ZI Data")
497 {
498 return @$LibSummaryInfo[4];
499 }
500 elsif ($flag eq "Debug")
501 {
502 return @$LibSummaryInfo[5];
503 }
504 }
505}
506
507#****************************************************************************
508# subroutine: GetInputSectionsByExeRegion
509# input: $strExeRegionName: Execution Name (Case sensitive)
510# output: Array_ref : InputSections: [[ExeRegionName, Base...], [ExeRegionName, Base...], ...]
511# [ExeRegionName, Base...]: InputSectionDetails elements
512#****************************************************************************
513sub GetInputSectionsByExeRegion
514{
515 my ($strExeRegionName) = @_;
516 my @InputSections;
517 my $Indexes = $g_InputSections{$strExeRegionName}; ### array
518 foreach my $nIndex (@$Indexes)
519 {
520 push(@InputSections, $g_InputSectionDetails{$nIndex}); ## $g_InputSectionDetails{$g_InputSectionCount} = [$strExeRegionName, $strBaseAddress, $strSize, $strType, $strAttr, $strInputSection, $strObjName, $strLibName];
521 }
522 return \@InputSections;
523}
524
525#****************************************************************************
526# subroutine: GetObjTotalSizesByExeRegion
527# input: $strRegionName: Execution Name (Case sensitive)
528# output: ObjTotalSize Hash Reference: {ObjName::LibName} => nSize
529# sample code:
530# my $strExeRegionName = "xxx";
531# my $nObjTotalSize_ref = &LISInfo::GetObjTotalSizesByExeRegion($strExeRegionName);
532# foreach my $Obj_LibName (keys %$nObjTotalSize_ref) {...}
533# => $Obj_LibName: "ObjName::LibName"
534#****************************************************************************
535sub GetObjTotalSizesByExeRegion
536{
537 my ($strExeRegionName) = @_;
538 my %nObjTotalSize; # {ObjName_LibName} = nSize;
539 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
540 foreach my $Info ( @$InputSections_ref)
541 {
542 if(defined $Info->[ExecutionRegion::ObjName])
543 {
544 my $strKey = $Info->[ExecutionRegion::ObjName]."::".$Info->[ExecutionRegion::LibName];
545 if(exists $nObjTotalSize{$strKey})
546 {
547 $nObjTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
548 #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
549 }
550 else
551 {
552 $nObjTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
553 #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
554 }
555 }
556 else #PAD
557 {
558 $nObjTotalSize{"PAD"} += hex($Info->[ExecutionRegion::Size]);
559 }
560 }
561 return \%nObjTotalSize;
562}
563
564#****************************************************************************
565# subroutine: GetObjSizeByCatExeRegion
566# input: $strRegionName: Execution Name (Case sensitive)
567# $strCategory: RO Data/RW Data/ZI Data/Code (Case sensitive)
568# output: ObjCateSize Hash Reference
569#****************************************************************************
570sub GetObjSizeByCatExeRegion
571{
572 my ($strExeRegionName, $strCategory) = @_;
573 my %nObjROSize;
574 my %nObjRWSize;
575 my %nObjZISize;
576 my %nObjCodeSize;
577
578 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
579 foreach my $Info ( @$InputSections_ref)
580 {
581 if(defined $Info->[ExecutionRegion::ObjName])
582 {
583 my $strKey = $Info->[ExecutionRegion::ObjName];
584
585 if(($strCategory eq "RO Data") && ($Info->[ExecutionRegion::Type] eq "Data") && ($Info->[ExecutionRegion::Attr] eq "RO"))
586 {
587 if(exists $nObjROSize{$strKey})
588 {
589 $nObjROSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
590 }
591 else
592 {
593 $nObjROSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
594 }
595 }
596 elsif(($strCategory eq "RW Data") && ($Info->[ExecutionRegion::Type] eq "Data") && ($Info->[ExecutionRegion::Attr] eq "RW"))
597 {
598 if(exists $nObjRWSize{$strKey})
599 {
600 $nObjRWSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
601 }
602 else
603 {
604 $nObjRWSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
605 }
606 }
607 elsif(($strCategory eq "ZI Data") && ($Info->[ExecutionRegion::Type] eq "Zero") && ($Info->[ExecutionRegion::Attr] eq "RW"))
608 {
609 if(exists $nObjZISize{$strKey})
610 {
611 $nObjZISize{$strKey} += hex($Info->[ExecutionRegion::Size]);
612 }
613 else
614 {
615 $nObjZISize{$strKey} = hex($Info->[ExecutionRegion::Size]);
616 }
617 }
618 elsif(($strCategory eq "Code") && ($Info->[ExecutionRegion::Type] eq "Code") && ($Info->[ExecutionRegion::Attr] eq "RO"))
619 {
620 if(exists $nObjCodeSize{$strKey})
621 {
622 $nObjCodeSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
623 }
624 else
625 {
626 $nObjCodeSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
627 }
628 }
629 }
630 }
631
632 if($strCategory eq "RO Data")
633 {
634 return \%nObjROSize;
635 }
636 elsif($strCategory eq "RW Data")
637 {
638 return \%nObjRWSize;
639 }
640 elsif($strCategory eq "ZI Data")
641 {
642 return \%nObjZISize;
643 }
644 elsif($strCategory eq "Code")
645 {
646 return \%nObjCodeSize;
647 }
648}
649
650
651#****************************************************************************
652# subroutine: GetTotalSizeByExeRegion
653# input: $strRegionName: Execution Region Name (Case sensitive)
654# output: total size for given execution region
655#****************************************************************************
656sub GetTotalSizeByExeRegion
657{
658 my ($strExeRegionName) = @_;
659 my %nExeRegionTotalSize; # {ObjName_LibName} = nSize;
660 my $TotalSize;
661 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
662 foreach my $Info ( @$InputSections_ref)
663 {
664 if(defined $Info->[ExecutionRegion::ExeRegionName])
665 {
666 my $strKey = $Info->[ExecutionRegion::ExeRegionName];
667 if(exists $nExeRegionTotalSize{$strKey})
668 {
669 $nExeRegionTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
670 #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
671 }
672 else
673 {
674 $nExeRegionTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
675 #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
676 }
677 $TotalSize = $nExeRegionTotalSize{$strKey};
678 }
679 }
680 return $TotalSize;
681}
682
683#****************************************************************************
684# subroutine: GetObjByExeRegion
685# input: Execution Region Name (Case sensitive)
686# output: OBJ array reference which given execution region contains
687#****************************************************************************
688sub GetObjByExeRegion
689{
690 my ($strExeRegionName) = @_;
691 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
692 my @obj;
693 my @uni_objs;
694 my %count;
695 foreach my $Info ( @$InputSections_ref)
696 {
697 if(defined $Info->[ExecutionRegion::ObjName])
698 {
699 my $strObj = $Info->[ExecutionRegion::ObjName];
700 push(@obj, $strObj);
701 }
702 }
703 @uni_objs = grep { ++$count{ $_ } < 2; } @obj;
704 return \@uni_objs;
705}
706
707#****************************************************************************
708# subroutine: GetLibByExeRegion
709# input: Execution Region Name (Case sensitive)
710# output: LIB array reference which given execution region contains
711#****************************************************************************
712sub GetLibByExeRegion
713{
714 my ($strExeRegionName) = @_;
715 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
716 my @lib;
717 my @uni_libs;
718 my %count;
719 foreach my $Info (@$InputSections_ref)
720 {
721 if(defined $Info->[ExecutionRegion::LibName])
722 {
723 my $strLib = $Info->[ExecutionRegion::LibName];
724 push(@lib, $strLib);
725 }
726 }
727 @uni_libs = grep { ++$count{ $_ } < 2; } @lib;
728 return \@uni_libs;
729}
730
731#****************************************************************************
732# subroutine: GetLibSizeByExeRegion
733# input: Execution Region Name, Library Name (Case sensitive)
734# output: size of given library in givin execution region
735#****************************************************************************
736sub GetLibSizeByExeRegion
737{
738 my ($strExeRegion, $strLib) = @_;
739 my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegion);
740 my $size = 0;
741 foreach my $Info ( @$InputSections_ref)
742 {
743 if($Info->[ExecutionRegion::LibName] eq $strLib)
744 {
745 $size += hex($Info->[ExecutionRegion::Size]);
746 }
747 }
748 return $size;
749}
750
751#****************************************************************************
752# subroutine: GetTotalSizeByLib
753# input: $strLibName: Library Name (Case sensitive)
754# output: total size for given library
755#****************************************************************************
756sub GetTotalSizeByLib
757{
758 my ($strLibName) = @_;
759 my %nLibTotalSize;
760 my $TotalSize;
761 foreach my $ExeRegion (@ExeRegions)
762 {
763 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
764 foreach my $Info ( @$InputSections_ref)
765 {
766 if(defined $Info->[ExecutionRegion::LibName])
767 {
768 my $strKey = $Info->[ExecutionRegion::LibName];
769 next if ($strKey ne $strLibName);
770 if(exists $nLibTotalSize{$strKey})
771 {
772 $nLibTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
773 #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
774 }
775 else
776 {
777 $nLibTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
778 #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
779 }
780 $TotalSize = $nLibTotalSize{$strKey};
781 }
782 }
783 }
784 return $TotalSize;
785}
786
787#****************************************************************************
788# subroutine: GetTotalSizeByObj
789# input: $strObjName: Obj Name, $strLibName: Library Name (Case sensitive)
790# output: total size for given (obj, library)
791#****************************************************************************
792sub GetTotalSizeByObj
793{
794 my ($strObjName, $strLibName) = @_;
795 my %nObjTotalSize;
796 my $TotalSize;
797 foreach my $ExeRegion(@ExeRegions)
798 {
799 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
800 foreach my $Info(@$InputSections_ref)
801 {
802 if(defined $Info->[ExecutionRegion::ObjName])
803 {
804 my $strKey = $Info->[ExecutionRegion::ObjName]."::".$Info->[ExecutionRegion::LibName];
805 my $Key = $strObjName."::".$strLibName;
806 next if ($Key ne $strKey);
807 if(exists $nObjTotalSize{$strKey})
808 {
809 $nObjTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
810 #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
811 }
812 else
813 {
814 $nObjTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
815 #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
816 }
817 $TotalSize = $nObjTotalSize{$strKey};
818 }
819 }
820 }
821 return $TotalSize;
822}
823
824#****************************************************************************
825# subroutine: ListObjLibBySymbol
826# input: $SymName: Symbol Name (Case sensitive)
827# output: [obj, library] list array reference
828#****************************************************************************
829sub ListObjLibBySymbol
830{
831 my ($SymName) = @_;
832 my @obj_lib;
833 foreach my $ExeRegion(@ExeRegions)
834 {
835 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
836 foreach my $Info(@$InputSections_ref)
837 {
838 if(defined $Info->[ExecutionRegion::SectionAttr])
839 {
840 my $strKey = $Info->[ExecutionRegion::SectionAttr];
841 if($strKey eq $SymName)
842 {
843 my $ObjName = $Info->[ExecutionRegion::ObjName];
844 my $LibName = $Info->[ExecutionRegion::LibName];
845 push(@obj_lib, [$ObjName, $LibName]);
846 }
847 }
848 }
849 }
850 return \@obj_lib;
851}
852
853#****************************************************************************
854# subroutine: ListObjByLib
855# input: $LibName: Library Name (Case sensitive)
856# output: obj array reference
857#****************************************************************************
858sub ListObjByLib
859{
860 my ($LibName) = @_;
861 my @obj;
862 my @uni_objs;
863 my %count;
864 foreach my $ExeRegion(@ExeRegions)
865 {
866 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
867 foreach my $Info(@$InputSections_ref)
868 {
869 if(defined $Info->[ExecutionRegion::LibName])
870 {
871 my $strKey = $Info->[ExecutionRegion::LibName];
872 if($strKey eq $LibName)
873 {
874 my $ObjName = $Info->[ExecutionRegion::ObjName];
875 push(@obj, $ObjName);
876 }
877 }
878 }
879 }
880 @uni_objs = grep { ++$count{ $_ } < 2; } @obj;
881 return \@uni_objs;
882}
883
884#****************************************************************************
885# subroutine: ListLibByObj
886# input: $ObjName: Object Name (Case sensitive)
887# output: Library array reference
888#****************************************************************************
889sub ListLibByObj
890{
891 my ($ObjName) = @_;
892 my @lib;
893 my @uni_libs;
894 my %count;
895 foreach my $ExeRegion(@ExeRegions)
896 {
897 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
898 foreach my $Info(@$InputSections_ref)
899 {
900 if(defined $Info->[ExecutionRegion::ObjName])
901 {
902 my $strKey = $Info->[ExecutionRegion::ObjName];
903 if($strKey eq $ObjName)
904 {
905 my $LibName = $Info->[ExecutionRegion::LibName];
906 push(@lib, $LibName);
907 }
908 }
909 }
910 }
911 @uni_libs = grep { ++$count{ $_ } < 2; } @lib;
912 return \@uni_libs;
913}
914
915#****************************************************************************
916# subroutine: GetObjDebugInfoSize
917# input: $strObjName: Obj Name (Case sensitive)
918# output: debug info size for given obj
919#****************************************************************************
920sub GetObjDebugInfoSize
921{
922 my ($strObjName) = @_;
923 my $DebugInfoSize = $debugInfoSize{$strObjName};
924 return $DebugInfoSize;
925}
926
927#****************************************************************************
928# subroutine: FootprintAnalyzeBySymbol
929# input: $strSymName: Symbol Name, $strObjName: Obj Name (Case sensitive)
930# output: symbol info array reference
931#****************************************************************************
932sub FootprintAnalyzeBySymbol
933{
934 my ($strSymName, $strObjName) = @_;
935 my %SymHash;
936 my @SymInfo;
937 foreach my $ExeRegion(@ExeRegions)
938 {
939 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
940 foreach my $Info(@$InputSections_ref)
941 {
942 if(defined $Info->[ExecutionRegion::SectionAttr])
943 {
944 my $strKey = $Info->[ExecutionRegion::SectionAttr]."::".$Info->[ExecutionRegion::ObjName];
945 my $Key = $strSymName."::".$strObjName;
946 next if ($Key ne $strKey);
947
948 my $type = $Info->[ExecutionRegion::Type];
949 if (($type ne "Pad") && ($type ne "Ven"))
950 {
951 my $attr = $Info->[ExecutionRegion::Attr]."-".$type;
952 my $base = $Info->[ExecutionRegion::Base];
953 my $size = hex($Info->[ExecutionRegion::Size]);
954 my $region = $ExeRegion;
955 $SymHash{$strKey} = [$region, $attr, $base, $size];
956
957 push(@SymInfo, $region);
958 push(@SymInfo, $attr);
959 push(@SymInfo, $base);
960 push(@SymInfo, $size);
961 }
962 elsif ($type eq "Ven")
963 {
964 my $region = $ExeRegion;
965 my $base = $Info->[ExecutionRegion::Base];
966 my $dest = $g_VeneerLookUpTable{$base};
967 my $size = hex($Info->[ExecutionRegion::Size]);
968 $SymHash{$strKey} = [$region, $type, $base, $size, $dest];
969
970 push(@SymInfo, $region);
971 push(@SymInfo, $type);
972 push(@SymInfo, $base);
973 push(@SymInfo, $size);
974 push(@SymInfo, $dest);
975 }
976 }
977 }
978 }
979 return \@SymInfo;
980}
981
982#****************************************************************************
983# subroutine: GetVeneerInfo
984# input: N/A
985# output: [Execution Region, Base Address, Size, DestinationSymbolName] array reference for veneer
986#****************************************************************************
987sub GetVeneerInfo
988{
989 my @veneers;
990 foreach my $ExeRegion(@ExeRegions)
991 {
992 my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
993 foreach my $Info(@$InputSections_ref)
994 {
995 if($Info->[ExecutionRegion::Type] eq "Ven")
996 {
997 my $base = $Info->[ExecutionRegion::Base];
998 my $size = hex($Info->[ExecutionRegion::Size]);
999 my $dest = $g_VeneerLookUpTable{$base};
1000 my @veneerinfo = [$ExeRegion, $base, $size, $dest];
1001 push(@veneers, @veneerinfo);
1002 }
1003 }
1004 }
1005 return \@veneers;
1006}
1007
1008#****************************************************************************
1009# subroutine: GetExeRegionInfo - Get Execution Region information
1010# input: $strRegionName: Execution Name (Case sensitive)
1011# $nOption: ExecutionRegion::Base
1012# ExecutionRegion::Size
1013# ExecutionRegion::MaxSize
1014# ExecutionRegion::Attr
1015# output: required Region Base address, Used Size, Region MaxSize, Attribute info
1016#****************************************************************************
1017sub GetExeRegionInfo
1018{
1019 my ($strRegionName, $nOption) = @_;
1020 my ($nBase, $nSize, $nMaxSize, $strAttribute) = (0,0,0,'');
1021 my $nIndex = $g_ExeRegionLookUpTable{$strRegionName};
1022 my $strInfo;
1023 if(defined $nIndex)
1024 {
1025 if($nOption == ExecutionRegion::Base)
1026 {
1027 $strInfo = &CommonUtil::Dec2Hex($g_ExeRegion{$nIndex}->[ExecutionRegion::Base]);
1028 }
1029 elsif($nOption == ExecutionRegion::Size)
1030 {
1031 $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::Size];
1032 }
1033 elsif($nOption == ExecutionRegion::MaxSize)
1034 {
1035 $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::MaxSize];
1036 }
1037 elsif($nOption == ExecutionRegion::Attr)
1038 {
1039 $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::Attr];
1040 }
1041 }
1042 return $strInfo;
1043}
1044
1045#****************************************************************************
1046# subroutine: GetLoadRegionInfo - Get Load Region information
1047# input: $strRegionName: Execution Name (Case sensitive)
1048# $nOption: LoadRegion::Base
1049# LoadRegion::Size
1050# LoadRegion::MaxSize
1051# LoadRegion::Attr
1052# output: required Region Base address, Used Size, Region MaxSize, Attribute infosub GetLoadRegionInfo
1053#****************************************************************************
1054sub GetLoadRegionInfo
1055{
1056 my ($strRegionName, $nOption) = (@_);
1057 my ($nBase, $nSize, $nMaxSize, $strAttribute) = (0,0,0,'');
1058 my $nIndex = $g_LoadRegionLookUpTable{$strRegionName};
1059 my $strInfo;
1060 if(defined $nIndex)
1061 {
1062 if($nOption == LoadRegion::Base)
1063 {
1064 $strInfo = &CommonUtil::Dec2Hex($g_LoadRegion{$nIndex}->[LoadRegion::Base]);
1065 }
1066 elsif($nOption == LoadRegion::Size)
1067 {
1068 $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::Size];
1069 }
1070 elsif($nOption == LoadRegion::MaxSize)
1071 {
1072 $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::MaxSize];
1073 }
1074 elsif($nOption == LoadRegion::Attr)
1075 {
1076 $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::Attr];
1077 }
1078 }
1079 return $strInfo;
1080}
1081
1082#****************************************************************************
1083# subroutine: GetTotalROSize - Get total RO size
1084# input: $bNeedString: 1=Return string, 0/default/no input=Return int
1085# output: $bNeedString=0:nROSize/ $bNeedString=1:strROSize
1086#****************************************************************************
1087sub GetTotalROSize
1088{
1089 my ($bNeedString) = @_;
1090 return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalROSize) : $g_nTotalROSize;
1091}
1092
1093#****************************************************************************
1094# subroutine: GetTotalRWZISize - Get total RWZI size
1095# input: $bNeedString: 1=Return string, 0/default/no input=Return int
1096# output: $bNeedString=0:nRWZISize/ $bNeedString=1:strRWZISize
1097#****************************************************************************
1098sub GetTotalRWZISize
1099{
1100 my ($bNeedString) = @_;
1101 return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalRWZISize) : $g_nTotalRWZISize;
1102}
1103
1104#****************************************************************************
1105# subroutine: GetTotalROMSize - Get total ROM size
1106# input: $bNeedString: 1=Return string, 0/default/no input=Return int
1107# output: $bNeedString=0:nROMSize/ $bNeedString=1:strROMSize
1108#****************************************************************************
1109sub GetTotalROMSize
1110{
1111 my ($bNeedString) = @_;
1112 return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalROMSize) : $g_nTotalROMSize;
1113}
1114
11151;