blob: efdd13ffd83f93d2abff2cd32221a256785df773 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* FileInfoParser.pm
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This module collects the subroutines for common utility.
48#*
49#*
50#* Author:
51#* -------
52#* Carl Kao (mtk08237)
53#*
54#****************************************************************************/
55
56use strict;
57BEGIN{push(@INC,'../', './tools/', './tools/MemoryUtility/')};
58use CommonUtility;
59use Digest::MD5;
60
61package Region;
62use constant Size => 1;
63use constant VMA => 2;
64use constant LMA => 3;
65use constant Offsets => 4;
66use constant Align => 5;
67use constant Attr => 6;
68
69# for %g_SymTable = ();
70package SymTable;
71use constant Name => 0;
72use constant Addr => 1;
73use constant Group => 2;
74use constant Region => 3;
75use constant Size => 4;
76use constant Obj => 5;
77use constant NeedMerge => 6;
78
79# for %symbol = ();
80package Symbol;
81use constant Addr => 0;
82use constant Region => 3;
83use constant Size => 4;
84
85# for %g_LinkerSymbol = ();
86package LinkerSymbol;
87use constant Addr => 0;
88use constant Group => 1;
89use constant Region => 2;
90use constant Size => 3;
91
92package LinkerSymPostfix;
93use constant Base => 0;
94use constant Limit => 1;
95use constant ZIBase => 2;
96use constant ZILimit => 3;
97use constant Length => 4;
98use constant ZILength => 5;
99
100package LinkerSymPrefix;
101use constant Image => 0;
102use constant Load => 1;
103use constant None => 2;
104
105#****************************************************************************
106# Constants
107#****************************************************************************
108my $SYM_FILE_PARSER_VERNO = " u0.07";
109 # u0.07 , 2015/10/28, Carl, Support LinkerSymPostfix::ZILength
110 # u0.06 , 2015/01/22, Carl, Add parsing rule for GCC 4.9.3
111 # u0.05 , 2015/01/19, Carl, Memory Utility Refinement
112 # u0.04, 2014/09/26, Carl, Add constant for LinkerSymPrefix
113 # u0.03, 2014/09/16, Carl, Add parsing rule for GCC 4.9.2
114 # u0.02, 2014/03/03, BM, Refine inculde path
115 # u0.01, 2014/02/20, BM, Init version, branch from MOLY
116
117#****************************************************************************
118# Global variable
119#****************************************************************************
120package SymFileParser;
121
122my $g_SYMPath;
123my %symbol;
124my $DUMMY_END_size;
125my $DUMMY_END_base;
126my %g_SymTable; # $strAddress.$strSymbolName => [strSymbol, $strAddress, strGroup, strRegion, nSize]
127my %g_LinkerSymbol; # $strSymbolName => [$strAddress, strGroup, strRegion, nSize]
128my %g_static_symbol_loookup; #$strSymbolName.".".$strObjName = [$strAddress, strGroup, strRegion, nSize]
129
130my $g_PreviousParsedSYMChecksum;
131my $g_PreviousParsedSYMPath;
132
133my %g_ExeRegion;# Execution Region
134my %g_ExeRegionLookUpTable; # RegionName -> Index
135my %Attr;
136
137#****************************************************************************
138# oo >>> Finished
139#****************************************************************************
140return 1;
141
142#****************************************************************************
143# subroutine: SYM_die
144# sample code: (message, __FILE__, __LINE__)
145# input: $error_msg, $file, $line_no
146#****************************************************************************
147sub SYM_die
148{
149 my ($error_msg, $file, $line_no) = (@_);
150 &CommonUtil::error_handler($error_msg, $file, $line_no, 'SYM');
151}
152
153#****************************************************************************
154# subroutine: ParseSYM
155# input: SYM Path string
156# output: x
157#****************************************************************************
158sub Clean
159{
160 %symbol = ();
161 %g_ExeRegion = ();
162 %g_ExeRegionLookUpTable = ();
163 %g_SymTable = ();
164 %g_LinkerSymbol = ();
165 %Attr = ();
166 $DUMMY_END_size = 0;
167 $DUMMY_END_size = 0;
168}
169
170sub ParseSYM
171{
172 ($g_SYMPath) = (@_);
173 if(defined $g_SYMPath and -e $g_SYMPath)
174 {
175 open (my $fh, '<', $g_SYMPath) or &SYM_die("$g_SYMPath: file error!", __FILE__, __LINE__);
176 binmode ($fh);
177 my $SYMChecksum = Digest::MD5->new->addfile($fh)->hexdigest;
178
179 if($g_SYMPath eq $g_PreviousParsedSYMPath and $SYMChecksum eq $g_PreviousParsedSYMChecksum)
180 {
181 #print "Sym File: $g_SYMPath was parsed before and not modified, skip PasrseSYM\n";
182 close($fh);
183 return;
184 }
185 close($fh);
186
187 Clean();
188 open (FILE_HANDLE, "<$g_SYMPath") or &SYM_die("$g_SYMPath: file error!", __FILE__, __LINE__);
189 my $strPreExeRegionName = undef;
190 my $bBegin = 0; #0= Program Header: begin, 1= Sections begin, 2=SYMBOL TABLE: begin
191 my $strObjName = undef; #parse static symbol's obj
192
193 while (<FILE_HANDLE>)
194 {
195 my $strLine = $_;
196 $bBegin = 1 if($strLine =~/^Sections:$/);#begin parse section table
197 $bBegin = 2 if($strLine =~/^SYMBOL TABLE:$/);#begin parse symbol table
198
199 if ($strLine =~ /\.hidden\s/)
200 {
201 $strObjName = undef;#no static symbol after '.hidden'
202
203 # add this rule for GCC 4.9.3
204 # [4.9.2] a0401ee4 g O CACHED_EXTSRAM 00000008 .hidden __CTOR_LIST__
205 $strLine =~ s|\.hidden\s||g;
206 }
207
208 last if($strLine =~/^RELOCATION RECORDS FOR \[ROM\]:$/);
209
210 ## begin to parse section table
211 if ($bBegin == 1 and
212 $strLine =~ /\s*(\d+)\s+(\S+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\S+)/)
213 { # Idx Name Size VMA LMA File off Algn
214 # 0 BL_GFH_SECTION 00000170 7000a000 7000a000 00002000 2**2
215 $g_ExeRegion{$1}= [$2, $3, $4, $5, $6, $7];
216 $g_ExeRegionLookUpTable{$2} = $1;
217 $strPreExeRegionName = $2;
218 next;
219 }
220 elsif($bBegin == 1 and defined $strPreExeRegionName)
221 { #parse section attribution
222 &ParseInputSection($strPreExeRegionName, $strLine);
223 next;
224 }
225
226 ## begin to parse symbol table
227 $strObjName = ParseSymbolTable($strLine,$strObjName) if($bBegin == 2);
228
229 if ($bBegin ==2 and $strLine =~ /DUMMY_END\$\$Base/)
230 { # f3fc0000 g *ABS* 00000000 Image$$CACHED_DUMMY_END$$Base
231
232 if(/^(\w+)\s+(\w+)\s+(.*)\s+(\w+)/)
233 {
234 $DUMMY_END_size = hex($4);
235 $DUMMY_END_base = "0x".$1;
236 }
237 next;
238 }
239 elsif ($bBegin ==2 and
240 $strLine =~ /^(\w+)\s+(\w+)\s+(\w+)\s+(\S+)\s+(\w+)\s+(\w+)$/)
241 { # 7000a000 l d BL_GFH_SECTION 00000000 BL_GFH_SECTION
242 next if (($2 ne "g") && ($2 ne "l") && ($2 ne "w"));
243 next if (($3 ne "F") && ($3 ne "O"));
244 my $symbol_name = $6;
245 my $base_address = $1;
246 my $execution_region = $4;
247 my $size = $5;
248 $symbol{$symbol_name} = [$1, $2, $3, $4, $5];
249 next;
250 }
251 elsif ($bBegin ==2 and
252 $strLine =~ /^(\w+)\s+(\w+)\s+(\w+)\s+(\S+)\s+(\w+)\s+(\w+)\s+(\w+)$/)
253 { # 901c2ae8 g F ROM 00000048 0xf0 EL1D_LPWR_Other_Core_Has_Run_Determine
254 next if (($2 ne "g") && ($2 ne "l") && ($2 ne "w"));
255 next if (($3 ne "F") && ($3 ne "O"));
256 my $symbol_name = $7;
257 my $base_address = $1;
258 my $execution_region = $4;
259 my $size = $5;
260 $symbol{$symbol_name} = [$1, $2, $3, $4, $5];
261 next;
262 }
263
264 }
265 close FILE_HANDLE;
266 &FixInputSectionLMAValue();
267
268 #record parsed sym file path and file checksum
269 $g_PreviousParsedSYMPath = $g_SYMPath;
270 $g_PreviousParsedSYMChecksum = $SYMChecksum;
271 }
272 else
273 {
274 &SYM_die("SYM Path($g_SYMPath) doesn't exist", __FILE__, __LINE__);
275 }
276}
277
278sub ParseSymbolTable
279{
280 my ($strLine,$strObjName) = @_;
281 my $bSearched = 0;
282 my ($strSymbolName, $strAddress, $strGroup, $strRegion, $nSize);
283
284 if($strLine =~ /^(\w+)\s+l\s+df\s+\*ABS\*\s+\w+\s+.+\\(\S+)\./
285 ||$strLine =~ /^(\w+)\s+l\s+df\s+\*ABS\*\s+\w+\s+.+\/(\S+)\./)
286 { #parse file name
287 #00000000 l df *ABS* 00000000 protocol/as_multimode/dbme/src/db_io.c
288 $strObjName = $2.".obj";
289 }
290 elsif($strLine =~ /^(\w+)\s+l\s+df\s+\*ABS\*\s+\w+\s+(\S+)\./)
291 { #parse file name
292 #00000000 l df *ABS* 00000000 db_io.c
293 $strObjName = $2.".obj";
294 }
295 elsif($strLine =~ /^(\w+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\w+)\s+(\S+)\s+(\w+|\w+\.\d+)(\.\D\S+\.\d+)?$/)
296 {#90338508 g F ROM 0000002e 0xf0 FT_GetDiskFreeSpace
297 ($strSymbolName, $strAddress, $strGroup, $strRegion, $nSize) = ($7, "0x".$1, $2.$3, $4, hex($5));
298 $bSearched = 1;
299 }
300 elsif($strLine =~ /^(\w+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\w+)\s+(\w+|\w+\.\d+)(\.\D\S+\.\d+)?$/)
301 {#0001622c l F ROM 000001b4 ast_hif_mcu_lisr_handler
302 ($strSymbolName, $strAddress, $strGroup, $strRegion, $nSize) = ($6, "0x".$1, $2.$3, $4, hex($5));
303 $bSearched = 1;
304 }
305 elsif($strLine =~ /^(\w+)\s+(\S+)\s+(\S+)\s+(\w+)\s+(\w+|\w+\.\d+)(\.\D\S+\.\d+)?$/)
306 {#90004200 l ROM 00000000 IRQ0_VEC
307 ($strSymbolName, $strAddress, $strGroup, $strRegion, $nSize) = ($5, "0x".$1, $2, $3, hex($4));
308 $bSearched = 1;
309 }
310 elsif($strLine =~ /^(\w+)\s+(\S+)\s+(\S+)\s+(\w+)\s+(\S+\$\$\S+)$/)
311 {#f06185f1 g CACHED_EXTSRAM 00000000 BUILD_TIME_RW$$Base
312 ($strSymbolName, $strAddress, $strGroup, $strRegion, $nSize) = ($5, "0x".$1, $2, $3, hex($4));
313 $bSearched = 1;
314 }
315
316 if($bSearched)
317 {
318 if($strGroup ne "l" and $strGroup ne "ldf" and $strGroup ne "ld")
319 {#skip 00000000 l *ABS* 00000000 MT6589
320 #skip 00000000 l df *ABS* 00000000 ft_fnc_fat.c
321
322 ## parse linker symbol
323 if($strSymbolName =~ /\$\$/ and (($strGroup eq "g") or ($strGroup eq "w")))
324 {
325 $g_LinkerSymbol{$strSymbolName} = [$strAddress, $strGroup, $strRegion, $nSize];
326 }
327
328 ##parse static symbol
329 elsif($strObjName and (($strGroup eq "lO") or ($strGroup eq "lF")))
330 {
331 #******************************************
332 # Static symbol need to be merged
333 #
334 # Before merge:
335 # 900bcdf0 l F ROM 00000230 ssleay_rand_add.part.0
336 # 900bd020 l F ROM 00000008 ssleay_rand_add
337 #
338 # After merge:
339 # 900bcdf0 l F ROM 00000238 ssleay_rand_add
340 #******************************************
341
342 my $need_merge = ($strLine=~/\.part\./)?1:0;
343
344 if($g_static_symbol_loookup{$strSymbolName.".".$strObjName} && ($need_merge || $g_static_symbol_loookup{$strSymbolName.".".$strObjName}->[SymTable::NeedMerge]))
345 {
346 if($g_static_symbol_loookup{$strSymbolName.".".$strObjName}->[SymTable::Addr] <= $strAddress)
347 {
348 $strAddress = $g_static_symbol_loookup{$strSymbolName.".".$strObjName}->[SymTable::Addr];
349 }
350 else
351 {
352 delete $g_SymTable{$strAddress.".".$strSymbolName};
353 }
354
355 $nSize += $g_static_symbol_loookup{$strSymbolName.".".$strObjName}->[SymTable::Size];
356 $g_static_symbol_loookup{$strSymbolName.".".$strObjName} = [$strSymbolName,$strAddress, $strGroup, $strRegion, $nSize, $strObjName, $need_merge];
357 $g_SymTable{$strAddress.".".$strSymbolName} = [$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName];
358 }
359 else
360 {
361 $g_static_symbol_loookup{$strSymbolName.".".$strObjName} = [$strSymbolName,$strAddress, $strGroup, $strRegion, $nSize, $strObjName, $need_merge];
362 $g_SymTable{$strAddress.".".$strSymbolName} = [$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize,$strObjName];
363 }
364 }
365 ## parse global symbol
366 else
367 {
368 print "$strAddress.$strSymbolName appears before\n" if(exists $g_SymTable{$strAddress.".".$strSymbolName});
369 $g_SymTable{$strAddress.".".$strSymbolName} = [$strSymbolName, $strAddress, $strGroup, $strRegion, $nSize];
370 }
371 }
372 elsif($strGroup eq "l" && $strSymbolName =~ /\$\$/)
373 {# add this rule for GCC 4.9.2
374 # 01400000 l L1CORE_RWZI 00000000 Image$$L1CORE_RWZI$$ZI$$Base
375 $g_LinkerSymbol{$strSymbolName} = [$strAddress, $strGroup, $strRegion, $nSize];
376 }
377 }
378 return $strObjName;
379}
380
381#****************************************************************************
382# subroutine: GetSymbolTable
383# input: N/A
384# output: get all symbol table in .sym file
385#
386#****************************************************************************
387sub GetSymbolTable
388{
389 my @symbol = values %g_SymTable;
390 return \@symbol;
391}
392
393#****************************************************************************
394# subroutine: GetSymbol
395# input: N/A
396# output: get all symbol info in .sym file
397# NOTE: The info for global symbol is right;
398# but for static symbol which has same name with other symbol, the info maybe wrong.
399#****************************************************************************
400sub GetSymbol
401{
402 return \%symbol;
403}
404
405sub GetLinkerSymbol
406{
407 return \%g_LinkerSymbol;
408}
409
410sub GrepSymbolBySection
411{
412 my ($strSection) = @_;
413 my @SymKeys = sort { hex($g_SymTable{$a}->[SymTable::Addr]) <=> hex($g_SymTable{$b}->[SymTable::Addr]) }
414 grep{$g_SymTable{$_}->[SymTable::Region] eq $strSection} keys %g_SymTable;
415 #map {print $_."\n"} @SymKeys;
416 my @SymInfo = map {$g_SymTable{$_}} @SymKeys;
417 return \@SymInfo;
418}
419
420sub GrepSymbolByOutputSection
421{
422 my ($strSection) = @_;
423 my $strStart = GetLinkerSymbolAddress($strSection, LinkerSymPostfix::Base, LinkerSymPrefix::Image);
424 my $strEnd = GetLinkerSymbolAddress($strSection, LinkerSymPostfix::ZILimit, LinkerSymPrefix::Image);
425 my @SymInfo;
426
427 if((hex($strEnd) - hex($strStart)) > 0)
428 {
429 my @SymKeys = sort { hex($g_SymTable{$a}->[SymTable::Addr]) <=> hex($g_SymTable{$b}->[SymTable::Addr]) }
430 grep{(hex($g_SymTable{$_}->[SymTable::Addr]) >= hex($strStart)) and
431 (hex($g_SymTable{$_}->[SymTable::Addr]) < hex($strEnd ))} keys %g_SymTable;
432 @SymInfo = map {$g_SymTable{$_}} @SymKeys;
433 }
434 return \@SymInfo;
435}
436
437#****************************************************************************
438# subroutine: GetLinkerSymbolAddress
439# input: $strRegionName, $nLocation, $nRegionType
440# output: $strAddr
441# NOTE:
442# nRegionType = 0: Execution Region
443# nRegionType = 1: Load Region
444# nRegionType = 2: Input Section
445#****************************************************************************
446sub GetLinkerSymbolAddress
447{
448 my ($strRegionName, $nLocation, $nRegionType) = @_;
449 my $strPrefix = 'Image$$';
450 if($nRegionType == 1)
451 {
452 $strPrefix = 'Load$$' ;
453 $nLocation = 0;
454 }
455 elsif($nRegionType == 2)
456 {
457 $strPrefix = "";
458 }
459 my $strPostfix = '$$Base'; #LinkerSymPostfix::Base
460 $strPostfix = '$$Limit' if($nLocation == LinkerSymPostfix::Limit);
461 $strPostfix = '$$ZI$$Base' if($nLocation == LinkerSymPostfix::ZIBase);
462 $strPostfix = '$$ZI$$Limit' if($nLocation == LinkerSymPostfix::ZILimit);
463 $strPostfix = '$$Length' if($nLocation == LinkerSymPostfix::Length);
464 $strPostfix = '$$ZI$$Length'if($nLocation == LinkerSymPostfix::ZILength);
465 my $strSymbolName = $strPrefix.uc($strRegionName).$strPostfix;
466 my $strAddr = undef;
467 $strAddr = $g_LinkerSymbol{$strSymbolName}->[0] if(exists $g_LinkerSymbol{$strSymbolName});
468 return $strAddr;
469}
470
471#****************************************************************************
472# subroutine: Get_DUMMY_END_Size
473# input: N/A
474# output: size of DUMMY_END region
475#****************************************************************************
476sub Get_DUMMY_END_Size
477{
478 return $DUMMY_END_size;
479}
480
481#****************************************************************************
482# subroutine: Get_DUMMY_END_Base
483# input: N/A
484# output: base address of DUMMY_END region
485#****************************************************************************
486sub Get_DUMMY_END_Base
487{
488 return $DUMMY_END_base;
489}
490
491#****************************************************************************
492# subroutine: StoreIntoTempFile
493# input: N/A
494# output: temp files which contain perl data structure
495#****************************************************************************
496use Storable qw/lock_nstore/;
497sub StoreIntoTempFile
498{
499 my ($strPath) = @_;
500 my $file = $strPath."\\SymParser_Temp.dat";
501 my %tempfile;
502
503 $tempfile{"execution_region"} = \%g_ExeRegion;
504 $tempfile{"symbol_info"} = \%symbol;
505
506 lock_nstore \%tempfile, $file;
507}
508
509#****************************************************************************
510# subroutine: ParseInputSection. used by ParseSYM to parse Execution Region Attribute
511# input: 1. Execution Name, 2. $strLine
512# output: x
513#****************************************************************************
514sub ParseInputSection
515{
516 my ($strExeRegionName, $strLine) = @_;
517 return if(!defined $strExeRegionName);#setting for $strExeRegionName = undef
518
519 my $attr = undef;
520 chomp($strLine);
521 if($strLine =~ /\s+(.*)/)
522 {
523 #CONTENTS, ALLOC, LOAD, READONLY, DATA
524 $Attr{$strExeRegionName} = $1;
525 }
526}
527
528#****************************************************************************
529# subroutine: FixInputSectionLMAValue is used to fix the wrong LMA value
530# record in InputSection
531# input: x
532# output: x
533#****************************************************************************
534sub FixInputSectionLMAValue
535{
536 while(my($strSymbolName, $arySymbolDataRef) = each %g_LinkerSymbol)
537 {
538 my @arySymbolData = @$arySymbolDataRef;# arySymbolData: 0x00760eb0 g *ABS* 0
539 #print "arySymbolData: @arySymbolData \n";
540 if($strSymbolName =~ /Load\$\$(\S+)\$\$Base/)# $strSymbolName = Load$$EXTSRAM_DSP_RX$$Base
541 {# Load$$EXTSRAM_DSP_RX$$Base
542 my $strExeRegionName = $1;# $strExeRegionName = EXTSRAM_DSP_RX
543
544 #check if $strExeRegionName exist in $g_ExeRegionLookUpTable
545 if(exists $g_ExeRegionLookUpTable{$strExeRegionName})
546 {
547 #extract the correct LMA value record in SymbolTable
548 my $strCorrectLMAValue = $arySymbolData[LinkerSymbol::Addr];
549 $strCorrectLMAValue =~ s/0x//;
550 #print "strCorrectLMAValue: $strCorrectLMAValue \n";
551
552 #fix LMA value stored in %g_ExeRegion
553 my $lookupIndex = $g_ExeRegionLookUpTable{$strExeRegionName};
554 #print "look up index: ".$lookupIndex."\n";
555 $g_ExeRegion{$lookupIndex}[Region::LMA] = $strCorrectLMAValue;
556 }
557 }
558 }
559}
560
561#****************************************************************************
562# subroutine: ListAllExeRegion
563# input: $bTrimDebugRegion: 1= NeedtoTrimDebugRegion, 0 or undef=NoNeedToTrimDebugRegion
564# output: Execution Region List
565#****************************************************************************
566sub ListAllExeRegion
567{
568 my ($bTrimDebugRegion) = @_;
569 my @k = keys %g_ExeRegion;
570 my @ExeRegion;
571 my $ExeRegion_aref = undef;
572 for (my $i = 0; $i <= $#k; $i++)
573 {
574 push(@ExeRegion,$g_ExeRegion{$i}->[0]);
575 }
576 $ExeRegion_aref = \@ExeRegion;
577 if($bTrimDebugRegion)
578 {
579 $ExeRegion_aref = TrimDebugRegion(\@ExeRegion);
580 }
581 return $ExeRegion_aref;
582}
583#****************************************************************************
584# subroutine: TrimDebugRegion
585# input: All Regions in array reference
586# output: Execution Region List(array reference) after trimming
587#****************************************************************************
588sub TrimDebugRegion
589{
590 my ($ERs_aref) = @_;
591 my @RealERs;
592 foreach my $region (@$ERs_aref)
593 {
594 if ( $region !~ /^\.debug_/
595 and $region !~ /^\.ARM\.attributes/
596 and $region !~ /^\.comment/
597 and $region !~ /^\.stab/
598 and $region ne "")
599 {
600 push(@RealERs , $region);
601 }
602 }
603 return \@RealERs;
604}
605
606#****************************************************************************
607# subroutine: GetExeRegionInfo
608# input: Execution Region Name, $nOption
609# $nOption = Region::VMA or Region::LMA or Region::Size
610# or Region::Offsets or Region::Align or Region::Attr
611# output: string of corresponding Execution Region Infomation
612#****************************************************************************
613sub GetExeRegionInfo
614{
615 # Name Size VMA LMA File off Algn
616 my ($strExeRegionName, $nOption) = @_;
617 my $index = $g_ExeRegionLookUpTable{$strExeRegionName};
618 my @ExeRegionInfo;
619 my $strInfo;
620 my @k = keys %g_ExeRegion;
621 my $key_count = $#k + 1;
622 for (my $i = 0; $i <= $#k; $i++)
623 {
624 my $string = $g_ExeRegion{$i}->[0];
625 next if ($string ne $strExeRegionName);
626 }
627
628 if ($nOption == Region::Size)
629 {
630 $strInfo = "0x".$g_ExeRegion{$index}->[Region::Size];
631 }
632 elsif ($nOption == Region::VMA)
633 {
634 $strInfo = "0x".$g_ExeRegion{$index}->[Region::VMA];
635 }
636 elsif ($nOption == Region::LMA)
637 {
638 $strInfo = "0x".$g_ExeRegion{$index}->[Region::LMA];
639 }
640 elsif ($nOption == Region::Offsets)
641 {
642 $strInfo = "0x".$g_ExeRegion{$index}->[Region::Offsets];
643 }
644 elsif ($nOption == Region::Align)
645 {
646 $strInfo = $g_ExeRegion{$index}->[Region::Align];
647 }
648 elsif ($nOption == Region::Attr)
649 {
650 $strInfo = $Attr{$strExeRegionName};
651 }
652
653 return $strInfo;
654}
655
656#****************************************************************************
657# subroutine: FootprintAnalyzeBySymbol
658# input: $strSymName: Symbol Name (Case sensitive)
659# output: symbol info array reference
660#****************************************************************************
661sub FootprintAnalyzeBySymbol
662{
663 return undef;
664}