rjw | 6c1fd8f | 2022-11-30 14:33:01 +0800 | [diff] [blame] | 1 | #!/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) 2012 |
| 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 | #* ckLDS.pl |
| 40 | #* |
| 41 | #* Project: |
| 42 | #* -------- |
| 43 | #* |
| 44 | #* |
| 45 | #* Description: |
| 46 | #* ------------ |
| 47 | #* This script is to check memory layout |
| 48 | #* |
| 49 | #* Author: |
| 50 | #* ------- |
| 51 | #* Qmei Yang (mtk03726) |
| 52 | #* |
| 53 | #****************************************************************************/ |
| 54 | |
| 55 | #**************************************************************************** |
| 56 | # Included Modules |
| 57 | #**************************************************************************** |
| 58 | |
| 59 | BEGIN { push @INC , './tools/', './tools/MemoryUtility/' } # add additional library path |
| 60 | use strict; |
| 61 | use File::Basename; |
| 62 | use FileInfoParser; |
| 63 | use CommonUtility; |
| 64 | use LinkerOutputParser; |
| 65 | use ldsInfo; |
| 66 | #**************************************************************************** |
| 67 | # Constants |
| 68 | #**************************************************************************** |
| 69 | #LDS Type |
| 70 | use constant MAIN => 0; |
| 71 | use constant BL => 1; |
| 72 | use constant EXT_BL => 2; |
| 73 | #CORE Type |
| 74 | use constant PCORE_TYPE => 0; |
| 75 | use constant L1CORE_TYPE => 1; |
| 76 | |
| 77 | # The following constant patterns are used in m notify for finding the corresponding owner. |
| 78 | # If any change, you have to sync with ErrorMsg Handler BM for the modification information. |
| 79 | use constant INVALID_OBJECT_LIST => "- INVALID OBJECT LIST -"; |
| 80 | use constant ERROR_HANDLING_SOP => "- ERROR HANDLING SOP -"; |
| 81 | #**************************************************************************** |
| 82 | # VERNO |
| 83 | #**************************************************************************** |
| 84 | my $CKLDS_VERNO = " u0.02"; |
| 85 | # u0.02 by Carl, 20150225, Refactor for L1core |
| 86 | # u0.01 by Carl, 20141023, Memory Utility Refinement |
| 87 | # m0.04 by mei, Remove warning messages |
| 88 | # m0.03 by mei, Show invalid regions even if it contains no objlist |
| 89 | # m0.02 by mei, Parse linker script directly and output formal error message |
| 90 | # m0.01 by JI , initial version |
| 91 | |
| 92 | |
| 93 | |
| 94 | #**************************************************************************** |
| 95 | # Input Parameters and Global Variables |
| 96 | #**************************************************************************** |
| 97 | my $phase = $ARGV[0]; |
| 98 | my $g_stop_build = $ARGV[1]; |
| 99 | my $g_LDSInputPath = $ARGV[2]; |
| 100 | my $map_file = $ARGV[3]; |
| 101 | my $FLASH_CFG_TMP = $ARGV[4]; # XXX Not Used in current version |
| 102 | my $g_MakeFilePath = $ARGV[5]; # XXX Not Used in current version |
| 103 | my $BB_FOLDER = $ARGV[6]; # XXX Not Used in current version |
| 104 | my $DUMMY_LDS_ALLOW = $ARGV[7]; # XXX Not Used in current version |
| 105 | |
| 106 | |
| 107 | #**************************************************************************** |
| 108 | # 0 >>> parse input parameters and decide ckscatter phase |
| 109 | #**************************************************************************** |
| 110 | if ($phase == 1) |
| 111 | { |
| 112 | #warn "ckLDS: phase 1 not implemented yet\n"; |
| 113 | } |
| 114 | elsif ($phase == 2) |
| 115 | { |
| 116 | &cklds_phase2($map_file, $g_LDSInputPath); |
| 117 | } |
| 118 | else |
| 119 | { |
| 120 | &error_handler("Unsupported ckMemLayout command!"); |
| 121 | } |
| 122 | |
| 123 | exit 0; |
| 124 | |
| 125 | #**************************************************************************** |
| 126 | # 1 >>> Phase 1 |
| 127 | #**************************************************************************** |
| 128 | |
| 129 | |
| 130 | #**************************************************************************** |
| 131 | # 2 >>> Phase 2 |
| 132 | #**************************************************************************** |
| 133 | sub cklds_phase2 |
| 134 | { |
| 135 | my ($LinkerOutput_MAP, $LDS) = @_; |
| 136 | |
| 137 | my $SYM_ERList = &ParseLinkerOutput_SYM($LinkerOutput_MAP); |
| 138 | my $LDS_ERList = &ParseLinkerInput($LDS); |
| 139 | my $SYMOddRegions_href = &CompareER($SYM_ERList, $LDS_ERList); |
| 140 | |
| 141 | if (keys(%$SYMOddRegions_href) > 0) |
| 142 | { |
| 143 | &LinkerOutputParser::FileParse($LinkerOutput_MAP); |
| 144 | my $InvalidER_href = &GetOddObjList($SYMOddRegions_href); |
| 145 | my $err_msg .= &Get_Template_Caution(); |
| 146 | $err_msg .= "------------------- INVALID SECTION LIST -------------------\n"; |
| 147 | $err_msg .= &Get_Template_DiffER_In_SYM_but_Not_in_LDS($InvalidER_href) . "\n"; |
| 148 | $err_msg .= "------------------".INVALID_OBJECT_LIST."-------------------\n"; |
| 149 | $err_msg .= &Get_Template_InvalidObjList($InvalidER_href); |
| 150 | my $nLDSType = &GetLDSType($LDS); |
| 151 | my $nCoreType = &GetCoreType($LDS); |
| 152 | $err_msg .= &Get_Template_ErrorHandlingSOP($nLDSType, $nCoreType); |
| 153 | |
| 154 | &error_handler($err_msg, 1); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | |
| 159 | #**************************************************************************** |
| 160 | # subroutine: GetOddObjList |
| 161 | # used in cklds_phase2() |
| 162 | # input : Region_href |
| 163 | # return: \%ObjList: {ER}=> \@ObjList |
| 164 | #**************************************************************************** |
| 165 | sub GetOddObjList |
| 166 | { # Check Linker Output Diff Regions , which object inside |
| 167 | my ($SYMOddRegions_href) = @_; |
| 168 | my %OddObjList; # RegionName => [obj1, obj2...] |
| 169 | foreach my $ER (sort keys %$SYMOddRegions_href) |
| 170 | { |
| 171 | my $Offender_objlist = &LinkerOutputParser::GetObjByExeRegion($ER); |
| 172 | $OddObjList{$ER} = $Offender_objlist; |
| 173 | } |
| 174 | return \%OddObjList; |
| 175 | } |
| 176 | |
| 177 | #**************************************************************************** |
| 178 | # subroutine: ParseLinkerInput: Retrieve Execution Regions from linker script |
| 179 | # used in cklds_phase2() |
| 180 | # input : strLDSFilePath |
| 181 | # return: \@ER_List: Execution Region Array |
| 182 | #**************************************************************************** |
| 183 | sub ParseLinkerInput |
| 184 | { |
| 185 | my ($strldsFilePath) = @_; |
| 186 | my $Info = new ldsInfo; |
| 187 | $Info->ParseLinkerScript($strldsFilePath); |
| 188 | my $ERList_aref = $Info->GetAllExeRegion(); |
| 189 | my $HiddenERList_aref = $Info->GetAllHiddenExeRegion(); |
| 190 | push (@$ERList_aref , @$HiddenERList_aref); |
| 191 | &error_handler("Input($strldsFilePath) is not correct!") if (!defined $ERList_aref); |
| 192 | #print "=================[LDS]=====================\n"; |
| 193 | #map {print "$_\n";} @$ERList_aref; |
| 194 | #print "======================================\n"; |
| 195 | return $ERList_aref; |
| 196 | } |
| 197 | |
| 198 | #**************************************************************************** |
| 199 | # subroutine: ParseLinkerOutput_SYM: Retrieve Execution Regions from Linker Output Parser |
| 200 | # used in cklds_phase2() |
| 201 | # input : strMapFilePath |
| 202 | # => it'll be transferred to sym file inside the function |
| 203 | # return: \@ER_List: Execution Region Array |
| 204 | #**************************************************************************** |
| 205 | sub ParseLinkerOutput_SYM |
| 206 | { |
| 207 | my ($strMAPPath) = @_; |
| 208 | my $ERList_aref = undef; |
| 209 | my $sym_file = $strMAPPath; |
| 210 | $sym_file =~ s/\.map$/\.sym/; #execution region information is not supported in LinkerOutputParser.pm while the input is .map |
| 211 | &LinkerOutputParser::FileParse($sym_file); |
| 212 | my $ERList_aref = &LinkerOutputParser::ListAllExeRegion(); |
| 213 | &error_handler("Input or LinkerOutputParser.pm is not correct!") if (!defined $ERList_aref); |
| 214 | #print "=================[SYM]=====================\n"; |
| 215 | #map {print "$_\n";} @$ERList_aref; |
| 216 | #print "======================================\n"; |
| 217 | return $ERList_aref; |
| 218 | } |
| 219 | |
| 220 | #**************************************************************************** |
| 221 | # subroutine: CompareER: Compare 2 region list |
| 222 | # used in cklds_phase2() |
| 223 | # input : $SYM_ERList: an array reference |
| 224 | # $LDS_ERList: an array reference |
| 225 | # return: \%Region List: a hash contains the regions in sym but not in lds |
| 226 | #**************************************************************************** |
| 227 | sub CompareER |
| 228 | { |
| 229 | my ($SYM_ERList, $LDS_ERList) = @_; # array_ref |
| 230 | my %Out_left; #used to get SYM Left Strange Regions |
| 231 | my @Out_Same; |
| 232 | my %LDSERHash; |
| 233 | map{$LDSERHash{$_} = 1;}@$LDS_ERList; |
| 234 | foreach my $ER (@$SYM_ERList) |
| 235 | { |
| 236 | next if($ER eq ""); |
| 237 | if (exists $LDSERHash{$ER}) |
| 238 | { |
| 239 | push @Out_Same, $ER; |
| 240 | delete $LDSERHash{$ER}; |
| 241 | } |
| 242 | else |
| 243 | { |
| 244 | $Out_left{$ER} = 1; |
| 245 | } |
| 246 | } |
| 247 | &TrimDebugRegions(\%Out_left); |
| 248 | #&Print_LDS_ERList_Not_In_SYM(\%LDSERHash); |
| 249 | #&Print_SameER_In_SYM_and_LDS(\@Out_Same); |
| 250 | return \%Out_left; |
| 251 | } |
| 252 | |
| 253 | #**************************************************************************** |
| 254 | # subroutine: TrimDebugRegions: Normal GCC Regions for Debugging |
| 255 | # used in CompareER() |
| 256 | # input : $SYM_ERList: a hash reference contains regions in sym |
| 257 | # return: N/A |
| 258 | #**************************************************************************** |
| 259 | sub TrimDebugRegions |
| 260 | { |
| 261 | my ($ERList_href) = @_; |
| 262 | foreach my $ER (sort keys %$ERList_href) |
| 263 | { #------ Normal GCC Regions for Debugging ----- |
| 264 | if ($ER =~ /^\.debug_/ |
| 265 | or $ER =~ /^\.ARM\.attributes/ |
| 266 | or $ER =~ /^\.comment/ |
| 267 | or $ER =~ /^\.stab/) |
| 268 | { |
| 269 | #print $ER, "\n"; |
| 270 | delete $ERList_href->{$ER}; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | #**************************************************************************** |
| 275 | # subroutine: GetCoreType |
| 276 | # input: $strLDSPath : LDS FilePath |
| 277 | # return: CORE Type: PCORE_TYPE, L1CORE_TYPE |
| 278 | #**************************************************************************** |
| 279 | sub GetCoreType |
| 280 | { |
| 281 | my ($strLDSPath) = @_; |
| 282 | if($strLDSPath =~/l1core/i) |
| 283 | { |
| 284 | return L1CORE_TYPE; |
| 285 | } |
| 286 | else |
| 287 | { |
| 288 | return PCORE_TYPE; |
| 289 | } |
| 290 | } |
| 291 | #**************************************************************************** |
| 292 | # subroutine: GetLDSType |
| 293 | # input: $strLDSPath : LDS FilePath |
| 294 | # return: LDSType: MAIN, BL, EXT_BL |
| 295 | #**************************************************************************** |
| 296 | sub GetLDSType |
| 297 | { |
| 298 | my ($strLDSPath) = @_; |
| 299 | my $strName = basename($strLDSPath); |
| 300 | if($strName =~/ldsBL.*\_ext\./i) |
| 301 | { |
| 302 | return EXT_BL; |
| 303 | } |
| 304 | elsif($strName =~/ldsBL.*\./i) |
| 305 | { |
| 306 | return BL; |
| 307 | } |
| 308 | else |
| 309 | { |
| 310 | return MAIN; |
| 311 | } |
| 312 | } |
| 313 | #**************************************************************************** |
| 314 | # subroutine: Get_Template_DiffER_In_SYM_but_Not_in_LDS |
| 315 | # input: $SYMER_href: a hash reference contains regions in sym but not in lds |
| 316 | # return: Template shown in log file: regions in sym but not in lds |
| 317 | #**************************************************************************** |
| 318 | sub Get_Template_DiffER_In_SYM_but_Not_in_LDS |
| 319 | { |
| 320 | my ($SYMER_href) = @_; |
| 321 | my $template; |
| 322 | #------ Linker Output Found Strange Regions --------; |
| 323 | map{$template .= "$_\n";}sort keys %$SYMER_href; |
| 324 | return $template; |
| 325 | } |
| 326 | |
| 327 | #**************************************************************************** |
| 328 | # subroutine: Get_Template_InvalidObjList |
| 329 | # input: $OddList_href: a hash reference contains regions in sym but not in lds |
| 330 | # return: Template shown in log file, e.g. |
| 331 | # |1. Objects as below are wrapped in invalid section(C$$code): |
| 332 | # |ex_hdlr_gcc.obj |
| 333 | # |stack_gcc.obj |
| 334 | # | |
| 335 | #**************************************************************************** |
| 336 | sub Get_Template_InvalidObjList |
| 337 | { |
| 338 | my ($OddList_href) = @_; |
| 339 | my $template; |
| 340 | my $i=1; |
| 341 | foreach my $ER(sort keys %$OddList_href) |
| 342 | { |
| 343 | ##################################################################################### |
| 344 | # The following pattern($ER) is used in m notify for finding the corresponding owner. |
| 345 | # If any change, you have to sync with ErrorMsg Handler BM for the modification information. |
| 346 | $template .= "$i. Objects as below are wrapped in invalid section($ER):\n"; |
| 347 | ##################################################################################### |
| 348 | map{ $template.= $_."\n";} @{$OddList_href->{$ER}}; |
| 349 | $template.= "\n"; |
| 350 | $i++; |
| 351 | } |
| 352 | return $template; |
| 353 | } |
| 354 | |
| 355 | sub Print_LDS_ERList_Not_In_SYM |
| 356 | { |
| 357 | my ($LDSER_href) = @_; |
| 358 | print "------ LDSRegionList not in SYM -------\n"; |
| 359 | map{print "$_\n";}sort keys %$LDSER_href; |
| 360 | } |
| 361 | |
| 362 | sub Print_SameER_In_SYM_and_LDS |
| 363 | { |
| 364 | my ($ER_aref) = @_; |
| 365 | print "------ The Same RegionList in SYM and LDS -------\n"; |
| 366 | map{print "$_\n";} @$ER_aref; |
| 367 | } |
| 368 | #**************************************************************************** |
| 369 | # subroutine: error_handler |
| 370 | # input : $error_msg |
| 371 | # $bPrintDirectly: undef or 0=using formal format to show error message, |
| 372 | # 1=print error message directly without adding any other message |
| 373 | # return: none |
| 374 | #**************************************************************************** |
| 375 | sub error_handler |
| 376 | { |
| 377 | my ($error_msg, $bPrintDirectly) = @_; |
| 378 | my $todie = $g_stop_build; |
| 379 | my ($pack_name, $file, $line_no) = caller; |
| 380 | my $final_error_msg = ($bPrintDirectly) ? $error_msg: "CKMEMLAYOUT ERROR: \n$error_msg\nat $file line $line_no\n"; |
| 381 | print $final_error_msg if ($todie ne 'TRUE'); |
| 382 | die $final_error_msg if ($todie eq 'TRUE'); |
| 383 | } |
| 384 | |
| 385 | |
| 386 | sub Get_Template_ErrorHandlingSOP |
| 387 | { |
| 388 | my ($nLdsType, $nCoreType) = @_; |
| 389 | my $title = ERROR_HANDLING_SOP; |
| 390 | my $template= "-------------------$title--------------------\n";; |
| 391 | my $strPath = &GetSOPPath($nLdsType, $nCoreType); |
| 392 | if(-e $strPath) |
| 393 | { |
| 394 | $template .= &CommonUtil::GetFileContent($strPath) . "\n"; |
| 395 | } |
| 396 | else |
| 397 | { |
| 398 | $template .= "Please refer to $strPath\n\n"; |
| 399 | } |
| 400 | $template .= "-------------------------------------------------------------\n"; |
| 401 | return $template; |
| 402 | } |
| 403 | |
| 404 | sub GetSOPPath |
| 405 | { |
| 406 | my ($nLdsType, $nCoreType) = @_; |
| 407 | my $strPath = "./YYY/custom/system/Template/XXX/InputSectionRule.txt"; |
| 408 | if($nLdsType == MAIN) |
| 409 | { |
| 410 | $strPath =~ s/XXX/lds_config/; |
| 411 | } |
| 412 | elsif($nLdsType == BL) |
| 413 | { |
| 414 | $strPath =~ s/XXX/BL_lds_config/; |
| 415 | } |
| 416 | elsif($nLdsType == EXT_BL) |
| 417 | { |
| 418 | $strPath = ~s/XXX/EXT_BL_lds_config/; |
| 419 | } |
| 420 | |
| 421 | if($nCoreType == PCORE_TYPE) |
| 422 | { |
| 423 | $strPath =~ s/YYY/pcore/; |
| 424 | } |
| 425 | elsif($nCoreType == L1CORE_TYPE) |
| 426 | { |
| 427 | $strPath =~ s/YYY/l1core/; |
| 428 | } |
| 429 | |
| 430 | $strPath = "./custom/system/Template/lds_config/InputSectionRule.txt"; |
| 431 | |
| 432 | return $strPath; |
| 433 | } |
| 434 | |
| 435 | #**************************************************************************** |
| 436 | # subroutine: Get_Template_Caution |
| 437 | # return: Template shown in log file to tell folks the risks |
| 438 | #**************************************************************************** |
| 439 | sub Get_Template_Caution |
| 440 | { |
| 441 | my $template = <<"__TEMPLATE"; |
| 442 | |
| 443 | ===================================================================== |
| 444 | [!!Caution!!] |
| 445 | Some functions, variables or assembly codes |
| 446 | in the following object list are wrapped around invalid sections, |
| 447 | which may cause bring-up failed due to region init not handling invalid regions. |
| 448 | Please fix it with Error Handling SOP as below. |
| 449 | |
| 450 | __TEMPLATE |
| 451 | return $template; |
| 452 | } |
| 453 | |