[Feature]Upload Modem source code
Change-Id: Id4294f30faced84d3e6fd6d5e61e1111bf287a37
diff --git a/mcu/tools/MemoryUtility/LisFileParser.pm b/mcu/tools/MemoryUtility/LisFileParser.pm
new file mode 100644
index 0000000..3cf60e3
--- /dev/null
+++ b/mcu/tools/MemoryUtility/LisFileParser.pm
@@ -0,0 +1,1115 @@
+use strict;
+BEGIN{push(@INC,'../', './tools/', './tools/MemoryUtility/')};
+use CommonUtility;
+
+#****************************************************************************
+# Constants
+#****************************************************************************
+package LoadRegion;
+use constant Base => 1;
+use constant Size => 2;
+use constant MaxSize => 3;
+use constant Attr => 4;
+
+package ExecutionRegion;
+use constant ExeRegionName => 0;
+use constant Base => 1;
+use constant Size => 2;
+use constant MaxSize => 3;
+use constant Type => 3;
+use constant Attr => 4;
+use constant SectionAttr => 5;
+use constant ObjName => 6;
+use constant LibName => 7;
+
+package LisFileParser;
+
+my $g_LISPath;
+# Load Region
+my %g_LoadRegion;
+my $g_LoadRegionCount = 0;
+my %g_LoadRegionLookUpTable; # RegionName -> Index
+# Execution Region
+my %g_ExeRegion;
+my $g_ExeRegionCount = 0;
+my %g_ExeRegionLookUpTable; # RegionName -> Index
+my %g_VeneerLookUpTable;
+
+# InputSection:
+my %g_InputSectionDetails; # {nIndex} => [0. strExecutionRegionName,
+ # 1. strBaseAddress,
+ # 2. strSize,
+ # 3. strType,
+ # 4. strAttr,
+ # 5. strSectionName,
+ # 6. strObjectName,
+ # 7. strLibName]
+ # nIndex starts from 0
+my %g_InputSections; # {strExecutionRegionName} => [nIndex, ...]
+my $g_InputSectionCount = 0;
+my %debugInfoSize;
+my %ObjSummary;
+my %LibSummary;
+
+my %child;
+my %parent;
+
+# Total Size
+my $g_nTotalROSize = 0;
+my $g_nTotalRWZISize = 0;
+my $g_nTotalROMSize = 0;
+
+my @LoadRegions;
+my @ExeRegions;
+
+#****************************************************************************
+# oo >>> Finished
+#****************************************************************************
+# return 1;
+
+#****************************************************************************
+# subroutine: LIS_die
+# sample code: (message, __FILE__, __LINE__)
+# input: $error_msg, $file, $line_no
+#****************************************************************************
+sub LIS_die
+{
+ my ($error_msg, $file, $line_no) = (@_);
+ &CommonUtil::error_handler($error_msg, $file, $line_no, 'LIS');
+}
+#****************************************************************************
+# subroutine: ParseLIS
+# input: LIS Path string
+# output: x
+#****************************************************************************
+sub ParseLIS
+{
+ ($g_LISPath) = (@_);
+
+ %g_LoadRegion = undef;
+ $g_LoadRegionCount = 0;
+ %g_LoadRegionLookUpTable = undef;
+ %g_ExeRegion = undef;
+ $g_ExeRegionCount = 0;
+ %g_ExeRegionLookUpTable = undef;
+ %g_VeneerLookUpTable = undef;
+ %g_InputSectionDetails = undef;
+ %g_InputSections = undef;
+ $g_InputSectionCount = 0;
+ %debugInfoSize = undef;
+ %ObjSummary = undef;
+ %LibSummary = undef;
+ %child = undef;
+ %parent = undef;
+ $g_nTotalROSize = 0;
+ $g_nTotalRWZISize = 0;
+ $g_nTotalROMSize = 0;
+ @LoadRegions = undef;
+ @ExeRegions = undef;
+
+ if(defined $g_LISPath and -e $g_LISPath)
+ {
+ open (FILE_HANDLE, "<$g_LISPath") or &LIS_die("$g_LISPath: file error!", __FILE__, __LINE__);
+ my $strPreExeRegionName = undef;
+ my $strObjDebug = 0;
+ my $strLibDebug = 0;
+ while (<FILE_HANDLE>)
+ {
+ my $strLine = $_;
+
+ if(/\s+(\S+)\..*\((\S+)\)\srefers\s\S*\s*to\s(\S+)\..*\((\S+)\)\sfor\s(\S+)\s*/)
+ { ### arm_unaligned.obj(i.memcpy) refers to rt_memcpy_w.o(.text) for __aeabi_memcpy4
+ my $parent = $2;
+ my $child = $5;
+ $parent =~ s/i\.//;
+ push(@{$child{$parent}}, $child);
+ push(@{$parent{$child}}, $parent);
+ }
+ elsif(/Veneer to (\w+)\s+(0x\w+)/)
+ {
+ $g_VeneerLookUpTable{$2} = $1;
+ ## Long ARM to Thumb Veneer to ASSERT 0x5000005c ARM Code 8 anon$$obj.o(Veneer$$Code)
+ }
+ elsif(/\s+Load Region\s(\w+)\s\(Base:\s(0x\w+)\,\sSize:\s(0x\w+),\sMax:\s(0x\w+),\s(\w+)\)/)
+ { # Load Region READ_ONLY (Base: 0x40000900, Size: 0x00004114, Max: 0xffffffff, ABSOLUTE)
+ #$1=Region name, $2=nBaseAddress, $3=nActualSize, $4=nMaxSize, $5=strAttribute
+ $g_LoadRegion{++$g_LoadRegionCount}= [$1, hex($2), hex($3), hex($4), $5];
+ #print "Index=$g_LoadRegionCount, LoadRegionName=$1, BaseAddress=$2, MaxSize=$3, ActualSize=$4, Attribute=$5\n";
+ $g_LoadRegionLookUpTable{$1} = $g_LoadRegionCount; ### use load region name to query load region id
+ $strPreExeRegionName = undef;
+ push(@LoadRegions, $1);
+ }
+ elsif (/\s+Execution Region\s(\w+)\s\(Base:\s(0x\w+)\,\sSize:\s(0x\w+),\sMax:\s(0x\w+),\s(\w+)(.*)\)/)
+ {
+ #$1=Region name, $2=nBaseAddress, $3=nActualSize, $4=nMaxSize, $5=strAttribute
+ $g_ExeRegion{++$g_ExeRegionCount}= [$1, hex($2), hex($3), hex($4), $5];
+ #print "Index=$g_ExeRegionCount, ExeRegionName=$1, BaseAddress=$2, Size=$3, ActualSize=$4, Attribute=$5\n";
+ $g_ExeRegionLookUpTable{$1} = $g_ExeRegionCount;
+ # For parsing Input sections
+ $strPreExeRegionName = $1;
+ $g_InputSections{$strPreExeRegionName} = [];
+ push(@ExeRegions, $1);
+ }
+ elsif (/=========/)
+ {
+ $strPreExeRegionName = undef;
+ }
+ elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Object Name/)
+ { ## Code (inc. data) RO Data RW Data ZI Data Debug Object Name
+ $strObjDebug = 1;
+ }
+ elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Library Member Name/)
+ {
+ $strObjDebug = 1;
+ }
+ elsif (/\s+Code\s+\(inc\. data\)\s+RO Data\s+RW Data\s+ZI Data\s+Debug\s+Library Name/)
+ { ## Code (inc. data) RO Data RW Data ZI Data Debug Library Name
+ $strLibDebug = 1;
+ }
+ elsif (/Total RO Size \(Code \+ RO Data\)\s+(\S+)/)
+ {
+ $g_nTotalROSize = $1;
+ }
+ elsif (/Total RW Size \(RW Data \+ ZI Data\)\s+(\S+)/)
+ {
+ $g_nTotalRWZISize = $1;
+ }
+ elsif (/Total ROM Size \(Code \+ RO Data \+ RW Data\)\s+(\S+)/)
+ {
+ $g_nTotalROMSize = $1;
+ }
+ &ParseInputSection($strPreExeRegionName, $strLine) if(defined $strPreExeRegionName);
+ &ParseDebugInfo($strObjDebug, $strLine) if ($strObjDebug);
+ &GetObjSummaryInfo($strObjDebug, $strLine) if ($strObjDebug);
+ &GetLibSummaryInfo($strLibDebug, $strLine) if ($strLibDebug);
+ }
+ close FILE_HANDLE;
+ }
+ else
+ {
+ &LIS_die("LIS Path($g_LISPath) doesn't exist", __FILE__, __LINE__);
+ }
+}
+
+#****************************************************************************
+# subroutine: StoreIntoTempFile
+# input: N/A
+# output: temp files which contain perl data structure
+#****************************************************************************
+use Storable qw/lock_nstore/;
+sub StoreIntoTempFile
+{
+ my ($strPath) = @_;
+ my $file = $strPath."\\LisParser_Temp.dat";
+ my %tempfile;
+ $tempfile{"parent_reference"} = \%parent;
+ $tempfile{"child_reference"} = \%child;
+ $tempfile{"debug_size"} = \%debugInfoSize;
+ $tempfile{"execution_region"} = \%g_ExeRegion;
+ $tempfile{"load_region"} = \%g_LoadRegion;
+ $tempfile{"symbol_info"} = \%g_InputSectionDetails;
+ $tempfile{"obj_summary"} = \%ObjSummary;
+ $tempfile{"lib_summary"} = \%LibSummary;
+
+ lock_nstore \%tempfile, $file;
+}
+
+#****************************************************************************
+# subroutine: GetParentOfSymbol
+# input: symbol name
+# output: parent symbol array reference
+#****************************************************************************
+sub GetParentOfSymbol
+{
+ my ($strSymbolName) = @_;
+ foreach my $key (keys %parent)
+ {
+ next if ($strSymbolName ne $key);
+ my $parent = $parent{$key};
+
+ return $parent;
+ }
+}
+
+#****************************************************************************
+# subroutine: GetChildOfSymbol
+# input: symbol name
+# output: child symbol array reference
+#****************************************************************************
+sub GetChildOfSymbol
+{
+ my ($strSymbolName) = @_;
+ foreach my $key (keys %child)
+ {
+ next if ($strSymbolName ne $key);
+ my $child = $child{$key};
+
+ return $child;
+ }
+}
+
+#****************************************************************************
+# subroutine: ListAllExeRegion
+# input: N/A
+# output: execution region array reference
+#****************************************************************************
+sub ListAllExeRegion
+{
+ $#ExeRegions = $#ExeRegions + 1;
+ return \@ExeRegions;
+}
+
+#****************************************************************************
+# subroutine: ListAllLoadRegion
+# input: N/A
+# output: load region array reference
+#****************************************************************************
+sub ListAllLoadRegion
+{
+ $#LoadRegions = $#LoadRegions + 1;
+ return \@LoadRegions;
+}
+#****************************************************************************
+# subroutine: ParseInputSection used by ParseLIS
+# to parse input sections
+# parsing format:
+# Base Addr Size Type Attr Idx E Section Name Object
+# 1. 0x70008230 0x00000020 Code RO 18 * VECTOR_TBL bl_BOOTARM.obj(bootloader.lib)
+# 2. 0x1007bb30 0x00000008 Ven RO 402248 Veneer$$Code anon$$obj.o
+# 3. 0x106f9c72 0x00000002 PAD
+# we don't need Idx(Index) and E(Entry)
+# input: 1. Execution Name, 2. $strLine
+# output: x
+#****************************************************************************
+sub ParseInputSection
+{
+ my ($strExeRegionName, $strLine) = @_;
+ return if(!defined $strExeRegionName); ### setting for $strExeRegionName = undef
+
+ my ($strBaseAddress, $strSize, $strType, $strAttr, $strInputSection, $strObjName, $strLibName)
+ = (undef, undef, undef, undef, undef, undef, undef);
+ my $bMatchInputSection = 0;
+ chomp($strLine);
+ if($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)\s+(\w+)\s+\d+\s+\**\s+(\S+)\s+(\S+)\((\S+)\)/)
+ {
+ # Base Addr Size Type Attr Idx E Section Name Object
+ # 0x70008230 0x00000020 Code RO 18 * VECTOR_TBL bl_BOOTARM.obj(bootloader.lib)
+ $strBaseAddress = $1;
+ $strSize = $2;
+ $strType = $3;
+ $strAttr = $4;
+ $strInputSection = $5;
+ $strObjName = $6;
+ $strLibName = $7;
+ #print "[Pattern 1]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType, [Attr]$strAttr, [InputAttr]$strInputSection, [ObjName]$strObjName, [LibName]$strLibName\n";
+ $bMatchInputSection = 1;
+ }
+ elsif($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)\s+(\w+)\s+\d+\s+\**\s+(\S+)\s+(\S+)/)
+ {
+ # Base Addr Size Type Attr Idx E Section Name Object
+ # 0x1007bb30 0x00000008 Ven RO 402248 Veneer$$Code anon$$obj.o
+ $strBaseAddress = $1;
+ $strSize = $2;
+ $strType = $3;
+ $strAttr = $4;
+ $strInputSection = $5;
+ $strObjName = $6;
+ #print "[Pattern 2]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType, [Attr]$strAttr, [InputAttr]$strInputSection, [ObjName]$strObjName, [LibName]x\n";
+ $bMatchInputSection = 1;
+ }
+ elsif($strLine =~ /\s+(0x\w+)\s+(0x\w+)\s+(\w+)/)
+ {
+ # Base Addr Size Type Attr Idx E Section Name Object
+ # 0x106f9c72 0x00000002 PAD
+ $strBaseAddress = $1;
+ $strSize = $2;
+ $strType = $3;
+ #print "[Pattern 3]$strLine:\n[Base]$strBaseAddress, [Size]$strSize, [Type]$strType\n";
+ $bMatchInputSection = 1;
+ }
+ if($bMatchInputSection == 1)
+ {
+ $g_InputSectionDetails{$g_InputSectionCount} = [$strExeRegionName, $strBaseAddress, $strSize,
+ $strType, $strAttr, $strInputSection,
+ $strObjName, $strLibName];
+ push (@{$g_InputSections{$strExeRegionName}}, $g_InputSectionCount);
+ $g_InputSectionCount++;
+ }
+}
+
+#****************************************************************************
+# subroutine: ListPadInfo
+# input: N/A
+# output: array reference
+# for lis file, array content:[array1,array2,...]
+# array1:[strPadBaseAddress,strPreSymName,strPreSymAddress,strPostSymName,strPostSymAddress]
+#****************************************************************************
+sub ListPadInfo
+{
+ my @padstring;
+ foreach my $key (sort keys %g_InputSectionDetails)
+ {
+ my $type = $g_InputSectionDetails{$key}->[3];
+ next if ($type ne "PAD");
+ my $base_address = $g_InputSectionDetails{$key}->[1];
+ my $pre_address = $g_InputSectionDetails{$key-1}->[1];
+ my $pre_symbol = $g_InputSectionDetails{$key-1}->[5];
+ my $post_address = $g_InputSectionDetails{$key+1}->[1];
+ my $post_symbol = $g_InputSectionDetails{$key+1}->[5];
+
+ my @padinfo = [$base_address,$pre_symbol,$pre_address,$post_symbol,$post_address];
+ push (@padstring, @padinfo);
+ }
+ return \@padstring;
+}
+
+#****************************************************************************
+# subroutine: ParseDebugInfo
+# input: $strObjDebug, $strLine
+# output: N/A
+#****************************************************************************
+sub ParseDebugInfo
+{
+ my ($strObjDebug, $strLine) = @_;
+ return if(!$strObjDebug);
+ ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
+ chomp($strLine);
+ if($strLine =~ /\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+(\S+\.obj$|\S+\.o$)/)
+ {
+ $debugInfoSize{$2} = $1;
+ }
+}
+
+#****************************************************************************
+# subroutine: GetObjSummaryInfo
+# input: flag $strObjDebug, $strLine
+# output: N/A
+#****************************************************************************
+sub GetObjSummaryInfo
+{
+ my ($strObjDebug, $strLine) = @_;
+ return if(!$strObjDebug);
+ ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
+ chomp($strLine);
+ if($strLine =~ /\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+\.obj$|\S+\.o$)/)
+ {
+ $ObjSummary{$7} = [$1,$2,$3,$4,$5,$6];
+ }
+}
+
+#****************************************************************************
+# subroutine: GetLibSummaryInfo
+# input: flag $strLibDebug, $strLine
+# output: N/A
+#****************************************************************************
+sub GetLibSummaryInfo
+{
+ my ($strLibDebug, $strLine) = @_;
+ return if(!$strLibDebug);
+ ### 0 0 7341676 0 0 0 IG_FT_CH_320X480.obj
+ chomp($strLine);
+ if($strLine =~ /\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+\.lib$|\S+\.l$|\S+\.a$)/)
+ {
+ $LibSummary{$7} = [$1,$2,$3,$4,$5,$6];
+ }
+}
+
+#****************************************************************************
+# subroutine: ListObjSummaryInfo
+# input: obj name, flag represents which column to show
+# flag = "Code"
+# = "inc.data"
+# = "RO Data"
+# = "RW Data"
+# = "ZI Data"
+# = "Debug"
+# output: Code/inc.data/RO Data/RW Data/ZI Data/Debug size for given obj
+#****************************************************************************
+sub ListObjSummaryInfo
+{
+ my ($strObjName, $flag) = @_;
+ foreach my $key (keys %ObjSummary)
+ {
+ next if ($strObjName ne $key);
+ my $ObjSummaryInfo = $ObjSummary{$key};
+ if ($flag eq "Code")
+ {
+ return @$ObjSummaryInfo[0];
+ }
+ elsif ($flag eq "inc.data")
+ {
+ return @$ObjSummaryInfo[1];
+ }
+ elsif ($flag eq "RO Data")
+ {
+ return @$ObjSummaryInfo[2];
+ }
+ elsif ($flag eq "RW Data")
+ {
+ return @$ObjSummaryInfo[3];
+ }
+ elsif ($flag eq "ZI Data")
+ {
+ return @$ObjSummaryInfo[4];
+ }
+ elsif ($flag eq "Debug")
+ {
+ return @$ObjSummaryInfo[5];
+ }
+ }
+}
+
+#****************************************************************************
+# subroutine: ListLibSummaryInfo
+# input: lib name, flag represents which column to show
+# flag = "Code"
+# = "inc.data"
+# = "RO Data"
+# = "RW Data"
+# = "ZI Data"
+# = "Debug"
+# output: Code/inc.data/RO Data/RW Data/ZI Data/Debug size for given lib
+#****************************************************************************
+sub ListLibSummaryInfo
+{
+ my ($strLibName, $flag) = @_;
+ foreach my $key (keys %LibSummary)
+ {
+ next if ($strLibName ne $key);
+ my $LibSummaryInfo = $LibSummary{$key};
+ if ($flag eq "Code")
+ {
+ return @$LibSummaryInfo[0];
+ }
+ elsif ($flag eq "inc.data")
+ {
+ return @$LibSummaryInfo[1];
+ }
+ elsif ($flag eq "RO Data")
+ {
+ return @$LibSummaryInfo[2];
+ }
+ elsif ($flag eq "RW Data")
+ {
+ return @$LibSummaryInfo[3];
+ }
+ elsif ($flag eq "ZI Data")
+ {
+ return @$LibSummaryInfo[4];
+ }
+ elsif ($flag eq "Debug")
+ {
+ return @$LibSummaryInfo[5];
+ }
+ }
+}
+
+#****************************************************************************
+# subroutine: GetInputSectionsByExeRegion
+# input: $strExeRegionName: Execution Name (Case sensitive)
+# output: Array_ref : InputSections: [[ExeRegionName, Base...], [ExeRegionName, Base...], ...]
+# [ExeRegionName, Base...]: InputSectionDetails elements
+#****************************************************************************
+sub GetInputSectionsByExeRegion
+{
+ my ($strExeRegionName) = @_;
+ my @InputSections;
+ my $Indexes = $g_InputSections{$strExeRegionName}; ### array
+ foreach my $nIndex (@$Indexes)
+ {
+ push(@InputSections, $g_InputSectionDetails{$nIndex}); ## $g_InputSectionDetails{$g_InputSectionCount} = [$strExeRegionName, $strBaseAddress, $strSize, $strType, $strAttr, $strInputSection, $strObjName, $strLibName];
+ }
+ return \@InputSections;
+}
+
+#****************************************************************************
+# subroutine: GetObjTotalSizesByExeRegion
+# input: $strRegionName: Execution Name (Case sensitive)
+# output: ObjTotalSize Hash Reference: {ObjName::LibName} => nSize
+# sample code:
+# my $strExeRegionName = "xxx";
+# my $nObjTotalSize_ref = &LISInfo::GetObjTotalSizesByExeRegion($strExeRegionName);
+# foreach my $Obj_LibName (keys %$nObjTotalSize_ref) {...}
+# => $Obj_LibName: "ObjName::LibName"
+#****************************************************************************
+sub GetObjTotalSizesByExeRegion
+{
+ my ($strExeRegionName) = @_;
+ my %nObjTotalSize; # {ObjName_LibName} = nSize;
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ObjName])
+ {
+ my $strKey = $Info->[ExecutionRegion::ObjName]."::".$Info->[ExecutionRegion::LibName];
+ if(exists $nObjTotalSize{$strKey})
+ {
+ $nObjTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
+ }
+ else
+ {
+ $nObjTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
+ }
+ }
+ else #PAD
+ {
+ $nObjTotalSize{"PAD"} += hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ return \%nObjTotalSize;
+}
+
+#****************************************************************************
+# subroutine: GetObjSizeByCatExeRegion
+# input: $strRegionName: Execution Name (Case sensitive)
+# $strCategory: RO Data/RW Data/ZI Data/Code (Case sensitive)
+# output: ObjCateSize Hash Reference
+#****************************************************************************
+sub GetObjSizeByCatExeRegion
+{
+ my ($strExeRegionName, $strCategory) = @_;
+ my %nObjROSize;
+ my %nObjRWSize;
+ my %nObjZISize;
+ my %nObjCodeSize;
+
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ObjName])
+ {
+ my $strKey = $Info->[ExecutionRegion::ObjName];
+
+ if(($strCategory eq "RO Data") && ($Info->[ExecutionRegion::Type] eq "Data") && ($Info->[ExecutionRegion::Attr] eq "RO"))
+ {
+ if(exists $nObjROSize{$strKey})
+ {
+ $nObjROSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ }
+ else
+ {
+ $nObjROSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ elsif(($strCategory eq "RW Data") && ($Info->[ExecutionRegion::Type] eq "Data") && ($Info->[ExecutionRegion::Attr] eq "RW"))
+ {
+ if(exists $nObjRWSize{$strKey})
+ {
+ $nObjRWSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ }
+ else
+ {
+ $nObjRWSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ elsif(($strCategory eq "ZI Data") && ($Info->[ExecutionRegion::Type] eq "Zero") && ($Info->[ExecutionRegion::Attr] eq "RW"))
+ {
+ if(exists $nObjZISize{$strKey})
+ {
+ $nObjZISize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ }
+ else
+ {
+ $nObjZISize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ elsif(($strCategory eq "Code") && ($Info->[ExecutionRegion::Type] eq "Code") && ($Info->[ExecutionRegion::Attr] eq "RO"))
+ {
+ if(exists $nObjCodeSize{$strKey})
+ {
+ $nObjCodeSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ }
+ else
+ {
+ $nObjCodeSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ }
+ }
+
+ if($strCategory eq "RO Data")
+ {
+ return \%nObjROSize;
+ }
+ elsif($strCategory eq "RW Data")
+ {
+ return \%nObjRWSize;
+ }
+ elsif($strCategory eq "ZI Data")
+ {
+ return \%nObjZISize;
+ }
+ elsif($strCategory eq "Code")
+ {
+ return \%nObjCodeSize;
+ }
+}
+
+
+#****************************************************************************
+# subroutine: GetTotalSizeByExeRegion
+# input: $strRegionName: Execution Region Name (Case sensitive)
+# output: total size for given execution region
+#****************************************************************************
+sub GetTotalSizeByExeRegion
+{
+ my ($strExeRegionName) = @_;
+ my %nExeRegionTotalSize; # {ObjName_LibName} = nSize;
+ my $TotalSize;
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ExeRegionName])
+ {
+ my $strKey = $Info->[ExecutionRegion::ExeRegionName];
+ if(exists $nExeRegionTotalSize{$strKey})
+ {
+ $nExeRegionTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
+ }
+ else
+ {
+ $nExeRegionTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
+ }
+ $TotalSize = $nExeRegionTotalSize{$strKey};
+ }
+ }
+ return $TotalSize;
+}
+
+#****************************************************************************
+# subroutine: GetObjByExeRegion
+# input: Execution Region Name (Case sensitive)
+# output: OBJ array reference which given execution region contains
+#****************************************************************************
+sub GetObjByExeRegion
+{
+ my ($strExeRegionName) = @_;
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
+ my @obj;
+ my @uni_objs;
+ my %count;
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ObjName])
+ {
+ my $strObj = $Info->[ExecutionRegion::ObjName];
+ push(@obj, $strObj);
+ }
+ }
+ @uni_objs = grep { ++$count{ $_ } < 2; } @obj;
+ return \@uni_objs;
+}
+
+#****************************************************************************
+# subroutine: GetLibByExeRegion
+# input: Execution Region Name (Case sensitive)
+# output: LIB array reference which given execution region contains
+#****************************************************************************
+sub GetLibByExeRegion
+{
+ my ($strExeRegionName) = @_;
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegionName);
+ my @lib;
+ my @uni_libs;
+ my %count;
+ foreach my $Info (@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::LibName])
+ {
+ my $strLib = $Info->[ExecutionRegion::LibName];
+ push(@lib, $strLib);
+ }
+ }
+ @uni_libs = grep { ++$count{ $_ } < 2; } @lib;
+ return \@uni_libs;
+}
+
+#****************************************************************************
+# subroutine: GetLibSizeByExeRegion
+# input: Execution Region Name, Library Name (Case sensitive)
+# output: size of given library in givin execution region
+#****************************************************************************
+sub GetLibSizeByExeRegion
+{
+ my ($strExeRegion, $strLib) = @_;
+ my $InputSections_ref = &GetInputSectionsByExeRegion($strExeRegion);
+ my $size = 0;
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if($Info->[ExecutionRegion::LibName] eq $strLib)
+ {
+ $size += hex($Info->[ExecutionRegion::Size]);
+ }
+ }
+ return $size;
+}
+
+#****************************************************************************
+# subroutine: GetTotalSizeByLib
+# input: $strLibName: Library Name (Case sensitive)
+# output: total size for given library
+#****************************************************************************
+sub GetTotalSizeByLib
+{
+ my ($strLibName) = @_;
+ my %nLibTotalSize;
+ my $TotalSize;
+ foreach my $ExeRegion (@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info ( @$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::LibName])
+ {
+ my $strKey = $Info->[ExecutionRegion::LibName];
+ next if ($strKey ne $strLibName);
+ if(exists $nLibTotalSize{$strKey})
+ {
+ $nLibTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
+ }
+ else
+ {
+ $nLibTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
+ }
+ $TotalSize = $nLibTotalSize{$strKey};
+ }
+ }
+ }
+ return $TotalSize;
+}
+
+#****************************************************************************
+# subroutine: GetTotalSizeByObj
+# input: $strObjName: Obj Name, $strLibName: Library Name (Case sensitive)
+# output: total size for given (obj, library)
+#****************************************************************************
+sub GetTotalSizeByObj
+{
+ my ($strObjName, $strLibName) = @_;
+ my %nObjTotalSize;
+ my $TotalSize;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ObjName])
+ {
+ my $strKey = $Info->[ExecutionRegion::ObjName]."::".$Info->[ExecutionRegion::LibName];
+ my $Key = $strObjName."::".$strLibName;
+ next if ($Key ne $strKey);
+ if(exists $nObjTotalSize{$strKey})
+ {
+ $nObjTotalSize{$strKey} += hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". $ObjTotalSize{$strKey} ."\n";
+ }
+ else
+ {
+ $nObjTotalSize{$strKey} = hex($Info->[ExecutionRegion::Size]);
+ #print "$strKey = ". hex($Info->[InputSection::Size])."\n";
+ }
+ $TotalSize = $nObjTotalSize{$strKey};
+ }
+ }
+ }
+ return $TotalSize;
+}
+
+#****************************************************************************
+# subroutine: ListObjLibBySymbol
+# input: $SymName: Symbol Name (Case sensitive)
+# output: [obj, library] list array reference
+#****************************************************************************
+sub ListObjLibBySymbol
+{
+ my ($SymName) = @_;
+ my @obj_lib;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::SectionAttr])
+ {
+ my $strKey = $Info->[ExecutionRegion::SectionAttr];
+ if($strKey eq $SymName)
+ {
+ my $ObjName = $Info->[ExecutionRegion::ObjName];
+ my $LibName = $Info->[ExecutionRegion::LibName];
+ push(@obj_lib, [$ObjName, $LibName]);
+ }
+ }
+ }
+ }
+ return \@obj_lib;
+}
+
+#****************************************************************************
+# subroutine: ListObjByLib
+# input: $LibName: Library Name (Case sensitive)
+# output: obj array reference
+#****************************************************************************
+sub ListObjByLib
+{
+ my ($LibName) = @_;
+ my @obj;
+ my @uni_objs;
+ my %count;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::LibName])
+ {
+ my $strKey = $Info->[ExecutionRegion::LibName];
+ if($strKey eq $LibName)
+ {
+ my $ObjName = $Info->[ExecutionRegion::ObjName];
+ push(@obj, $ObjName);
+ }
+ }
+ }
+ }
+ @uni_objs = grep { ++$count{ $_ } < 2; } @obj;
+ return \@uni_objs;
+}
+
+#****************************************************************************
+# subroutine: ListLibByObj
+# input: $ObjName: Object Name (Case sensitive)
+# output: Library array reference
+#****************************************************************************
+sub ListLibByObj
+{
+ my ($ObjName) = @_;
+ my @lib;
+ my @uni_libs;
+ my %count;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::ObjName])
+ {
+ my $strKey = $Info->[ExecutionRegion::ObjName];
+ if($strKey eq $ObjName)
+ {
+ my $LibName = $Info->[ExecutionRegion::LibName];
+ push(@lib, $LibName);
+ }
+ }
+ }
+ }
+ @uni_libs = grep { ++$count{ $_ } < 2; } @lib;
+ return \@uni_libs;
+}
+
+#****************************************************************************
+# subroutine: GetObjDebugInfoSize
+# input: $strObjName: Obj Name (Case sensitive)
+# output: debug info size for given obj
+#****************************************************************************
+sub GetObjDebugInfoSize
+{
+ my ($strObjName) = @_;
+ my $DebugInfoSize = $debugInfoSize{$strObjName};
+ return $DebugInfoSize;
+}
+
+#****************************************************************************
+# subroutine: FootprintAnalyzeBySymbol
+# input: $strSymName: Symbol Name, $strObjName: Obj Name (Case sensitive)
+# output: symbol info array reference
+#****************************************************************************
+sub FootprintAnalyzeBySymbol
+{
+ my ($strSymName, $strObjName) = @_;
+ my %SymHash;
+ my @SymInfo;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if(defined $Info->[ExecutionRegion::SectionAttr])
+ {
+ my $strKey = $Info->[ExecutionRegion::SectionAttr]."::".$Info->[ExecutionRegion::ObjName];
+ my $Key = $strSymName."::".$strObjName;
+ next if ($Key ne $strKey);
+
+ my $type = $Info->[ExecutionRegion::Type];
+ if (($type ne "Pad") && ($type ne "Ven"))
+ {
+ my $attr = $Info->[ExecutionRegion::Attr]."-".$type;
+ my $base = $Info->[ExecutionRegion::Base];
+ my $size = hex($Info->[ExecutionRegion::Size]);
+ my $region = $ExeRegion;
+ $SymHash{$strKey} = [$region, $attr, $base, $size];
+
+ push(@SymInfo, $region);
+ push(@SymInfo, $attr);
+ push(@SymInfo, $base);
+ push(@SymInfo, $size);
+ }
+ elsif ($type eq "Ven")
+ {
+ my $region = $ExeRegion;
+ my $base = $Info->[ExecutionRegion::Base];
+ my $dest = $g_VeneerLookUpTable{$base};
+ my $size = hex($Info->[ExecutionRegion::Size]);
+ $SymHash{$strKey} = [$region, $type, $base, $size, $dest];
+
+ push(@SymInfo, $region);
+ push(@SymInfo, $type);
+ push(@SymInfo, $base);
+ push(@SymInfo, $size);
+ push(@SymInfo, $dest);
+ }
+ }
+ }
+ }
+ return \@SymInfo;
+}
+
+#****************************************************************************
+# subroutine: GetVeneerInfo
+# input: N/A
+# output: [Execution Region, Base Address, Size, DestinationSymbolName] array reference for veneer
+#****************************************************************************
+sub GetVeneerInfo
+{
+ my @veneers;
+ foreach my $ExeRegion(@ExeRegions)
+ {
+ my $InputSections_ref = &GetInputSectionsByExeRegion($ExeRegion);
+ foreach my $Info(@$InputSections_ref)
+ {
+ if($Info->[ExecutionRegion::Type] eq "Ven")
+ {
+ my $base = $Info->[ExecutionRegion::Base];
+ my $size = hex($Info->[ExecutionRegion::Size]);
+ my $dest = $g_VeneerLookUpTable{$base};
+ my @veneerinfo = [$ExeRegion, $base, $size, $dest];
+ push(@veneers, @veneerinfo);
+ }
+ }
+ }
+ return \@veneers;
+}
+
+#****************************************************************************
+# subroutine: GetExeRegionInfo - Get Execution Region information
+# input: $strRegionName: Execution Name (Case sensitive)
+# $nOption: ExecutionRegion::Base
+# ExecutionRegion::Size
+# ExecutionRegion::MaxSize
+# ExecutionRegion::Attr
+# output: required Region Base address, Used Size, Region MaxSize, Attribute info
+#****************************************************************************
+sub GetExeRegionInfo
+{
+ my ($strRegionName, $nOption) = @_;
+ my ($nBase, $nSize, $nMaxSize, $strAttribute) = (0,0,0,'');
+ my $nIndex = $g_ExeRegionLookUpTable{$strRegionName};
+ my $strInfo;
+ if(defined $nIndex)
+ {
+ if($nOption == ExecutionRegion::Base)
+ {
+ $strInfo = &CommonUtil::Dec2Hex($g_ExeRegion{$nIndex}->[ExecutionRegion::Base]);
+ }
+ elsif($nOption == ExecutionRegion::Size)
+ {
+ $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::Size];
+ }
+ elsif($nOption == ExecutionRegion::MaxSize)
+ {
+ $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::MaxSize];
+ }
+ elsif($nOption == ExecutionRegion::Attr)
+ {
+ $strInfo = $g_ExeRegion{$nIndex}->[ExecutionRegion::Attr];
+ }
+ }
+ return $strInfo;
+}
+
+#****************************************************************************
+# subroutine: GetLoadRegionInfo - Get Load Region information
+# input: $strRegionName: Execution Name (Case sensitive)
+# $nOption: LoadRegion::Base
+# LoadRegion::Size
+# LoadRegion::MaxSize
+# LoadRegion::Attr
+# output: required Region Base address, Used Size, Region MaxSize, Attribute infosub GetLoadRegionInfo
+#****************************************************************************
+sub GetLoadRegionInfo
+{
+ my ($strRegionName, $nOption) = (@_);
+ my ($nBase, $nSize, $nMaxSize, $strAttribute) = (0,0,0,'');
+ my $nIndex = $g_LoadRegionLookUpTable{$strRegionName};
+ my $strInfo;
+ if(defined $nIndex)
+ {
+ if($nOption == LoadRegion::Base)
+ {
+ $strInfo = &CommonUtil::Dec2Hex($g_LoadRegion{$nIndex}->[LoadRegion::Base]);
+ }
+ elsif($nOption == LoadRegion::Size)
+ {
+ $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::Size];
+ }
+ elsif($nOption == LoadRegion::MaxSize)
+ {
+ $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::MaxSize];
+ }
+ elsif($nOption == LoadRegion::Attr)
+ {
+ $strInfo = $g_LoadRegion{$nIndex}->[LoadRegion::Attr];
+ }
+ }
+ return $strInfo;
+}
+
+#****************************************************************************
+# subroutine: GetTotalROSize - Get total RO size
+# input: $bNeedString: 1=Return string, 0/default/no input=Return int
+# output: $bNeedString=0:nROSize/ $bNeedString=1:strROSize
+#****************************************************************************
+sub GetTotalROSize
+{
+ my ($bNeedString) = @_;
+ return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalROSize) : $g_nTotalROSize;
+}
+
+#****************************************************************************
+# subroutine: GetTotalRWZISize - Get total RWZI size
+# input: $bNeedString: 1=Return string, 0/default/no input=Return int
+# output: $bNeedString=0:nRWZISize/ $bNeedString=1:strRWZISize
+#****************************************************************************
+sub GetTotalRWZISize
+{
+ my ($bNeedString) = @_;
+ return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalRWZISize) : $g_nTotalRWZISize;
+}
+
+#****************************************************************************
+# subroutine: GetTotalROMSize - Get total ROM size
+# input: $bNeedString: 1=Return string, 0/default/no input=Return int
+# output: $bNeedString=0:nROMSize/ $bNeedString=1:strROMSize
+#****************************************************************************
+sub GetTotalROMSize
+{
+ my ($bNeedString) = @_;
+ return $bNeedString ? &CommonUtil::Dec2Hex($g_nTotalROMSize) : $g_nTotalROMSize;
+}
+
+1;
\ No newline at end of file