blob: 80fd6956f7dfec11b84d6de32374e631d43b08f7 [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001#!/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#* MapFileParser.pm
40#*
41#* Project:
42#* --------
43#*
44#*
45#* Description:
46#* ------------
47#* This perl module is used to collect information from map file
48#*
49#*
50#* Author:
51#* -------
52#* Carl Kao (mtk08237)
53#*
54#****************************************************************************/
55use strict;
56BEGIN{push(@INC,'../../tools/', './tools/', './tools/MemoryUtility/')};
57use CommonUtility;
58
59package SymbolInfoTable;
60use constant SymbolName => 0;
61use constant Addr => 1;
62use constant ObjName => 2;
63use constant LibName => 3;
64use constant OutputSectionName => 4;
65use constant InputSectionName => 5;
66use constant Size => 6;
67
68package MapFileParser;
69
70my $VERNO = " u0.01";
71 # u0.01 , 2015/01/19, Initial revision for Memory Utility Refinement
72
73my $g_MAPPath;
74
75my %parent_of_symbol; #symbol info in "symbol table"
76my %parent_obj_of_symbol; #symbol info in "symbol table"
77my %parent_lib_of_symbol; #symbol info in "symbol table"
78my %contained_obj; # obj contained in lib
79my %related_lib; # lib related a obj
80my %obj_size; # obj total size
81my %lib_size; # lib total size
82my %region_obj_size;
83my %region_lib_size;
84my %region_contained_obj;
85my %region_obj;
86my %region_contained_lib;
87my @veneers;
88my %obj_pad;
89my %obj_lib_lookup;
90my $obj_pad_count = 0;
91my @pad;
92my %g_discard_symbols; #$inputsection.".".$obj => $nSize;
93
94my %obj_debuginfo;
95my %lib_debuginfo;
96my %OBJ_RO_Size; #{objname} => nSize
97my %LIB_RO_Size; #{libname} => nSize
98my %OBJ_RW_Size;
99my %LIB_RW_Size;
100my %OBJ_ZI_Size;
101my %LIB_ZI_Size;
102
103my %region_OBJ_RO_Size; #{regionname-objname} => nSize
104my %region_OBJ_RW_Size;
105my %region_OBJ_ZI_Size;
106
107my @sections; # input section
108
109my %symbol_info; #{$strSymbolName} => [strSymbolName, strAddress, strObjName, strLibName, strOutputSectionName, strInputSectionName, nInputSectionSize]
110my %symbol_lookup_table; #{$SymbolName.".".$strObjName.".".$strLibName} => [strSymbolName, strAddress, strObjName, strLibName, strOutputSectionName, strInputSectionName, nInputSectionSize]
111my %region_arribution;
112
113my $g_fill; #record ** zero fill ** part
114my %g_fill_info; #record all fill info.
115
116#****************************************************************************
117# oo >>> Finished
118#****************************************************************************
119return 1;
120
121#****************************************************************************
122# subroutine: MAP_die
123# sample code: (message, __FILE__, __LINE__)
124# input: $error_msg, $file, $line_no
125#****************************************************************************
126sub MAP_die
127{
128 my ($error_msg, $file, $line_no) = (@_);
129 &CommonUtil::error_handler($error_msg, $file, $line_no, 'MAP');
130}
131
132#****************************************************************************
133# subroutine: ParseMAP
134# input: MAP Path string
135# output: x
136#****************************************************************************
137sub initGlobalVariable
138{
139 %parent_of_symbol = ();
140 %parent_obj_of_symbol = ();
141 %parent_lib_of_symbol = ();
142 %contained_obj = ();
143 %related_lib = ();
144 %obj_size = ();
145 %lib_size = ();
146 %region_obj_size = ();
147 %region_lib_size = ();
148 %region_contained_obj = ();
149 %region_obj = ();
150 %region_contained_lib = ();
151 @veneers = ();
152 %obj_pad = ();
153 %obj_lib_lookup = ();
154 $obj_pad_count = 0;
155 @pad = ();
156 %obj_debuginfo = ();
157 %lib_debuginfo = ();
158 %OBJ_RO_Size = ();
159 %LIB_RO_Size = ();
160 %OBJ_RW_Size = ();
161 %LIB_RW_Size = ();
162 %OBJ_ZI_Size = ();
163 %LIB_ZI_Size = ();
164 %region_OBJ_RO_Size = ();
165 %region_OBJ_RW_Size = ();
166 %region_OBJ_ZI_Size = ();
167 @sections = ();
168 %g_discard_symbols = ();
169 %symbol_info = ();
170 %symbol_lookup_table = ();
171 %region_arribution = ();
172 $g_fill = undef;
173 %g_fill_info = ();
174}
175
176sub ParseMAP
177{
178 ($g_MAPPath) = @_;
179 initGlobalVariable();
180
181 if(defined $g_MAPPath and -e $g_MAPPath)
182 {
183 open (FILE_HANDLE, "<$g_MAPPath") or &MAP_die("$g_MAPPath: file error!", __FILE__, __LINE__);
184
185 my ($strPreSymbolName, $strPreExeRegion, $strPreInputSection,$strSymbolName) = (undef, undef, undef, undef);
186 my ($flag_end_group, $b_enter_reference_table, $b_enter_discard) = (1, 0, 0);
187
188 #since $strPreInputSection will be set back to undef after _ParseContent(), we need another variable to store it
189 my ($strObjName, $strLibName, $strInputSectionName, $nInputSectionSize, $strMergeName) = ("NOT_FOUND", undef, undef, undef, undef);
190
191 my $prefix = '(?:startup|unlikely)';#prefix of symbol, ex: .text.unlikely.UL1_SEND_MSG_TO_NVRAM
192
193 while (<FILE_HANDLE>)
194 {
195 my $strLine = $_;
196 if(/Discarded input sections/)
197 {
198 $b_enter_discard = 1; next;
199 }
200 elsif(/Memory Configuration/)
201 {
202 $b_enter_discard = 0; next;
203 }
204 elsif(/Memory map/)
205 {
206 $b_enter_discard = 0;
207 $flag_end_group = 0;
208 next;
209 }
210 elsif($b_enter_discard == 1)
211 {
212 $strPreSymbolName = _ParseDiscardInputSection($strLine, $strPreSymbolName);
213 }
214 elsif (/END GROUP/)
215 {
216 $flag_end_group = 0; next;
217 }
218 elsif ($flag_end_group)
219 {
220 next;
221 }
222 elsif (/Symbol\s+File/ or /Cross Reference Table/)
223 { #Symbol File
224 $b_enter_reference_table = 1; next;
225 }
226 elsif($b_enter_reference_table == 0 )
227 {
228 if(/^(\S+)/ and $strLine !~/^OUTPUT\(/)
229 {#ignore: OUTPUT(./build/MT6589_MD2_TDD128HSPA/SKYPA/bin/MT6589_MD2_TDD128HSPA_PCB01_MT6589_S00.elf elf32-littlearm)
230 $strPreExeRegion = $1; next;
231 }
232 elsif(/^\s+(\.\b\w+\b)(\.\b$prefix\b)?(?:\.([^\.\s]+))?(\.\d+)?/)
233 {# .text.AsnDecode_RRC_BSIC => $strPreInputSection = .text; $strSymbolName = AsnDecode_RRC_BSIC
234
235 $strInputSectionName = $1;
236 $strSymbolName = ($4)?$3.$4:$3 if($3 or $4);
237
238 #if symbol name and size are in same line, need to parse symbol size
239 #.rodata.off 0x913f3760 0x1 ./build/MT6297_EVB/NLWCTG_SAP/bin/lib/libatc.a(valatapi.obj)
240 next if ($strLine !~ /0x\w+/);
241 }
242 elsif(/^\s+(\S+)$/)
243 {# .debug_aranges
244 $strInputSectionName = $1; next;
245 }
246 elsif(/^\s+\*\*\s+merge\s+(\S+)$/)
247 {# ** merge strings
248 $strMergeName = $1; next
249 }
250
251 ($strObjName, $strLibName, $strInputSectionName, $nInputSectionSize, $strMergeName,$strSymbolName)
252 = _ParseContent($strLine, $strPreExeRegion, $strObjName, $strLibName, $strInputSectionName, $nInputSectionSize, $strMergeName,$strSymbolName);
253 }
254 else
255 {
256 my $tmp_ref;
257 ($strPreSymbolName,$tmp_ref) = _ParseSymboltable($_, $strPreSymbolName);
258 $parent_of_symbol{$strPreSymbolName}=$tmp_ref;
259 }
260 }
261 close FILE_HANDLE;
262 }
263 else
264 {
265 &MAP_die("MAP Path($g_MAPPath) doesn't exist", __FILE__, __LINE__);
266 }
267}
268
269sub _UpdateSize
270{
271 my ($href, $strKey, $strSize) = @_;
272 if(exists $href->{$strKey})
273 {
274 $href->{$strKey} += hex($strSize);
275 }
276 else
277 {
278 $href->{$strKey} = hex($strSize);
279 }
280}
281
282sub _ParseDiscardInputSection
283{
284 my ($strInput, $strPreLine) = @_;
285 chomp($strInput);
286 if($strInput =~ /^\s+(\S+)\s*$/)
287 {# .debug_aranges
288 # 0x0000000000000000 0x20 ./build/MT6589_MD2_TDD128HSPA/SKYPA/bin/lib/libsys_drv.a(bootarm_gcc.obj)
289 return $1;
290 }
291 elsif(/^\s+(0x\w+)/)
292 {
293 $strInput = $strPreLine . $strInput;
294 }
295 if (($strInput =~ /(\S+)\s+(0x\w+)\s+(0x\w+)\s+.*\\(.*)\((.*)\)/) ||
296 ($strInput =~ /(\S+)\s+(0x\w+)\s+(0x\w+)\s+.*\/(.*)\((.*)\)/))
297 { # C$$code 0x0000000000000000 0x210 ./build/MT6572_DEMO_TDD128HSPA/DEFAULT/bin/lib/libsys_drv.a(bootarm_gcc.obj)
298 my $lib = $4;
299 my $obj = $5;
300 my $nSize = hex($3);
301 my $inputsection = $1;
302 _UpdateDiscardSymbol($inputsection, $nSize, $obj, $lib);
303 }
304 return "";
305}
306
307sub _UpdateDiscardSymbol
308{
309 my ($inputsection, $nSize, $obj, $lib) = @_;
310 $g_discard_symbols{$obj.'$$'.$inputsection} = $nSize;
311}
312
313sub _ParseContent
314{
315 my ($strInput, $strPreExeRegion, $strObjName, $strLibName, $strInputSectionName, $nInputSectionSize, $strMergeName,$strSymbolName) = @_;
316 chomp($strInput);
317
318 ## parse lib, obj, symbol size
319 if (($strInput =~ /\s+(\S+)?\s+(0x\w+)\s+(0x\w+)\s+.*\\(.*)\((.*)\)/) ||
320 ($strInput =~ /\s+(\S+)?\s+(0x\w+)\s+(0x\w+)\s+.*\/(.*)\((.*)\)/))
321 {
322 #**********************************************************
323 # For beloew three cases:
324 # Case1:symbol and addr in same line
325 # .rodata.off 0x913f3760 0x1 ./build/MT6297_EVB/NLWCTG_SAP/bin/lib/libatc.a(valatapi.obj)
326 # Case2: symbol and addr in diff line
327 # .rodata.__FUNCTION__.108590
328 # 0x913f3764 0xb ./build/MT6297_EVB/NLWCTG_SAP/bin/lib/libatc.a(valatceng.obj)
329 # Case3: contain input section
330 # EXTRAM_TXDATA 0x09e26864 0x63c8 ./mtk_rel/MT6297_EVB/NLWCTG_SAP/TARGET/lib//libgas_tdd.a(rlc_main.obj)
331 #**********************************************************
332 my $base = $2;
333 my $size = $3;
334 my $obj = $5;
335 $strLibName = $4;
336 $nInputSectionSize = hex($size);
337 $strObjName = $obj;
338
339 $strInputSectionName = $1 if ($1 and $1 !~ /\./);#case3:update input section.
340
341 $obj_pad{++$obj_pad_count} = $base;
342 $obj_lib_lookup{$base} = [$strObjName,$strLibName];
343 &ParseObjLib($strPreExeRegion, $strInput);
344 push(@sections, $strInputSectionName);
345
346 if($g_fill)
347 {
348 $g_fill_info{$base} = [$g_fill->[0], $g_fill->[1], , $region_arribution{$strPreExeRegion}, $obj, $strLibName];
349 $g_fill = undef;
350 }
351
352 _UpdateRORWZISize($strPreExeRegion, $base, $obj, $strLibName, $size);
353 }
354 elsif ($strInput =~ /(0x\w+)\s+(0x\w+)\s+linker stubs/)
355 {
356 &ParseObjLib($strPreExeRegion, $strInput);
357 _UpdateRORWZISize($strPreExeRegion, $1, "*stub*", undef, $2);
358 }
359 elsif(($strPreExeRegion =~ "EXTSRAM_L1DSP_ZI") and
360 (($strInput =~ /\*fill\*\s+(0x\w+)\s+(0x\w+)/) or ($strInput =~ /\*\*\s+zero\s+fill\s+(0x\w+)\s+(0x\w+)/)))
361 {
362 my $base = $1;
363 my $size = $2;
364 my $obj = "DSP";
365 $strLibName = "DSP";
366 $nInputSectionSize = hex($size);
367 $strObjName = $obj;
368
369 push(@sections, $strInputSectionName);
370
371 _UpdateRORWZISize($strPreExeRegion, $base, $obj, $strLibName, $size);
372 }
373 elsif(($strInput =~ /\*fill\*\s+(0x\w+)\s+(0x\w+)/) or ($strInput =~ /\*\*\s+zero\s+fill\s+(0x\w+)\s+(0x\w+)/))
374 {
375 $obj_pad{++$obj_pad_count} = $1;
376 push(@pad, $obj_pad_count);
377 #record fill info
378 $g_fill = [$1,hex($2)];
379 _UpdateRORWZISize($strPreExeRegion, $1, "*fill*", undef, $2);
380 }
381 elsif($g_fill && $strInput =~ /\s+(0x\w+)\s+(\S+\$\$\S+)\s+/)
382 {
383 #record fill info in hash table.
384 #there are same address for different linker symbols, in case get wrong info, here use address.symbol as the key of hash.
385 $g_fill_info{$1.".".$2} = [$g_fill->[0], $g_fill->[1], $region_arribution{$strPreExeRegion}, $2];
386 $g_fill = undef;
387 }
388
389 ## parse symbol
390 if(!defined $strMergeName)
391 {
392 ($strSymbolName, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize)
393 = _ParseSymbolInfo($strInput, $strSymbolName, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize);
394 }
395
396 ## parse ** merge
397 if(defined $strMergeName)
398 {
399 if ($strInput =~ /^\s+(0x\w+)\s+(0x\w+)/)
400 {
401 $obj_pad{++$obj_pad_count} = $1;
402 push(@pad, $obj_pad_count);
403 _UpdateRORWZISize($strPreExeRegion, $1, "*$strMergeName*", undef, $2);
404 }
405 $strMergeName =undef;
406 }
407
408 return ($strObjName, $strLibName, $strInputSectionName, $nInputSectionSize, $strMergeName,$strSymbolName);
409}
410
411sub _UpdateRORWZISize
412{
413 my ($strPreExeRegion, $base, $obj, $lib, $size) = @_;
414 $lib = $obj if(!defined $lib);
415 my $key = $strPreExeRegion."-".$obj;
416 my $objkey = $obj."-".$lib;
417
418 if($strPreExeRegion =~ /^\.debug/)
419 {
420 _UpdateSize(\%obj_debuginfo, $obj, $size);
421 _UpdateSize(\%lib_debuginfo, $lib, $size);
422 }
423 elsif(isZI($strPreExeRegion))
424 {
425 return if($base eq "0x0000000000000000");
426 _UpdateSize(\%OBJ_ZI_Size, $obj, $size);
427 _UpdateSize(\%LIB_ZI_Size, $lib, $size);
428 _UpdateSize(\%region_OBJ_ZI_Size, $key, $size);
429 _UpdateSize(\%obj_size, $objkey, $size);
430 $region_arribution{$strPreExeRegion} = "ZI";
431 }
432 elsif(isRW($strPreExeRegion))
433 {
434 return if($base eq "0x0000000000000000");
435 _UpdateSize(\%OBJ_RW_Size, $obj, $size);
436 _UpdateSize(\%LIB_RW_Size, $lib, $size);
437 _UpdateSize(\%region_OBJ_RW_Size, $key, $size);
438 _UpdateSize(\%obj_size, $objkey, $size);
439 $region_arribution{$strPreExeRegion} = "RW";
440 }
441 elsif(isRO($strPreExeRegion))
442 {
443 return if($base eq "0x0000000000000000" and $obj !~ /bootarm/i);
444 _UpdateSize(\%OBJ_RO_Size, $obj, $size);
445 _UpdateSize(\%LIB_RO_Size, $lib, $size);
446 _UpdateSize(\%region_OBJ_RO_Size, $key, $size);
447 _UpdateSize(\%obj_size, $objkey, $size);
448 $region_arribution{$strPreExeRegion} = "RO";
449 }
450 ParseInputSection($strPreExeRegion, $obj, $lib, $size);
451}
452
453sub isZI
454{
455 my ($strRegionName) = @_;
456 my $bRet = ($strRegionName =~ /ZI|\.bss|EXTSRAM_DSP/);
457 return $bRet;
458}
459sub isRW
460{
461 my ($strRegionName) = @_;
462 my $bRet = 0;
463 $bRet = 1 if(!isZI($strRegionName) and $strRegionName =~ /DSPRAM|EXTSRAM|DATA|RW/);
464 return $bRet;
465}
466sub isRO
467{
468 my ($strRegionName) = @_;
469 my $bRet = 0;
470 $bRet = 1 if(!isZI($strRegionName) and !isRW($strRegionName)
471 and ($strRegionName !~/\.ARM\.attributes|\.comment|\.debug|\.stab/));
472 return $bRet;
473}
474
475
476#****************************************************************************
477# subroutine: _ParseSymbolInfo
478# input:
479# output: N/A
480#****************************************************************************
481sub _ParseSymbolInfo
482{
483 my ($strInput, $strSymbolName, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize) = @_;
484 my $skip_pattern = "Image\\$\\$|\\$\\$Base|\\$\\$Limit|\\$\\$Length|load address|\ LONG\ ";
485
486 if($strSymbolName and
487 (($strInput =~ /^\s+(?:\S+\s+)?(0x\w+)\s+(0x\w+)\s+.*\\(.*)\((.*)\)/) ||
488 ($strInput =~ /^\s+(?:\S+\s+)?(0x\w+)\s+(0x\w+)\s+.*\/(.*)\((.*)\)/)))
489 { #for below case
490 # 0x911c5d06 0x214 ./mtk_rel/MT6297_EVB/NLWCTG_SAP/TARGET/lib/liburr_fdd.a(slce_configuration_controller.obj)
491 # .bss.fsm_desc 0x23c30ac4 0xec ./build/MT6297_EVB/NLWCTG_SAP/bin/lib/libatc.a(valatud.obj)
492 my $strAddress = $1;
493 my $symbol_lookup_key = $strSymbolName.".".$strObjName.".".$strLibName;
494
495 if($symbol_lookup_table{$symbol_lookup_key})
496 {
497 if($symbol_lookup_table{$symbol_lookup_key}->[1] > $strAddress)
498 {
499 delete $symbol_info{$symbol_lookup_table{$symbol_lookup_key}->[1].".".$strSymbolName};
500 }
501 else
502 {
503 $strAddress = $symbol_lookup_table{$symbol_lookup_key}->[1];
504 }
505
506 $nInputSectionSize += $symbol_lookup_table{$symbol_lookup_key}->[6];
507 }
508
509 $symbol_lookup_table{$symbol_lookup_key} = [$strSymbolName, $strAddress, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize];
510 $symbol_info{$strAddress.".".$strSymbolName} = [$strSymbolName, $strAddress, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize];
511 $strSymbolName = undef;
512 }
513 elsif($strInput =~ /^\s+(0x\w+)\s+(\w+)$/ and $strInput !~/$skip_pattern/)
514 {
515 # for below case
516 # 0x00024054 p_SLILM
517 my $strAddress = $1;
518 my $SymbolName = $2;
519 my $symbol_lookup_key = $SymbolName.".".$strObjName.".".$strLibName;
520
521 if(!$symbol_lookup_table{$symbol_lookup_key})
522 {# .bss 0x2443e1c0 0x20 ./build/MT6297_EVB/NLWCTG_SAP/bin/lib/libdevdrv.a(drv_mdcirq.obj)
523 # 0x2443e1c0 drv_mdcirq_activate_lisr_lock
524 $nInputSectionSize = hex(0);
525 $symbol_lookup_table{$symbol_lookup_key} = [$SymbolName, $strAddress, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize];
526 $symbol_info{$strAddress.".".$SymbolName} = [$SymbolName, $strAddress, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize];
527 }
528 }
529
530 return ($strSymbolName, $strObjName, $strLibName, $strPreExeRegion, $strInputSectionName, $nInputSectionSize);
531}
532
533
534#****************************************************************************
535# subroutine: _ParseSymboltable
536# input: ($strInput, $strPreSymbolName)
537# output: N/A
538#****************************************************************************
539sub _ParseSymboltable
540{
541 my ($strInput, $strPreSymbolName) = @_;
542 if ($strInput =~ /(\S+)\s+.*[\/|\\](.*)\((.*)\)/)
543 {
544 $strPreSymbolName = $1;
545 my @lib_obj = [$2,$3];
546 my @obj_lib = [$3,$2];
547 push(@{$parent_of_symbol{$1}}, @lib_obj);
548 push(@{$parent_obj_of_symbol{$1}}, $3);
549 push(@{$parent_lib_of_symbol{$1}}, $2);
550 }
551 elsif ($strInput =~ /\s+.*[\/|\\](.*)\((.*)\)/)
552 {
553 my @lib_obj = [$1,$2];
554 my @obj_lib = [$2,$1];
555 push(@{$parent_of_symbol{$strPreSymbolName}}, @lib_obj);
556 push(@{$parent_obj_of_symbol{$strPreSymbolName}}, $2);
557 push(@{$parent_lib_of_symbol{$strPreSymbolName}}, $1);
558 }
559 return ($strPreSymbolName, $parent_of_symbol{$1} );
560}
561
562#****************************************************************************
563# subroutine: ListAllSections
564# input: N/A
565# output: N/A
566#****************************************************************************
567sub ListAllSections
568{
569 my %count;
570 my @uni_sections = grep { ++$count{ $_ } < 2; } @sections;
571 return \@uni_sections;
572}
573
574#****************************************************************************
575# subroutine: ListAllLoadRegion (not support this function)
576# input: N/A
577# output: N/A
578#****************************************************************************
579sub ListAllLoadRegion
580{
581 return undef;
582}
583
584#****************************************************************************
585# subroutine: ListPadInfo
586# input: N/A
587# output: array reference
588# for map file, array content:[array1,array2,...]
589# array1:[strPadBaseAddress,[strPreObjName,strPreLibName],strPreObjAddress,[strPostObjName,strPostLibName],strPostObjAddress]
590#****************************************************************************
591sub ListPadInfo
592{
593 my @padstring;
594 foreach my $temp(@pad)
595 {
596 my $pad_address = $obj_pad{$temp};
597 my $previous = $obj_pad{$temp - 1};
598 my $post = $obj_pad{$temp + 1};
599 my @pre_obj = $obj_lib_lookup{$previous};
600 my @post_obj = $obj_lib_lookup{$post};
601 # next if(!$pad_address);
602 my @padinfo = [$pad_address,@pre_obj,$previous,@post_obj,$post];
603 push (@padstring, @padinfo);
604 }
605 return \@padstring;
606}
607
608#****************************************************************************
609# subroutine: StoreIntoTempFile
610# input: N/A
611# output: temp files which contain perl data structure
612#****************************************************************************
613use Storable qw/lock_nstore/;
614sub StoreIntoTempFile
615{
616 my ($strPath) = @_;
617 my $file = $strPath."\\MapParser_Temp.dat";
618 my %tempfile;
619 $tempfile{"parent_reference"} = \%parent_of_symbol;
620 $tempfile{"parent_obj_reference"} = \%parent_obj_of_symbol;
621 $tempfile{"parent_lib_reference"} = \%parent_lib_of_symbol;
622 $tempfile{"veneer"} = \@veneers;
623 $tempfile{"obj_in_exeregion"} = \%region_contained_obj;
624 $tempfile{"lib_in_exeregion"} = \%region_contained_lib;
625 $tempfile{"obj_by_lib"} = \%contained_obj;
626 $tempfile{"lib_by_obj"} = \%related_lib;
627
628 lock_nstore \%tempfile, $file;
629}
630
631#****************************************************************************
632# subroutine: ParseObjLib
633# input: Execution Region Name, $strLine
634# output: N/A
635#****************************************************************************
636sub ParseObjLib
637{
638 my ($strPreExeRegion, $strLine) = @_;
639 if (($strPreExeRegion !~ /\.ARM\.attributes/) and ($strPreExeRegion !~ /\.comment/)
640 and ($strPreExeRegion !~ /^\.debug/) and ($strPreExeRegion !~ /^\.stab/))
641 {
642 if ((/(0x\w+)\s+(0x\w+)\s+.*\\(.*)\((.*)\)/) || (/(0x\w+)\s+(0x\w+)\s+.*\/(.*)\((.*)\)/))
643 {
644 my $lib = $3;
645 my $obj = $4;
646 $contained_obj{$lib}{$obj} = 1;
647 $related_lib{$obj}{$lib} = 1;
648 }
649 elsif(/(0x\w+)\s+(0x\w+)\s+linker stubs/)
650 {## C$$code.stub 0x7000a258 0x8 linker stubs
651 push (@veneers, [$strPreExeRegion, $1, hex($2)]);
652 }
653 }
654}
655
656#****************************************************************************
657# subroutine: ParseInputSection
658# input: Execution Region Name, $strLine
659# output: N/A
660#****************************************************************************
661sub ParseInputSection
662{
663 my ($strExeRegionName, $obj, $lib, $size) = @_;
664 return if(!defined $strExeRegionName); ### setting for $strExeRegionName = undef
665
666 $region_contained_obj{$strExeRegionName}{$obj} = 1;
667 $region_contained_lib{$strExeRegionName}{$lib} = 1;
668
669 my $obj_key = $strExeRegionName."-".$obj."-".$lib;
670 my $lib_key = $strExeRegionName."-".$lib;
671 _UpdateSize(\%region_obj_size, $obj_key, $size);
672 _UpdateSize(\%region_lib_size, $obj_key, $size);
673}
674
675sub GetDiscardSymbol
676{
677 my ($discard_href) = @_;
678 %$discard_href = %g_discard_symbols;
679}
680
681#****************************************************************************
682# subroutine: GetSymbolInfo
683# input:
684#
685#****************************************************************************
686sub GetSymbolInfo
687{
688 my ($symbol_key) = @_;
689 my @symbol_info_array = @{$symbol_info{$symbol_key}} if $symbol_info{$symbol_key};
690
691 return @symbol_info_array;
692}
693
694#****************************************************************************
695# subroutine: GetFillInfo
696# input:
697#
698#****************************************************************************
699sub GetFillInfo
700{
701 return \%g_fill_info;
702}
703
704#****************************************************************************
705# subroutine: GetParentOfSymbol
706# input: Execution Region Name, flag (all/lib/obj)
707# output: (Object Name, Library Name) which refers to given symbol (flag = all)
708# Object Name which refers to given symbol (flag = obj)
709# Library Name which refers to given symbol (flag = lib)
710#****************************************************************************
711sub GetParentOfSymbol
712{
713 # Name Size VMA LMA File off Algn
714 my ($strSymName, $flag) = @_;
715
716 my $parent_array;
717 if($flag eq "all")
718 {
719 $parent_array = $parent_of_symbol{$strSymName};
720 }
721 elsif($flag eq "lib")
722 {
723 $parent_array = $parent_lib_of_symbol{$strSymName};
724 }
725 elsif($flag eq "obj")
726 {
727 $parent_array = $parent_obj_of_symbol{$strSymName};
728 }
729 return $parent_array;
730}
731
732#****************************************************************************
733# subroutine: GetChildOfSymbol
734# input: symbol name
735# output: undef(not support this function)
736#****************************************************************************
737sub GetChildOfSymbol
738{
739 my ($strSymbolName) = @_;
740 return undef;
741}
742
743#****************************************************************************
744# subroutine: ListObjByLib
745# input: Library Name
746# output: Objects array reference
747#****************************************************************************
748sub ListObjByLib
749{
750 my ($lib_name) = @_;
751 my @obj_array = keys %{$contained_obj{$lib_name}};
752 return \@obj_array;
753}
754
755#****************************************************************************
756# subroutine: ListLibByObj
757# input: Object Name
758# output: Library array reference
759#****************************************************************************
760sub ListLibByObj
761{
762 my ($obj_name) = @_;
763 my @lib_array = keys %{$related_lib{$obj_name}};
764 return \@lib_array;
765}
766
767#****************************************************************************
768# subroutine: ListObjLibByAddr
769# input: symbol address
770# output: objeck and lib info
771#****************************************************************************
772sub ListObjLibByAddr
773{
774 my ($strAddress) = @_;
775 my @obj_lib_by_addr = @{$obj_lib_lookup{$strAddress}} if $obj_lib_lookup{$strAddress};
776
777 return \@obj_lib_by_addr;
778}
779
780#****************************************************************************
781# subroutine: GetTotalSizeByObj
782# input: Object Name, Library Name
783# output: Total size of given object
784# (excluding size in .comment, .ARM.attribut,
785# execution region which begins with .debug or .stab)
786#****************************************************************************
787sub GetTotalSizeByObj
788{
789 my ($obj_name, $lib_name) = @_;
790 my $key = $obj_name."-".$lib_name;
791 my $obj_size = $obj_size{$key};
792 return $obj_size;
793}
794
795#****************************************************************************
796# subroutine: GetTotalSizeByLib
797# input: Library Name
798# output: Total size of given library
799# (excluding size in .comment, .ARM.attribut,
800# execution region which begins with .debug or .stab)
801#****************************************************************************
802sub GetTotalSizeByLib
803{
804 my ($lib_name) = @_;
805 my $obj_array = $contained_obj{$lib_name};
806 foreach my $temp (@$obj_array)
807 {
808 my $strObjSize = CommonUtil::Dec2Hex($obj_size{$temp});
809 _UpdateSize(\%lib_size, $lib_name, $strObjSize);
810 }
811 return $lib_size{$lib_name};
812}
813
814#****************************************************************************
815# subroutine: GetObjByExeRegion
816# input: Execution Region Name
817# output: objects which given execution region contains
818#****************************************************************************
819sub GetObjByExeRegion
820{
821 my ($strExeRegionName) = @_;
822 my @obj_array = keys %{$region_contained_obj{$strExeRegionName}};
823 return \@obj_array;
824}
825
826#****************************************************************************
827# subroutine: GetLibByExeRegion
828# input: Execution Region Name
829# output: libraries which given execution region contains
830#****************************************************************************
831sub GetLibByExeRegion
832{
833 my ($strExeRegionName) = @_;
834 my @lib_array = keys %{$region_contained_lib{$strExeRegionName}};
835 return \@lib_array;
836}
837
838#****************************************************************************
839# subroutine: GetObjSizeByExeRegion
840# input: ExeRegion Name, Object Name, Library Name
841# output: size of object in given execution region
842#****************************************************************************
843sub GetObjSizeByExeRegion
844{
845 my ($strExeRegion, $strObj, $strLib) = @_;
846 my $string = $strExeRegion."-".$strObj."-".$strLib;
847 my $obj_size = $region_obj_size{$string};
848 return $obj_size;
849}
850
851#****************************************************************************
852# subroutine: GetLibSizeByExeRegion
853# input: ExeRegion Name, Library Name
854# output: size of library in given execution region
855#****************************************************************************
856sub GetLibSizeByExeRegion
857{
858 my ($strExeRegion, $strLib) = @_;
859 my $string = $strExeRegion."-".$strLib;
860 my $lib_size = $region_lib_size{$string};
861 return $lib_size;
862}
863
864#****************************************************************************
865# subroutine: GetObjSizeByCatExeRegion
866# input: $strRegionName: Execution Name (Case sensitive)
867# $strCategory: RO/RW/ZI (Case sensitive)
868# output: ObjCateSize Hash Reference
869#****************************************************************************
870sub GetObjSizeByCatExeRegion
871{
872 my ($strERName, $strCategory) = @_;
873 my %ObjSize; # {strObjName} => Size
874
875 my $included_obj_aref = &GetObjByExeRegion($strERName);
876 my $region_OBJ_href = undef;
877 $region_OBJ_href = \%region_OBJ_ZI_Size if(isZI($strERName) and $strCategory =~ /ZI/i);
878 $region_OBJ_href = \%region_OBJ_RW_Size if(isRW($strERName) and $strCategory =~ /RW/i);
879 $region_OBJ_href = \%region_OBJ_RO_Size if(isRO($strERName) and $strCategory =~ /RO/i);
880
881 if(defined $region_OBJ_href)
882 {
883 foreach my $temp(@$included_obj_aref)
884 {
885 my $key = $strERName."-".$temp;
886 if(exists $region_OBJ_href->{$key})
887 {
888 $ObjSize{$temp} = $region_OBJ_href->{$key};
889 }
890 else
891 {
892 $ObjSize{$temp} = 0;
893 }
894 }
895 }
896 return \%ObjSize;
897}
898
899#****************************************************************************
900# subroutine: GetVeneerInfo
901# input: N/A
902# output: [Execution Region, Base Address, Size] list for veneer
903#****************************************************************************
904sub GetVeneerInfo
905{
906 return \@veneers;
907}
908
909#****************************************************************************
910# subroutine: GetExeRegionAttr
911# input: N/A
912# output: {region_name} = region attribution
913#****************************************************************************
914sub GetExeRegionAttr
915{
916 return \%region_arribution;
917}
918
919#****************************************************************************
920# subroutine: ListObjLibBySymbol
921# input: $strSymName: Symbol Name (Case sensitive)
922# output: for map file, output array reference
923# array content:[[strObjName1,strLibName1],[strObjName2,strLibName2],...]
924#****************************************************************************
925sub ListObjLibBySymbol
926{
927 print "[Error] not support any more\n";
928 return undef;
929}
930
931#****************************************************************************
932# subroutine: GetLoadRegionInfo - Get Load Region information
933# input: N/A
934# output: undef(not support this function)
935#****************************************************************************
936sub GetLoadRegionInfo
937{
938 return undef;
939}
940
941#****************************************************************************
942# subroutine: GetTotalROSize - Get total RO size
943# input: $bNeedString: 1=Return string, 0/default/no input=Return int
944# output: undef(not support this function)
945#****************************************************************************
946sub GetTotalROSize
947{
948 my ($bNeedString) = @_;
949 return undef;
950}
951
952#****************************************************************************
953# subroutine: GetTotalRWZISize - Get total RWZI size
954# input: $bNeedString: 1=Return string, 0/default/no input=Return int
955# output: undef(not support this function)
956#****************************************************************************
957sub GetTotalRWZISize
958{
959 my ($bNeedString) = @_;
960 return undef;
961}
962
963#****************************************************************************
964# subroutine: GetTotalROMSize - Get total ROM size
965# input: $bNeedString: 1=Return string, 0/default/no input=Return int
966# output: undef(not support this function)
967#****************************************************************************
968sub GetTotalROMSize
969{
970 my ($bNeedString) = @_;
971 return undef;
972}
973
974#****************************************************************************
975# subroutine: GetObjDebugInfoSize
976# input: $strObjName: Obj Name (Case sensitive)
977# output: debug info size for given obj
978#****************************************************************************
979sub GetObjDebugInfoSize
980{
981 my ($strObjName) = @_;
982 my $DebugInfoSize = $obj_debuginfo{$strObjName};
983 return $DebugInfoSize;
984}
985
986#****************************************************************************
987# subroutine: ListObjSummaryInfo
988# input: obj name, flag represents which column to show
989# flag = "RO"
990# = "RW"
991# = "ZI"
992# = "Debug"
993# output: RO/RW/ZI/Debug size for given obj
994#****************************************************************************
995sub ListObjSummaryInfo
996{
997 my ($strName, $flag) = @_;
998 my $nSize = 0;
999 if ($flag =~ /RO/i)
1000 {
1001 $nSize = $OBJ_RO_Size{$strName};
1002 }
1003 elsif ($flag =~ /RW/i)
1004 {
1005 $nSize = $OBJ_RW_Size{$strName};
1006 }
1007 elsif ($flag =~ /ZI/i)
1008 {
1009 $nSize = $OBJ_ZI_Size{$strName};
1010 }
1011 elsif ($flag eq "Debug")
1012 {
1013 $nSize = $obj_debuginfo{$strName};
1014 }
1015 return $nSize;
1016}
1017
1018#****************************************************************************
1019# subroutine: ListLibSummaryInfo
1020# input: lib name, flag represents which column to show
1021# flag = "RO"
1022# = "RW"
1023# = "ZI"
1024# = "Debug"
1025# output: RO/RW/ZI/Debug size for given lib
1026#****************************************************************************
1027sub ListLibSummaryInfo
1028{
1029 my ($strLibName, $flag) = @_;
1030 my $nSize = 0;
1031 if ($flag =~ /RO/i)
1032 {
1033 $nSize = $LIB_RO_Size{$strLibName};
1034 }
1035 elsif ($flag =~ /RW/i)
1036 {
1037 $nSize = $LIB_RW_Size{$strLibName};
1038 }
1039 elsif ($flag =~ /ZI/i)
1040 {
1041 $nSize = $LIB_ZI_Size{$strLibName};
1042 }
1043 elsif ($flag eq "Debug")
1044 {
1045 $nSize = $lib_debuginfo{$strLibName};
1046 }
1047 return $nSize;
1048}
1049
1050#****************************************************************************
1051# subroutine: GrepSymbolByInputSection
1052# input: input section name represent in regular expression
1053# ex: INTSRAM_ROCODE.*
1054# INTSRAM_ROCODE_A
1055# INTSRAM_ROCODE_B
1056#
1057# output: symbol info array reference in order of address in the following format:
1058# [[$strSymbolName, $nSymbolAddr, $strObjName, $strLibName, $strOutputSectionName, $strInputSectionName, $nInputSectionSize], ...]
1059#****************************************************************************
1060sub GrepSymbolByInputSection
1061{
1062 my ($strSectionNameInRegularExp) = @_;
1063 my @SymInfoKeys = sort { hex($symbol_info{$a}->[SymbolInfoTable::Addr]) <=> hex($symbol_info{$b}->[SymbolInfoTable::Addr]) }
1064 grep{$symbol_info{$_}->[SymbolInfoTable::InputSectionName] =~ /$strSectionNameInRegularExp/} keys %symbol_info;
1065 #map {print $_."\n"} @SymInfoKeys;
1066 my @SymInfo = map {$symbol_info{$_}} @SymInfoKeys;
1067 return \@SymInfo;
1068}
1069
1070#****************************************************************************
1071# subroutine: GrepSymbolByOutputSection
1072# input: input section name represent in regular expression
1073# ex: CACHED_EXTSRAM_L2CACHE_LOCK_DATA
1074# CACHED_EXTSRAM_L2CACHE_LOCK_DATA
1075# CACHED_EXTSRAM_L2CACHE_LOCK_DATA_ZI
1076#
1077# output: symbol info array reference in order of address in the following format:
1078# [[$strObjName, $strLibName], [$strObjName, $strLibName] ...]
1079#****************************************************************************
1080sub GrepSymbolByOutputSection
1081{
1082 my ($strSectionNameInRegularExp) = @_;
1083 my @SymInfoKeys = sort { hex($symbol_info{$a}->[SymbolInfoTable::Addr]) <=> hex($symbol_info{$b}->[SymbolInfoTable::Addr]) }
1084 grep{$symbol_info{$_}->[SymbolInfoTable::OutputSectionName] =~ /$strSectionNameInRegularExp/} keys %symbol_info;
1085 #map {print $_."\n"} @SymInfoKeys;
1086 my @SymInfo = map {$symbol_info{$_}} @SymInfoKeys;
1087 return \@SymInfo;
1088}
1089