yu.dong | c33b307 | 2024-08-21 23:14:49 -0700 | [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) 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 | #* ldsFrame.pm |
| 40 | #* |
| 41 | #* Project: |
| 42 | #* -------- |
| 43 | #* |
| 44 | #* |
| 45 | #* Description: |
| 46 | #* ------------ |
| 47 | #* This script is to generate the frame of memory layout |
| 48 | #* and provides the flow of generation |
| 49 | #* |
| 50 | #* Author: |
| 51 | #* ------- |
| 52 | #* Carl Kao (mtk08237) |
| 53 | #* |
| 54 | #****************************************************************************/ |
| 55 | #**************************************************************************** |
| 56 | # Included Modules |
| 57 | #**************************************************************************** |
| 58 | use strict; |
| 59 | BEGIN { push @INC, './tools/' } # add additional library path |
| 60 | use ldsInfo; |
| 61 | use CommonUtility; |
| 62 | use sysGenUtility; |
| 63 | package ldsFrame; |
| 64 | #**************************************************************************** |
| 65 | # oo >>> Finished |
| 66 | #**************************************************************************** |
| 67 | return 1; |
| 68 | |
| 69 | #**************************************************************************** |
| 70 | # ldsFrame Version |
| 71 | #**************************************************************************** |
| 72 | sub ldsFrame_verno |
| 73 | { |
| 74 | return " u0.05"; |
| 75 | # u0.05, 2016/06/21 by Tero, Fixed Memory parsing |
| 76 | # u0.04, 2016/01/19 by Tero, Fixed ASSERT multiple parenthesis issue |
| 77 | # u0.03, 2015/10/19 by Carl, Catch invalid input section |
| 78 | # u0.02, 2014/12/17 by Carl, Support multiple overlap section |
| 79 | # u0.01, 2014/02/20 by BM, Initial version |
| 80 | # m0.28 , 20130913 by mei, Fix symbol bug |
| 81 | # m0.27 , 20130605 by mei, Make input section file name more flexible in OVERLAY section |
| 82 | # m0.26 , 20130115 by mei, Change Default csv name to Default.csv |
| 83 | # m0.25 , 20130114 by mei, Set LDSType to be MAIN by default |
| 84 | # m0.24 , 20130113 by mei, Support template getting from build folder first |
| 85 | # m0.23 , 20121030 by mei, Support more flexible ASSERT in Action, |
| 86 | # Support EndAction (to put Action in the end) |
| 87 | # m0.22 , 20121029 by mei, Support MEMORY without counting reserved region |
| 88 | # m0.21 , 20121020 by mei, Make addresses in OVERLAY region be 4 bytes aligned |
| 89 | # m0.20 , 20121002 by mei, Make all lengths are 4 bytes aligned for region-init |
| 90 | # m0.19 , 20120827 by mei, Support Head input sections |
| 91 | # m0.18 , 20120817 by mei, Support SetMemorySetting() without calling callback if no need to replace |
| 92 | # m0.17 , 20120816 by mei, Change symbol assignment in OVERLAY to fix ld's bug |
| 93 | # m0.16 , 20120816 by mei, Support Input section with Common Block, Chip Block and DefaultChip Block |
| 94 | # m0.15 , 20120727 by mei, Refine lds output format |
| 95 | # m0.14 , 20120724 by mei, Support MaxSize ASSERT |
| 96 | # m0.13 , 20120713 by mei, Support atomic Type(e.g. not accept //SectionFrame) |
| 97 | # Fix LoadAddress' bug |
| 98 | # Support Default address(top and bottom) align 4 bytes |
| 99 | # m0.12 , 20120712 by mei, Remove EWS since no need to add dependency in pm file |
| 100 | # m0.11 , 20120710 by mei, Support input section got from chip.txt as well |
| 101 | # m0.10 , 20120702 by mei, Support EWS |
| 102 | # m0.09 , 20120702 by mei, Support Memory Setting with booting type via GetBootingType() |
| 103 | # m0.08 , 20120625 by mei, Use scalar instead of $# |
| 104 | # m0.07 , 20120615 by mei, Support using $# on Linux |
| 105 | # m0.06 , 20120530 by mei, Support RegionList by chip |
| 106 | # m0.05 , 20120530 by mei, Fix CleanCallBackFunc()'s bug |
| 107 | # m0.04 , 20120528 by mei, Support path and filename case sensitive on Linux |
| 108 | # m0.03 , 20120513 by mei, Support BLldsGen |
| 109 | # m0.02 , 20120507 by mei, Fix ACTION behavior |
| 110 | # m0.01 , 20120507 by mei, initial version |
| 111 | } |
| 112 | #**************************************************************************** |
| 113 | # Constants |
| 114 | #**************************************************************************** |
| 115 | #**************************************************************************** |
| 116 | # Global Variables |
| 117 | #**************************************************************************** |
| 118 | my %Func = ("CollectMemorySetting" => undef, |
| 119 | "SetMemorySegment" => undef, # not necessary |
| 120 | "GetChip" => undef, |
| 121 | "SetRegionList" => undef, |
| 122 | "GetBootingType" => undef, |
| 123 | "GetCustomFolder" => undef, # to get CustomFolder's template first |
| 124 | ); |
| 125 | my %g_MEMORYSetting; |
| 126 | my $g_nLDSType = 0; #default be MAIN |
| 127 | #**************************************************************************** |
| 128 | # Input Parameters |
| 129 | #**************************************************************************** |
| 130 | use constant BASIC => 0; |
| 131 | use constant MEMORY => 1; |
| 132 | use constant InputSections => 2; |
| 133 | use constant RegionList => 3; |
| 134 | #LDS Type |
| 135 | use constant MAIN => 0; |
| 136 | use constant BL => 1; |
| 137 | use constant EXT_BL => 2; |
| 138 | use constant FOTA => 3; |
| 139 | #Input Section File Name |
| 140 | use constant COMMON_InputSection => "Common"; |
| 141 | use constant ChipDependent_Default_InputSection => "DefaultChip"; |
| 142 | use constant HEAD_InputSection => "Head"; |
| 143 | #**************************************************************************** |
| 144 | # subroutines |
| 145 | #**************************************************************************** |
| 146 | sub GetLDSType |
| 147 | { |
| 148 | my %LDSFolderName = (0 => "lds_config", |
| 149 | 1 => "BL_lds_config", |
| 150 | 2 => "EXT_BL_lds_config", |
| 151 | ); |
| 152 | &ldsFrame_die("unsupport LDSType: $g_nLDSType \n", __FILE__, __LINE__) if(!exists $LDSFolderName{$g_nLDSType}); |
| 153 | return $LDSFolderName{$g_nLDSType}; |
| 154 | } |
| 155 | #ldsFrame::GetPath("MT6280", ldsFrame::MEMORY) |
| 156 | #ldsFrame::GetPath("ROM", ldsFrame::InputSections) |
| 157 | #ldsFrame::GetPath("MT6280", ldsFrame::RegionList) |
| 158 | sub GetPath |
| 159 | { |
| 160 | my ($strKey, $nType) = @_; |
| 161 | my $strPath = undef; |
| 162 | my $LDSFolderName = &GetLDSType(); |
| 163 | my $strDefaultSystemFolder = "./custom/system"; |
| 164 | my $strTemplateFolder = "$strDefaultSystemFolder/Template/$LDSFolderName/"; |
| 165 | my %PathMap = ("ldsMainFrame" => "ldsTemplate/ldsMainFrame.txt", |
| 166 | "RegionList" => "RegionConfig/", |
| 167 | "MEMORY" => "ldsTemplate/MEMORY/", |
| 168 | "InputSections" => "InputSections/", |
| 169 | ); |
| 170 | if($nType == BASIC) |
| 171 | { |
| 172 | $strPath = $strTemplateFolder . $PathMap{$strKey}; |
| 173 | } |
| 174 | elsif($nType == MEMORY) |
| 175 | { |
| 176 | $strPath = $strTemplateFolder.$PathMap{MEMORY}.$strKey."_".&{$Func{GetBootingType}}().".txt" if(defined $Func{GetBootingType}); |
| 177 | $strPath = $strTemplateFolder.$PathMap{MEMORY}.$strKey.".txt" if(!-e $strPath);; |
| 178 | } |
| 179 | elsif($nType == RegionList) |
| 180 | { |
| 181 | $strPath = $strTemplateFolder.$PathMap{RegionList}.$strKey.".csv"; |
| 182 | $strPath = $strTemplateFolder.$PathMap{RegionList}."Default.csv" if(!-e $strPath); |
| 183 | $strPath = $strTemplateFolder.$PathMap{RegionList}."RegionList.csv" if(!-e $strPath); # for backward compatible |
| 184 | } |
| 185 | elsif($nType == InputSections) |
| 186 | { |
| 187 | $strPath = $strTemplateFolder . $PathMap{InputSections}.$strKey."/"; |
| 188 | } |
| 189 | else |
| 190 | { |
| 191 | &ldsFrame_die("[GetPath]Unsupport Type", __FILE__, __LINE__); |
| 192 | } |
| 193 | if(exists $Func{GetCustomFolder}) |
| 194 | { |
| 195 | my $strCustomedFolder = &{$Func{GetCustomFolder}}(); |
| 196 | my $strCustomedPath = $strPath; |
| 197 | $strCustomedPath =~ s/$strDefaultSystemFolder/$strCustomedFolder/; |
| 198 | $strPath = $strCustomedPath if(-e $strCustomedPath); |
| 199 | } |
| 200 | return $strPath; |
| 201 | } |
| 202 | |
| 203 | |
| 204 | |
| 205 | #**************************************************************************** |
| 206 | # subroutine: ProcessTemplate |
| 207 | # Input: $strFilePath: the file to be processed |
| 208 | # $strKeyFinding: e.g. ldsGen or AUTOGEN |
| 209 | # Output: $content: the content after processing |
| 210 | # Description: if there is the pattern as [ldsGen_funcname], |
| 211 | # the whole pattern will be replaced by calling funcname(). |
| 212 | # if funcname() doesn't exist, it'll fail and report error. |
| 213 | #**************************************************************************** |
| 214 | sub ProcessTemplate |
| 215 | { |
| 216 | my ($strFilePath, $strKeyFinding) = @_; |
| 217 | my $content; |
| 218 | open (FILE_HANDLE, $strFilePath) or &ldsFrame_die("Cannot open $strFilePath\n", __FILE__, __LINE__); |
| 219 | while(<FILE_HANDLE>) |
| 220 | { |
| 221 | my $strLine = $_; |
| 222 | while ($strLine =~ /\[$strKeyFinding\_(\w+)\]/) |
| 223 | { |
| 224 | my $func = $1; |
| 225 | my $template; |
| 226 | { |
| 227 | no strict 'refs'; |
| 228 | $template = &{$func}() if(exists &{$func}) |
| 229 | or &ldsFrame_die("$func() doesn't exist!\n", __FILE__, __LINE__); |
| 230 | } |
| 231 | chomp($strLine); |
| 232 | $strLine =~ s/\[$strKeyFinding\_$func\]/$template/g; |
| 233 | } |
| 234 | $content .= $strLine; |
| 235 | } |
| 236 | close FILE_HANDLE; |
| 237 | return $content; |
| 238 | } |
| 239 | |
| 240 | sub ProcessSection |
| 241 | { |
| 242 | my ($strContent, $Info_ref, $Index_ref) = @_; |
| 243 | my @lines = split(/\n/, $strContent); |
| 244 | my $strResult; |
| 245 | foreach my $strLine (@lines) |
| 246 | { |
| 247 | while ($strLine =~ /\[ldsGen_(\w+)\]/) |
| 248 | { |
| 249 | my $func = "Gen".$1; |
| 250 | my $template; |
| 251 | { |
| 252 | no strict 'refs'; |
| 253 | |
| 254 | $template = &{$func}($Info_ref, $Index_ref) if(exists &{$func}) |
| 255 | or &ldsFrame_die("[ProcessSection]$func() doesn't exist!\n", __FILE__, __LINE__); |
| 256 | } |
| 257 | $strLine =~ s/\[ldsGen_$1\]/$template/g; |
| 258 | } |
| 259 | $strResult .= $strLine . "\n"; |
| 260 | } |
| 261 | return $strResult; |
| 262 | } |
| 263 | |
| 264 | #**************************************************************************** |
| 265 | sub GenLDS |
| 266 | { |
| 267 | ($g_nLDSType) = @_; |
| 268 | #Check CallBack functions |
| 269 | |
| 270 | my $strLayout = &ProcessTemplate( &GetPath("ldsMainFrame", BASIC) , "ldsGen"); |
| 271 | return $strLayout; |
| 272 | } |
| 273 | |
| 274 | sub CleanCallBackFunc |
| 275 | { |
| 276 | foreach (keys %Func) |
| 277 | { |
| 278 | delete $Func{$_}; |
| 279 | } |
| 280 | %g_MEMORYSetting = (); |
| 281 | $g_nLDSType = 0; |
| 282 | } |
| 283 | sub SetCallBackFunc |
| 284 | { |
| 285 | my ($strKey, $func) = @_; |
| 286 | $Func{$strKey} = $func; |
| 287 | } |
| 288 | |
| 289 | #**************************************************************************** |
| 290 | sub GenMEMORY |
| 291 | { |
| 292 | my $MEMORYPath = &GetPath(&{$Func{GetChip}}(), MEMORY); |
| 293 | my $MEMORYContent = &CommonUtil::GetFileContent($MEMORYPath); |
| 294 | my $MEMORY_SEGMENT_aref = &ldsInfo::ParseMEMORY($MEMORYContent); |
| 295 | my ($RegionList_ref, $Index_ref)= &PreProcessRegionList(undef); |
| 296 | &SetMemorySetting($MEMORY_SEGMENT_aref, $MEMORYPath, $RegionList_ref, $Index_ref); |
| 297 | &{$Func{SetMemorySegment}}($MEMORY_SEGMENT_aref) if(exists $Func{SetMemorySegment}); # for extension, not used now |
| 298 | my $strMEMORY; |
| 299 | foreach my $i (@$MEMORY_SEGMENT_aref) |
| 300 | { |
| 301 | if (!defined $i->[1]) |
| 302 | { |
| 303 | $strMEMORY .="$i->[0]\n"; |
| 304 | next; |
| 305 | } |
| 306 | $strMEMORY .= " $i->[0] : ORIGIN = $i->[1], LENGTH = $i->[2]\n"; |
| 307 | my $nBase = eval($i->[1]); |
| 308 | my $nLen = eval($i->[2]); |
| 309 | $g_MEMORYSetting{$i->[0]} = [&CommonUtil::Dec2Hex($nBase), |
| 310 | &CommonUtil::Dec2Hex($nLen)]; |
| 311 | } |
| 312 | return $strMEMORY; |
| 313 | } |
| 314 | |
| 315 | sub SetMemorySetting |
| 316 | { |
| 317 | my ($MEMORY_SEGMENT_aref, $MEMORYPath, $RegionList_ref, $Index_ref) = @_; |
| 318 | if(exists $Func{CollectMemorySetting}) |
| 319 | { |
| 320 | my $Setting = &{$Func{CollectMemorySetting}}($MEMORYPath, , $RegionList_ref, $Index_ref); |
| 321 | foreach my $i (@$MEMORY_SEGMENT_aref) |
| 322 | { |
| 323 | while($i->[1] =~ /\[(\S+)\]/) |
| 324 | { |
| 325 | my $temp = $1; |
| 326 | &ldsFrame_die("$1 in\n$MEMORYPath\n isn't set in CollectMemorySetting()!\n", __FILE__, __LINE__) if(!exists $Setting->{$1}); |
| 327 | $i->[1] =~ s/\[$temp\]/$Setting->{$temp}/g; |
| 328 | } |
| 329 | while($i->[2] =~ /\[(\S+)\]/) |
| 330 | { |
| 331 | my $temp = $1; |
| 332 | &ldsFrame_die("$1 in\n$MEMORYPath\n isn't set in CollectMemorySetting()!\n", __FILE__, __LINE__) if(!exists $Setting->{$1}); |
| 333 | $i->[2] =~ s/\[$temp\]/$Setting->{$temp}/g; |
| 334 | } |
| 335 | } |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | sub PreProcessRegionList |
| 340 | { |
| 341 | my ($MEMORYSetting_href) = @_; |
| 342 | my $RegionListPath = &GetPath(&{$Func{GetChip}}(), RegionList); |
| 343 | my ($BasicRegionList_ref, $Index_ref) = &CommonUtil::ParseCSV($RegionListPath, undef); |
| 344 | my $RegionList_ref = $BasicRegionList_ref; |
| 345 | $RegionList_ref = &{$Func{SetRegionList}}($BasicRegionList_ref, $Index_ref, $MEMORYSetting_href) |
| 346 | if(exists $Func{SetRegionList}); |
| 347 | return ($RegionList_ref, $Index_ref); |
| 348 | } |
| 349 | |
| 350 | #**************************************************************************** |
| 351 | sub GenSECTIONS |
| 352 | { |
| 353 | my $strLayout; |
| 354 | my ($RegionList_ref, $Index_ref) = &PreProcessRegionList(\%g_MEMORYSetting); |
| 355 | &SetHints_Symbols_Nearby_InputSections($RegionList_ref, $Index_ref); |
| 356 | my $LOADADDR_template; |
| 357 | my $LengthSymbol_template; |
| 358 | my $ASSERT_template; |
| 359 | my $End_template; |
| 360 | my $strPreviousType; |
| 361 | my @OVERLAY_items; |
| 362 | my $strOVERLAY_base; |
| 363 | foreach my $item (@$RegionList_ref) |
| 364 | { |
| 365 | my $strType = $item->[$Index_ref->{Type}]; |
| 366 | |
| 367 | if( $strPreviousType =~ /^OVERLAY$/i and ($strType !~ /^OVERLAY$/i or $strOVERLAY_base ne $item->[$Index_ref->{BaseRegion}]) ) |
| 368 | { |
| 369 | my ($template, $strLOADADDR, $strLengthSymbol)= &FillOVERLAYSectionFrame(\@OVERLAY_items, $Index_ref); |
| 370 | $strLayout .=$template; |
| 371 | $LOADADDR_template .= $strLOADADDR; |
| 372 | $LengthSymbol_template .= $strLengthSymbol; |
| 373 | @OVERLAY_items = (); |
| 374 | $strOVERLAY_base = ""; |
| 375 | } |
| 376 | |
| 377 | if( $strType =~ /^OVERLAY$/i) |
| 378 | { |
| 379 | push @OVERLAY_items, $item; |
| 380 | $strOVERLAY_base = $item->[$Index_ref->{BaseRegion}]; |
| 381 | } |
| 382 | elsif( $strType =~ /^SectionFrame$/i) |
| 383 | { |
| 384 | $strLayout .= &ProcessSection(&Gen_TEMPLATE_SECTION(), $item, $Index_ref); |
| 385 | $LOADADDR_template .= &Gen_TEMPLATE_LOADADDR($item, $Index_ref); |
| 386 | $LengthSymbol_template .= &Gen_TEMPLATE_LengthSymbol($item, $Index_ref); |
| 387 | $ASSERT_template .= &Gen_TEMPLATE_ASSERT($item, $Index_ref); |
| 388 | } |
| 389 | elsif($strType =~ /^ACTION$/i or $strType =~ /^ENDACTION$/i) |
| 390 | { |
| 391 | my $CMPLOption = $item->[$Index_ref->{CompileOption}]; |
| 392 | my $FeatureOption = $item->[$Index_ref->{Condition}]; |
| 393 | my @temp = map{ $_ if(($_ ne $strType) and ($_ ne $CMPLOption) and ($_ ne $FeatureOption)) } @$item; |
| 394 | my $strACTION = &CommonUtil::ConnetString(\@temp, ",", undef); |
| 395 | if($strACTION =~ /^ASSERT/ or $strACTION =~ /^\"\s*ASSERT/) |
| 396 | { |
| 397 | $strACTION =~ s/\"//g; |
| 398 | $strACTION =~ s/\,\s*/\,\"/; |
| 399 | $strACTION =~ s/\)$/\"\)/; |
| 400 | } |
| 401 | $End_template .= " $strACTION\n" if($strType=~/END/i); |
| 402 | $strLayout .= " $strACTION\n" if($strType!~/END/i); |
| 403 | } |
| 404 | elsif($strType =~/^LinkerSymbol$/i) |
| 405 | { |
| 406 | $strLayout .= &FillLinkerSymbol($item, $Index_ref); |
| 407 | } |
| 408 | $strPreviousType = $strType; |
| 409 | } |
| 410 | $strLayout .= $LOADADDR_template . $LengthSymbol_template . $ASSERT_template . $End_template; |
| 411 | return $strLayout; |
| 412 | } |
| 413 | |
| 414 | |
| 415 | sub AvoidOrphanSECTIONS |
| 416 | { |
| 417 | my $strLayout; |
| 418 | my ($RegionList_ref, $Index_ref) = &PreProcessRegionList(\%g_MEMORYSetting); |
| 419 | &SetHints_Symbols_Nearby_InputSections($RegionList_ref, $Index_ref); |
| 420 | #my $LOADADDR_template; |
| 421 | #my $LengthSymbol_template; |
| 422 | #my $ASSERT_template; |
| 423 | #my $End_template; |
| 424 | my $strPreviousType; |
| 425 | my @OVERLAY_items; |
| 426 | my $strOVERLAY_base; |
| 427 | foreach my $item (@$RegionList_ref) |
| 428 | { |
| 429 | my $strType = $item->[$Index_ref->{Type}]; |
| 430 | |
| 431 | if( $strPreviousType =~ /^OVERLAY$/i and ($strType !~ /^OVERLAY$/i or $strOVERLAY_base ne $item->[$Index_ref->{BaseRegion}]) ) |
| 432 | { |
| 433 | #@OVERLAY_items = (); |
| 434 | $strOVERLAY_base = ""; |
| 435 | } |
| 436 | |
| 437 | if( $strType =~ /^OVERLAY$/i) |
| 438 | { |
| 439 | #push @OVERLAY_items, $item; |
| 440 | $strOVERLAY_base = $item->[$Index_ref->{BaseRegion}]; |
| 441 | |
| 442 | my $strName = $item->[$Index_ref->{Name}]; |
| 443 | next if ($strName =~ /\.text$|\.rodata$|.data$|\.bss$/); |
| 444 | $strName =~ s/#//g; |
| 445 | $strLayout .= " "x4 ."INVALID_INPUT_SECTION__$strName 0xDEAD0000 : { * ($strName); }\n"; |
| 446 | } |
| 447 | elsif( $strType =~ /^SectionFrame$/i) |
| 448 | { |
| 449 | my $strName = $item->[$Index_ref->{Name}]; |
| 450 | next if ($strName =~ /\.text$|\.rodata$|.data$|\.bss$|bss$/); |
| 451 | $strName =~ s/#//g; |
| 452 | $strLayout .= " "x4 ."INVALID_INPUT_SECTION__$strName 0xDEAD0000 : { * ($strName); }\n"; |
| 453 | } |
| 454 | $strPreviousType = $strType; |
| 455 | } |
| 456 | #$strLayout .= "LONG(0);\n"; |
| 457 | $strLayout = " "x4 ."\/\* If build fail with logs in link.log like this \n". |
| 458 | " "x12 ."\"section INVALID_INPUT_SECTION__XX_section_name loaded at [00000000,00000003] overlaps section ROM_GFH loaded at [00000000,000004af]\"\n". |
| 459 | " "x8 ."It means there are wrong input sections \"XX_section_name.\"\n". |
| 460 | " "x8 ."Please use correct input section name by following the rules in mcu/custom/system/Template/lds_config/InputSectionRule.txt\n". |
| 461 | " "x8 ."If you cannot find the symbol, please use \"\.\/m gendummy\" command.\n". |
| 462 | " "x8 ."A dummy sym file will be generated in bin folder. Search the keyword INVALID_INPUT_SECTION to find the symbol\n". |
| 463 | " "x4 ."\*\/\n". |
| 464 | $strLayout if(0); |
| 465 | |
| 466 | return $strLayout; |
| 467 | } |
| 468 | |
| 469 | sub FillLinkerSymbol #Called by GenSECTIONS() |
| 470 | { |
| 471 | my ($Info_ref, $Index_ref) = @_; |
| 472 | my $template; |
| 473 | my $AttributeIndex = $Index_ref->{Attribute}; |
| 474 | my $NameIndex = $Index_ref->{Name}; |
| 475 | if($Info_ref->[$AttributeIndex] =~ /(\S+)::(\S+)/) |
| 476 | { |
| 477 | my $strPostfix = $2; |
| 478 | my $strPrefix = $1 =~ /EV/ ? "Image" : "Load"; |
| 479 | if($strPostfix =~ /ZIBase/i) |
| 480 | { |
| 481 | $template = 'Image$$' . $Info_ref->[$NameIndex] . '$$ZI$$Base'; |
| 482 | } |
| 483 | elsif($strPostfix =~ /ZILength/i) |
| 484 | { |
| 485 | $template = 'Image$$' . $Info_ref->[$NameIndex] . '$$ZI$$Length'; |
| 486 | } |
| 487 | elsif($strPostfix =~ /ZILimit/i) |
| 488 | { |
| 489 | $template = 'Image$$' . $Info_ref->[$NameIndex] . '$$ZI$$Limit'; |
| 490 | } |
| 491 | elsif($strPostfix =~ /Base/i) |
| 492 | { |
| 493 | $template = $strPrefix . '$$' . $Info_ref->[$NameIndex] . '$$Base'; |
| 494 | } |
| 495 | elsif($strPostfix =~ /Length/i) |
| 496 | { |
| 497 | $template = 'Image$$' . $Info_ref->[$NameIndex] . '$$Length'; |
| 498 | } |
| 499 | elsif($strPostfix =~ /Limit/i) |
| 500 | { |
| 501 | $template = 'Image$$' . $Info_ref->[$NameIndex] . '$$Limit'; |
| 502 | } |
| 503 | my $VMA = $Info_ref->[$Index_ref->{VMA}]; |
| 504 | return ' 'x4 . $template . " = $VMA;" . "\n"; |
| 505 | } |
| 506 | return ""; |
| 507 | } |
| 508 | sub FillOVERLAYSectionFrame #Called by GenSECTIONS() |
| 509 | { |
| 510 | my ($Infos_ref, $Index_ref) = @_; |
| 511 | my ($OVERLAY_template, $strLOADADDR, $strLengthSymbol) = &Gen_TEMPLATE_OVERLAY($Infos_ref, $Index_ref); |
| 512 | my $template = &ProcessSection($OVERLAY_template, $Infos_ref->[0], $Index_ref); |
| 513 | return ($template, $strLOADADDR, $strLengthSymbol); |
| 514 | } |
| 515 | #**************************************************************************** |
| 516 | sub GenBaseRegionName # Called by ProcessSection() |
| 517 | { |
| 518 | my ($Info_ref, $Index_ref) = @_; |
| 519 | my $strBaseRegion = $Info_ref->[$Index_ref->{BaseRegion}]; |
| 520 | my $strOrgRegion = $Info_ref->[$Index_ref->{Name}]; |
| 521 | my $strType = $Info_ref->[$Index_ref->{Type}]; |
| 522 | my $strName = ($strBaseRegion eq "" or $strType =~ /^OVERLAY$/i) ? $strOrgRegion : $strBaseRegion; |
| 523 | $strName =~ s/\#//g; #workaround because .xxx can't be a folder name or a file name |
| 524 | return $strName; |
| 525 | } |
| 526 | sub GenRegionName # Called by ProcessSection() |
| 527 | { |
| 528 | my ($Info_ref, $Index_ref) = @_; |
| 529 | my $strName = $Info_ref->[$Index_ref->{Name}]; |
| 530 | $strName =~ s/\#//g; #workaround because .xxx can't be a folder name or a file name |
| 531 | $strName = ".bss" if($strName eq "bss"); |
| 532 | return $strName; |
| 533 | } |
| 534 | sub GenVMA # Called by ProcessSection() |
| 535 | { |
| 536 | my ($Info_ref, $Index_ref) = @_; |
| 537 | return $Info_ref->[$Index_ref->{VMA}]; |
| 538 | } |
| 539 | sub GenLMA # Called by ProcessSection() |
| 540 | { |
| 541 | my ($Info_ref, $Index_ref) = @_; |
| 542 | my $strLMA = ""; |
| 543 | $strLMA = "AT($Info_ref->[$Index_ref->{LMA}])" if($Info_ref->[$Index_ref->{LMA}] ne ""); |
| 544 | return $strLMA; |
| 545 | } |
| 546 | sub GenRegionAttr # Called by ProcessSection() |
| 547 | { |
| 548 | my ($Info_ref, $Index_ref) = @_; |
| 549 | my $strAttr = ""; |
| 550 | $strAttr = "(NOLOAD)" if($Info_ref->[$Index_ref->{Attribute}] eq "ZI"); |
| 551 | return $strAttr; |
| 552 | } |
| 553 | sub GenInputSections # Called by ProcessSection() |
| 554 | { |
| 555 | my ($Info_ref, $Index_ref) = @_; |
| 556 | my $RegionName = $Info_ref->[$Index_ref->{Name}]; |
| 557 | my $InputSectionFolder = &GetPath($RegionName, InputSections); |
| 558 | my $InputSections; |
| 559 | my $SpecificChipPath = $InputSectionFolder.&{$Func{GetChip}}().".txt"; |
| 560 | my $DefaultChipPath = $InputSectionFolder.ChipDependent_Default_InputSection.".txt"; |
| 561 | my $HeadPath = $InputSectionFolder.HEAD_InputSection.".txt"; |
| 562 | if(-e $HeadPath) |
| 563 | { |
| 564 | $InputSections = &CommonUtil::GetFileContent($HeadPath)."\n"; |
| 565 | } |
| 566 | if(-e $SpecificChipPath) |
| 567 | { |
| 568 | $InputSections .= &CommonUtil::GetFileContent($SpecificChipPath)."\n"; |
| 569 | } |
| 570 | elsif(-e $DefaultChipPath) |
| 571 | { |
| 572 | $InputSections .= &CommonUtil::GetFileContent($DefaultChipPath)."\n"; |
| 573 | } |
| 574 | my $CommonPath = $InputSectionFolder.COMMON_InputSection.".txt"; |
| 575 | $InputSections .= &CommonUtil::GetFileContent($CommonPath); |
| 576 | return $InputSections; |
| 577 | } |
| 578 | sub GenExecutionRegion # Called by ProcessSection() |
| 579 | { |
| 580 | my ($Info_ref, $Index_ref) = @_; |
| 581 | my $ExecutionView = ""; |
| 582 | $ExecutionView = " > $Info_ref->[$Index_ref->{ExecutionView}]" if($Info_ref->[$Index_ref->{ExecutionView}] ne ""); |
| 583 | return $ExecutionView; |
| 584 | } |
| 585 | sub GenLoadRegion # Called by ProcessSection() |
| 586 | { |
| 587 | my ($Info_ref, $Index_ref) = @_; |
| 588 | my $LoadView = ""; |
| 589 | $LoadView = " AT> $Info_ref->[$Index_ref->{LoadView}]" if($Info_ref->[$Index_ref->{LoadView}] ne ""); |
| 590 | return $LoadView; |
| 591 | } |
| 592 | sub GenALIGN # Called by ProcessSection() |
| 593 | { |
| 594 | my ($Info_ref, $Index_ref) = @_; |
| 595 | my $strALIGN = ""; |
| 596 | $strALIGN = "ALIGN(4)" if($Info_ref->[$Index_ref->{Type}] !~ /^OVERLAY$/i); |
| 597 | $strALIGN = $Info_ref->[$Index_ref->{ALIGN}] if($Info_ref->[$Index_ref->{ALIGN}] ne ""); |
| 598 | return $strALIGN; |
| 599 | } |
| 600 | |
| 601 | #**************************************************************************** |
| 602 | sub InsertBasicHintSymbols #used by SetHints_Symbols_Nearby_InputSections |
| 603 | { |
| 604 | my ($RegionList_ref, $Index_ref, $Hints_ref) = @_; |
| 605 | $Index_ref->{Symbols} = keys %$Index_ref; |
| 606 | my $SymbolIndex = $Index_ref->{Symbols}; |
| 607 | for(my $i=0; $i < scalar(@$RegionList_ref); $i++) |
| 608 | { |
| 609 | my $item = $RegionList_ref->[$i]; |
| 610 | my $strType = $item->[$Index_ref->{Type}]; |
| 611 | if( $strType =~ /^SectionFrame$/) |
| 612 | { |
| 613 | my %Symbols = ("Base"=>0, "Limit" =>1, "ZIBase"=>1, "ZILimit"=>1); |
| 614 | $item->[$SymbolIndex] = \%Symbols; |
| 615 | my $BaseRegion = $item->[$Index_ref->{BaseRegion}]; |
| 616 | if($BaseRegion ne "") |
| 617 | { |
| 618 | $Hints_ref->{$BaseRegion} = [] if(!exists $Hints_ref->{$BaseRegion}); |
| 619 | push(@{$Hints_ref->{$BaseRegion}}, $item); |
| 620 | } |
| 621 | } |
| 622 | } |
| 623 | } |
| 624 | sub SetHints_Symbols_Nearby_InputSections #called by GenSECTIONS() |
| 625 | { |
| 626 | my ($RegionList_ref, $Index_ref) = @_; |
| 627 | my %Hints; |
| 628 | # Step1. insert 4 symbols and collect BaseRegion Info. into %Hints |
| 629 | &InsertBasicHintSymbols($RegionList_ref, $Index_ref, \%Hints); |
| 630 | # Step2. Remove Symbols |
| 631 | my $SymbolIndex = $Index_ref->{Symbols}; |
| 632 | my $AttributeIndex = $Index_ref->{Attribute}; |
| 633 | my $NameIndex = $Index_ref->{Name}; |
| 634 | foreach my $items (values %Hints) |
| 635 | { |
| 636 | next if(!@$items); |
| 637 | for(my $i=0; $i< scalar(@$items); $i++) |
| 638 | { |
| 639 | my $CurrentItem = $items->[$i]->[$SymbolIndex]; |
| 640 | my $CurrentAttr = $items->[$i]->[$AttributeIndex]; |
| 641 | if($i==0) |
| 642 | { |
| 643 | my $NextAttr = $items->[$i+1]->[$AttributeIndex]; |
| 644 | delete $CurrentItem->{ZILimit} if($CurrentAttr ne "ZI"); |
| 645 | delete $CurrentItem->{ZIBase} if($CurrentAttr ne "ZI"); |
| 646 | delete $CurrentItem->{Limit} if($NextAttr ne "ZI"); |
| 647 | } |
| 648 | elsif($i==(scalar(@$items)-1)) |
| 649 | { |
| 650 | my $PrevAttr = $items->[$i-1]->[$AttributeIndex]; |
| 651 | delete $CurrentItem->{Base}; |
| 652 | delete $CurrentItem->{Limit} if($CurrentAttr eq "ZI"); |
| 653 | delete $CurrentItem->{ZIBase} if($PrevAttr eq "ZI"); |
| 654 | } |
| 655 | else |
| 656 | { |
| 657 | my $NextAttr = $items->[$i+1]->[$AttributeIndex]; |
| 658 | my $PrevAttr = $items->[$i-1]->[$AttributeIndex]; |
| 659 | delete $CurrentItem->{Base}; |
| 660 | delete $CurrentItem->{ZILimit}; |
| 661 | delete $CurrentItem->{Limit} if(($CurrentAttr eq "ZI" and $PrevAttr ne "ZI") |
| 662 | or ($CurrentAttr ne "ZI" and $NextAttr ne "ZI")); |
| 663 | delete $CurrentItem->{ZIBase} if(($CurrentAttr eq "ZI" and $PrevAttr eq "ZI") |
| 664 | or ($CurrentAttr ne "ZI")); |
| 665 | } |
| 666 | } |
| 667 | } |
| 668 | } |
| 669 | #**************************************************************************** |
| 670 | sub GenSymbol_Before_InputSections # Gen_TEMPLATE_SECTION |
| 671 | { |
| 672 | my ($Info_ref, $Index_ref) = @_; |
| 673 | my $template; |
| 674 | $template = &Gen_TEMPLATE_BaseSymbol($Info_ref, $Index_ref); |
| 675 | if($Info_ref->[$Index_ref->{Attribute}] eq "ZI") |
| 676 | { |
| 677 | my $LimitSymbol = &Gen_TEMPLATE_LimitSymbol($Info_ref, $Index_ref); |
| 678 | my $ZIBaseSymbol = &Gen_TEMPLATE_ZIBaseSymbol($Info_ref, $Index_ref); |
| 679 | my $break = "\n" if($template ne "" and $LimitSymbol ne ""); |
| 680 | $template .= $break . $LimitSymbol; |
| 681 | $break = "\n"; |
| 682 | $break = "" if($LimitSymbol eq "" or $ZIBaseSymbol eq ""); |
| 683 | $template .= $break . $ZIBaseSymbol; |
| 684 | } |
| 685 | return $template; |
| 686 | } |
| 687 | sub GenSymbol_After_InputSections # Gen_TEMPLATE_SECTION |
| 688 | { |
| 689 | my ($Info_ref, $Index_ref) = @_; |
| 690 | my $template; |
| 691 | my $break = ""; |
| 692 | if($Info_ref->[$Index_ref->{Attribute}] ne "ZI") |
| 693 | { |
| 694 | $template = &Gen_TEMPLATE_LimitSymbol($Info_ref, $Index_ref); |
| 695 | my $ZIBaseSymbol = &Gen_TEMPLATE_ZIBaseSymbol($Info_ref, $Index_ref); |
| 696 | $break= "\n" if($template ne "" and $ZIBaseSymbol ne ""); |
| 697 | $template .= $break. $ZIBaseSymbol; |
| 698 | $break = ""; |
| 699 | } |
| 700 | my $ZILimitSymbol = &Gen_TEMPLATE_ZILimitSymbol($Info_ref, $Index_ref); |
| 701 | $break= "\n" if($template ne "" and $ZILimitSymbol ne ""); |
| 702 | $template .= $break . $ZILimitSymbol; |
| 703 | return $template; |
| 704 | } |
| 705 | #**************************************************************************** |
| 706 | sub GenRORWInputSections # Gen_TEMPLATE_SECTION_IN_OVERLAY |
| 707 | { |
| 708 | my ($Info_ref, $Index_ref) = @_; |
| 709 | return &GenInputSectionsByAttribute($Info_ref, $Index_ref, sub{ my ($file) = @_; |
| 710 | return $file if($file !~/ZI/);} ); |
| 711 | } |
| 712 | sub GenZIInputSections # Gen_TEMPLATE_SECTION_IN_OVERLAY |
| 713 | { |
| 714 | my ($Info_ref, $Index_ref) = @_; |
| 715 | return &GenInputSectionsByAttribute($Info_ref, $Index_ref, sub{ my ($file) = @_; |
| 716 | return $file if($file =~/ZI/);} ); |
| 717 | } |
| 718 | sub GenInputSectionsByAttribute # used by GenRORWInputSections and GenZIInputSections |
| 719 | { |
| 720 | my ($Info_ref, $Index_ref, $expr) = @_; |
| 721 | my $RegionName = $Info_ref->[$Index_ref->{Name}]; |
| 722 | my $InputSectionFolder = &GetPath($RegionName, InputSections); |
| 723 | opendir( my $DIR, $InputSectionFolder) || &ldsFrame_die("Can't open $InputSectionFolder!", __FILE__, __LINE__); |
| 724 | my @FileList = grep { $expr->($_)=~/\.txt$|.csv$/ && -f "$InputSectionFolder$_" } readdir( $DIR ); |
| 725 | closedir $DIR; |
| 726 | my $InputSections = undef; |
| 727 | if(scalar(@FileList)>0) |
| 728 | { |
| 729 | my ($strCommonPath, $strDefaultChipPath, $strChipDependentPath, $strHeadPath) = (undef, undef, undef, undef); |
| 730 | foreach my $file (@FileList) |
| 731 | { |
| 732 | my $strChip = &{$Func{GetChip}}(); |
| 733 | my $filename = $file; |
| 734 | $filename =~ s/\.\S+$//; |
| 735 | my ($Common, $ChipDefault, $Head) = (COMMON_InputSection, ChipDependent_Default_InputSection, HEAD_InputSection); |
| 736 | $strChipDependentPath = $InputSectionFolder.$file if($filename =~/($strChip)$/); |
| 737 | $strCommonPath = $InputSectionFolder.$file if($filename =~/$Common/); |
| 738 | $strDefaultChipPath = $InputSectionFolder.$file if($filename =~/$ChipDefault/); |
| 739 | $strHeadPath = $InputSectionFolder.$file if($filename =~/$Head/); |
| 740 | } |
| 741 | if(-e $strHeadPath) |
| 742 | { |
| 743 | $InputSections = &CommonUtil::GetFileContent($strHeadPath)."\n"; |
| 744 | } |
| 745 | if(-e $strChipDependentPath) |
| 746 | { |
| 747 | $InputSections .= &CommonUtil::GetFileContent($strChipDependentPath)."\n"; |
| 748 | } |
| 749 | elsif(-e $strDefaultChipPath) |
| 750 | { |
| 751 | $InputSections .= &CommonUtil::GetFileContent($strDefaultChipPath)."\n"; |
| 752 | } |
| 753 | $InputSections .= &CommonUtil::GetFileContent($strCommonPath); |
| 754 | } |
| 755 | return $InputSections; |
| 756 | } |
| 757 | #**************************************************************************** |
| 758 | sub Gen_TEMPLATE_SECTION # called by GenSECTIONS() and Gen_TEMPLATE_OVERLAY() |
| 759 | { |
| 760 | my $template = <<"__TEMPLATE"; |
| 761 | [ldsGen_RegionName] [ldsGen_VMA] [ldsGen_RegionAttr] : [ldsGen_LMA] [ldsGen_ALIGN] |
| 762 | { |
| 763 | [ldsGen_Symbol_Before_InputSections] |
| 764 | [ldsGen_InputSections] |
| 765 | . = ALIGN(4); |
| 766 | [ldsGen_Symbol_After_InputSections] |
| 767 | } [ldsGen_ExecutionRegion] [ldsGen_LoadRegion] |
| 768 | __TEMPLATE |
| 769 | } |
| 770 | sub Gen_TEMPLATE_SECTION_IN_OVERLAY # called by Gen_TEMPLATE_OVERLAY() |
| 771 | { |
| 772 | my $template = <<"__TEMPLATE"; |
| 773 | [ldsGen_RegionName] |
| 774 | { |
| 775 | Image\$\$[ldsGen_RegionName]\$\$Base = ADDR([ldsGen_RegionName]); |
| 776 | [ldsGen_RORWInputSections] |
| 777 | . = ALIGN(4); |
| 778 | Image\$\$[ldsGen_RegionName]\$\$Limit = .; |
| 779 | Image\$\$[ldsGen_RegionName]\$\$ZI\$\$Base = .; |
| 780 | [ldsGen_ZIInputSections] |
| 781 | . = ALIGN(4); |
| 782 | Image\$\$[ldsGen_RegionName]\$\$ZI\$\$Limit = .; |
| 783 | } |
| 784 | __TEMPLATE |
| 785 | } |
| 786 | sub Gen_TEMPLATE_OVERLAY # called by FillOVERLAYSectionFrame() |
| 787 | { |
| 788 | my ($Infos_ref, $Index_ref) = @_; |
| 789 | my $LOADADDR_template; |
| 790 | map { $LOADADDR_template .= &Gen_TEMPLATE_LOADADDR($_, $Index_ref)} @$Infos_ref; |
| 791 | my $strOVERLAY_SECTIONS; |
| 792 | map {$strOVERLAY_SECTIONS .= &ProcessSection(&Gen_TEMPLATE_SECTION_IN_OVERLAY(), $_, $Index_ref)}(@$Infos_ref); |
| 793 | my $LengthSymbol_template; |
| 794 | map { $LengthSymbol_template .= &Gen_TEMPLATE_LengthSymbol($_, $Index_ref)} @$Infos_ref; |
| 795 | |
| 796 | my $template = <<"__TEMPLATE"; |
| 797 | OVERLAY [ldsGen_VMA] [ldsGen_RegionAttr] : [ldsGen_LMA] [ldsGen_ALIGN] |
| 798 | { |
| 799 | $strOVERLAY_SECTIONS |
| 800 | } [ldsGen_ExecutionRegion] [ldsGen_LoadRegion] |
| 801 | __TEMPLATE |
| 802 | return ($template, $LOADADDR_template, $LengthSymbol_template); |
| 803 | } |
| 804 | sub Gen_TEMPLATE_LOADADDR # Called by GenSECTIONS and Gen_TEMPLATE_OVERLAY() |
| 805 | { |
| 806 | my ($Info_ref, $Index_ref) = @_; |
| 807 | my $strBaseRegion = $Info_ref->[$Index_ref->{BaseRegion}]; |
| 808 | my $strOrgRegion = $Info_ref->[$Index_ref->{Name}]; |
| 809 | my $strType = $Info_ref->[$Index_ref->{Type}]; |
| 810 | return "" if($strBaseRegion ne "" and $strBaseRegion ne $strOrgRegion and $strType !~ /^OVERLAY$/i); |
| 811 | |
| 812 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 813 | my $template = <<"__TEMPLATE"; |
| 814 | Load\$\$$strRegionName\$\$Base = LOADADDR($strRegionName); |
| 815 | __TEMPLATE |
| 816 | return $template; |
| 817 | } |
| 818 | sub Gen_TEMPLATE_LengthSymbol # Called by GenSECTIONS() and Gen_TEMPLATE_OVERLAY() |
| 819 | { |
| 820 | my ($Info_ref, $Index_ref) = @_; |
| 821 | my $strBaseRegion = $Info_ref->[$Index_ref->{BaseRegion}]; |
| 822 | my $strOrgRegion = $Info_ref->[$Index_ref->{Name}]; |
| 823 | my $strType = $Info_ref->[$Index_ref->{Type}]; |
| 824 | return "" if($strBaseRegion ne "" and $strBaseRegion ne $strOrgRegion and $strType !~ /^OVERLAY$/i); |
| 825 | |
| 826 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 827 | my $template = <<"__TEMPLATE"; |
| 828 | Image\$\$$strRegionName\$\$Length = Image\$\$$strRegionName\$\$Limit - Image\$\$$strRegionName\$\$Base; |
| 829 | Image\$\$$strRegionName\$\$ZI\$\$Length = Image\$\$$strRegionName\$\$ZI\$\$Limit - Image\$\$$strRegionName\$\$ZI\$\$Base; |
| 830 | __TEMPLATE |
| 831 | return $template; |
| 832 | } |
| 833 | sub Gen_TEMPLATE_ASSERT |
| 834 | { |
| 835 | my ($Info_ref, $Index_ref) = @_; |
| 836 | my $strBaseRegion = $Info_ref->[$Index_ref->{BaseRegion}]; |
| 837 | my $strOrgRegion = $Info_ref->[$Index_ref->{Name}]; |
| 838 | my $strMaxSize = $Info_ref->[$Index_ref->{MaxSize}]; |
| 839 | return "" if(($strBaseRegion ne "" and $strBaseRegion ne $strOrgRegion) or $strMaxSize eq ""); |
| 840 | |
| 841 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 842 | my $ERRTitle = genERR::SYSERR_1_2; |
| 843 | my $template = <<"__TEMPLATE"; |
| 844 | ASSERT( (Image\$\$$strRegionName\$\$Length + Image\$\$$strRegionName\$\$ZI\$\$Length ) <= $strMaxSize , \"$ERRTitle\Sizes of $strRegionName exceed $strMaxSize\") |
| 845 | __TEMPLATE |
| 846 | return $template; |
| 847 | } |
| 848 | sub Gen_TEMPLATE_BaseSymbol # Called by GenSymbol_Before_InputSections() |
| 849 | { |
| 850 | my ($Info_ref, $Index_ref) = @_; |
| 851 | return "" if(!exists $Info_ref->[$Index_ref->{Symbols}]->{Base}); |
| 852 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 853 | return ' ' x 8 . "Image\$\$$strRegionName\$\$Base = . ;"; |
| 854 | } |
| 855 | sub Gen_TEMPLATE_LimitSymbol # Called by GenSymbol_(Before/After)_InputSections() |
| 856 | { |
| 857 | my ($Info_ref, $Index_ref) = @_; |
| 858 | return "" if(!exists $Info_ref->[$Index_ref->{Symbols}]->{Limit}); |
| 859 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 860 | return ' ' x 8 . "Image\$\$$strRegionName\$\$Limit = . ;"; |
| 861 | } |
| 862 | sub Gen_TEMPLATE_ZIBaseSymbol # Called by GenSymbol_(Before/After)_InputSections() |
| 863 | { |
| 864 | my ($Info_ref, $Index_ref) = @_; |
| 865 | return "" if(!exists $Info_ref->[$Index_ref->{Symbols}]->{ZIBase}); |
| 866 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 867 | return ' ' x 8 . "Image\$\$$strRegionName\$\$ZI\$\$Base = . ;"; |
| 868 | } |
| 869 | sub Gen_TEMPLATE_ZILimitSymbol # Called by GenSymbol_After_InputSections() |
| 870 | { |
| 871 | my ($Info_ref, $Index_ref) = @_; |
| 872 | return "" if(!exists $Info_ref->[$Index_ref->{Symbols}]->{ZILimit}); |
| 873 | my $strRegionName = &GenBaseRegionName($Info_ref, $Index_ref); |
| 874 | return ' ' x 8 . "Image\$\$$strRegionName\$\$ZI\$\$Limit = . ;"; |
| 875 | } |
| 876 | |
| 877 | #**************************************************************************** |
| 878 | # subroutine: ldsFrame_die |
| 879 | # sample code: (message, __FILE__, __LINE__) |
| 880 | # input: $error_msg, $file, $line_no |
| 881 | #**************************************************************************** |
| 882 | sub ldsFrame_die |
| 883 | { |
| 884 | my ($error_msg, $file, $line_no) = (@_); |
| 885 | &CommonUtil::error_handler($error_msg, $file, $line_no, 'ldsFrame'); |
| 886 | } |