[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