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) 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 | #* exLogParser.pl |
| 40 | #* |
| 41 | #* Project: |
| 42 | #* -------- |
| 43 | #* |
| 44 | #* |
| 45 | #* Description: |
| 46 | #* ------------ |
| 47 | #* This script parses raw data of the exception log |
| 48 | #* |
| 49 | #* Author: |
| 50 | #* ------- |
| 51 | #* xxx (mtkxxxxx) |
| 52 | #* |
| 53 | #*============================================================================ |
| 54 | #* HISTORY |
| 55 | #* Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 56 | #*------------------------------------------------------------------------------ |
| 57 | #* $Revision$ |
| 58 | #* $Modtime$ |
| 59 | #* $Log$ |
| 60 | #* |
| 61 | #* 04 28 2014 woody.kuo |
| 62 | #* [MOLY00054950] [System Service][MOLY Kernel Internal Request] To prevent nested exception during KAL_ERROR_BUFFMNGR_ISVALID_FAILED |
| 63 | #* change file to binmode due to 0xa 0xd |
| 64 | #* |
| 65 | #*------------------------------------------------------------------------------ |
| 66 | #* Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| 67 | #*============================================================================ |
| 68 | #****************************************************************************/ |
| 69 | |
| 70 | #**************************************************************************** |
| 71 | # Included Modules |
| 72 | #**************************************************************************** |
| 73 | |
| 74 | |
| 75 | #**************************************************************************** |
| 76 | # Constants |
| 77 | #**************************************************************************** |
| 78 | my $MY_VERNO = " v0.02"; |
| 79 | # v0.01 , initial draft |
| 80 | |
| 81 | |
| 82 | #**************************************************************************** |
| 83 | # File Names |
| 84 | #**************************************************************************** |
| 85 | my $DBGINFO = $ARGV[0]; |
| 86 | my $ADDRESS = $ARGV[1]; |
| 87 | my $AddressInDecimal; |
| 88 | |
| 89 | my $DebugPrint = 0; # 1 for debug; 0 for non-debug |
| 90 | |
| 91 | printf STDERR "version: $MY_VERNO\n" if($DebugPrint == 1); |
| 92 | #**************************************************************************** |
| 93 | # 0 >>> Print out input parameters for checking |
| 94 | #**************************************************************************** |
| 95 | if ($DebugPrint == 1) { |
| 96 | printf "DBGINFO: $DBGINFO\n"; |
| 97 | printf "ADDRESS: $ADDRESS\n"; |
| 98 | printf "\n"; |
| 99 | } |
| 100 | |
| 101 | #**************************************************************************** |
| 102 | # 1 >>> Check Input ADDRESS |
| 103 | #**************************************************************************** |
| 104 | printf "Starting stage1... (Check input ADDRESS)\n" if($DebugPrint == 1); |
| 105 | if ($ADDRESS =~ m/0x[a-fA-F0-9]+/) { |
| 106 | $AddressInDecimal = hex($ADDRESS); |
| 107 | printf "input ADDRESS = 0x%x\n", $AddressInDecimal if($DebugPrint == 1); |
| 108 | } |
| 109 | else { |
| 110 | &error_handler("Illegal ADDRESS: $ADDRESS! please input address beginning with format \"0x?\"", __FILE__, __LINE__); |
| 111 | } |
| 112 | print "\n" if($DebugPrint == 1); |
| 113 | |
| 114 | my $func = convert2FuncName($AddressInDecimal); |
| 115 | my $file = convert2FileName($AddressInDecimal); |
| 116 | |
| 117 | if ($func eq "\0"){ |
| 118 | printf "error: input address $ADDRESS is not a function address!!!"; |
| 119 | } else { |
| 120 | printf "file: $file, func: $func \n"; |
| 121 | } |
| 122 | |
| 123 | #**************************************************************************** |
| 124 | # oo >>> Finished |
| 125 | #**************************************************************************** |
| 126 | exit 0; |
| 127 | |
| 128 | #------------------------------------------------------------------------------------------------------------- |
| 129 | #| DbgInfo output file format | |
| 130 | #|-----------------------------------------------------------------------------------------------------------| |
| 131 | #| Item | Content | Size | |
| 132 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 133 | #| DEBUGINFO_DB_FILE_PREFIX | CATI | 4 | |
| 134 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 135 | #| DEBUGINFO_DB_VER_MAIN | 1 | 4 | |
| 136 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 137 | #| DEBUGINFO_DB_VER_SUB | 0 | 4 | |
| 138 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 139 | #| Project Name | (string)argv[3] | length+1 | |
| 140 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 141 | #| HW Version | (string)argv[4] | length+1 | |
| 142 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 143 | #| SW Version | (string)argv[5] | length+1 | |
| 144 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 145 | #| Build Time | (string)argv[6] | length+1 | |
| 146 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 147 | #| Sym Table Offset | nSymTableOffset | 4 | |
| 148 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 149 | #| File Table Offset | nFileTableOffset | 4 | |
| 150 | #|------------------------------------------------------|-----------------------------------------|----------| |
| 151 | #| Symbol Table | Function name | m_mFunctions.m_Name | length+1 | |
| 152 | #| |---------------------------------------|-----------------------------------------|----------| |
| 153 | #| | Start Address | m_mFunctions.m_Addr | 4 | |
| 154 | #| |---------------------------------------|-----------------------------------------|----------| |
| 155 | #| | End Address | m_mFunctions.m_Addr+m_mFunctions.m_Size | 4 | |
| 156 | #| |--------------------------------------------------------------------------------------------| |
| 157 | #| | Repeat above 3 items�K | |
| 158 | #| |--------------------------------------------------------------------------------------------| |
| 159 | #| | NULL Function Name | "" | 1 | |
| 160 | #|--------------|---------------------------------------|-----------------------------------------|----------| |
| 161 | #| File Table | m_mRangesByFile | File Path | key | length+1 | |
| 162 | #| |-----------------------|---------------|-----------------------------------------|----------| |
| 163 | #| | m_mRangesByFile | Count | value.size | 4 | |
| 164 | #| |-----------------------|---------------|-----------------------------------------|----------| |
| 165 | #| | m_mRangesByFile.value | Start Address | m_mRangesByFile.value.key | 4 | |
| 166 | #| | |---------------|-----------------------------------------|----------| |
| 167 | #| | | End Address | m_mRangesByFile.value.value | 4 | |
| 168 | #| | |--------------------------------------------------------------------| |
| 169 | #| | | Repeat above 2 items�K | |
| 170 | #| |--------------------------------------------------------------------------------------------| |
| 171 | #| | Repeat above 3 items�K | |
| 172 | #| |--------------------------------------------------------------------------------------------| |
| 173 | #| | NULL Function Name | "" | 1 | |
| 174 | #------------------------------------------------------------------------------------------------------------- |
| 175 | |
| 176 | #**************************************************************************** |
| 177 | # subroutine: convert2FuncName |
| 178 | # input: addr |
| 179 | #**************************************************************************** |
| 180 | sub convert2FuncName |
| 181 | { |
| 182 | my ($addr) = @_; |
| 183 | my ($data, @byte, $n, $i); |
| 184 | my ($str, $start_addr, $end_addr); |
| 185 | |
| 186 | # open DbgInfo |
| 187 | &error_handler("$DBGINFO: NOT exist!", __FILE__, __LINE__) if (!-e $DBGINFO); |
| 188 | open (FILE_HANDLE, "<$DBGINFO") or &error_handler("$DBGINFO: file error!", __FILE__, __LINE__); |
| 189 | binmode FILE_HANDLE; |
| 190 | |
| 191 | # skip three words & four strings |
| 192 | foreach (1..3) { |
| 193 | read FILE_HANDLE, $data, 4; |
| 194 | } |
| 195 | foreach (1..4) { |
| 196 | while (($n = read FILE_HANDLE, $data, 1) != 0) { |
| 197 | last if (ord($data) == 0); |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | # skip two words (nSymTableOffset & nFileTableOffset) |
| 202 | foreach (1..2) { |
| 203 | read FILE_HANDLE, $data, 4; |
| 204 | } |
| 205 | |
| 206 | # find the corresponding function name |
| 207 | while (1) { |
| 208 | # read a string |
| 209 | $str = ""; |
| 210 | while (($n = read FILE_HANDLE, $data, 1) != 0) { |
| 211 | $str .= $data; |
| 212 | last if (ord($data) == 0); |
| 213 | } |
| 214 | |
| 215 | # check if NULL string |
| 216 | last if ($str eq "\0"); |
| 217 | printf "function name = \"%40s\"", $str if($DebugPrint == 1); |
| 218 | |
| 219 | # read start address |
| 220 | for ($i = 0; $i < 4; $i++) { |
| 221 | read FILE_HANDLE, $byte[$i], 1; |
| 222 | } |
| 223 | $start_addr = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 224 | printf ", start_addr = 0x%08x", $start_addr if($DebugPrint == 1); |
| 225 | |
| 226 | # read end address |
| 227 | for ($i = 0; $i < 4; $i++) { |
| 228 | read FILE_HANDLE, $byte[$i], 1; |
| 229 | } |
| 230 | $end_addr = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 231 | printf ", end_addr = 0x%08x\n", $end_addr if($DebugPrint == 1); |
| 232 | |
| 233 | #check if the one we want |
| 234 | last if ($start_addr <= ($addr + 1) && ($addr + 1) < $end_addr); |
| 235 | } |
| 236 | |
| 237 | # close DbgInfo |
| 238 | close(FILE_HANDLE); |
| 239 | |
| 240 | if ($DebugPrint == 1) { |
| 241 | print sprintf("start_addr: 0x%08X, end_addr: 0x%08X\n", $start_addr, $end_addr); |
| 242 | print sprintf("addr: 0x%08X\n", $addr); |
| 243 | print "func_name returned: $str\n"; |
| 244 | } |
| 245 | |
| 246 | return $str; |
| 247 | } |
| 248 | |
| 249 | #**************************************************************************** |
| 250 | # subroutine: convert2FileName |
| 251 | # input: addr |
| 252 | #**************************************************************************** |
| 253 | sub convert2FileName |
| 254 | { |
| 255 | my ($addr) = @_; |
| 256 | my ($data, @byte, $offset, $n, $i, $j); |
| 257 | my ($nFileTableOffset, $str, $count, $start_addr, $end_addr); |
| 258 | |
| 259 | # open DbgInfo |
| 260 | &error_handler("$DBGINFO: NOT exist!", __FILE__, __LINE__) if (!-e $DBGINFO); |
| 261 | open (FILE_HANDLE, "<$DBGINFO") or &error_handler("$DBGINFO: file error!", __FILE__, __LINE__); |
| 262 | |
| 263 | # skip three words & four strings |
| 264 | foreach (1..3) { |
| 265 | read FILE_HANDLE, $data, 4; |
| 266 | } |
| 267 | $offset = 12; |
| 268 | foreach (1..4) { |
| 269 | while (($n = read FILE_HANDLE, $data, 1) != 0) { |
| 270 | $offset++; |
| 271 | last if (ord($data) == 0); |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | # read nFileTableOffset |
| 276 | read FILE_HANDLE, $data, 4; |
| 277 | for ($i = 0; $i < 4; $i++) { |
| 278 | read FILE_HANDLE, $byte[$i], 1; |
| 279 | } |
| 280 | $nFileTableOffset = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 281 | $offset += 8; |
| 282 | |
| 283 | # go to the offset |
| 284 | while($offset < $nFileTableOffset) { |
| 285 | read FILE_HANDLE, $data, 1; |
| 286 | $offset++; |
| 287 | } |
| 288 | |
| 289 | # find the corresponding file name |
| 290 | while (1) { |
| 291 | # read a string |
| 292 | $str = ""; |
| 293 | while (($n = read FILE_HANDLE, $data, 1) != 0) { |
| 294 | $str .= $data; |
| 295 | last if (ord($data) == 0); |
| 296 | } |
| 297 | |
| 298 | # check if NULL string |
| 299 | last if ($str eq "\0"); |
| 300 | |
| 301 | #read count |
| 302 | for ($i = 0; $i < 4; $i++) { |
| 303 | read FILE_HANDLE, $byte[$i], 1; |
| 304 | } |
| 305 | $count = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 306 | |
| 307 | for ($i = 0; $i < $count; $i++) { |
| 308 | # read start address |
| 309 | for ($j = 0; $j < 4; $j++) { |
| 310 | read FILE_HANDLE, $byte[$j], 1; |
| 311 | } |
| 312 | $start_addr = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 313 | |
| 314 | # read end address |
| 315 | for ($j = 0; $j < 4; $j++) { |
| 316 | read FILE_HANDLE, $byte[$j], 1; |
| 317 | } |
| 318 | $end_addr = get_int32(ord($byte[0]), ord($byte[1]), ord($byte[2]), ord($byte[3])); |
| 319 | |
| 320 | # check if the one we want |
| 321 | last if ($start_addr <= ($addr + 1) && ($addr + 1) < $end_addr); |
| 322 | } |
| 323 | last if ($i < $count); |
| 324 | } |
| 325 | |
| 326 | # close DbgInfo |
| 327 | close(FILE_HANDLE); |
| 328 | |
| 329 | if ($DebugPrint == 1) { |
| 330 | print sprintf("start_addr: 0x%08X, end_addr: 0x%08X\n", $start_addr, $end_addr); |
| 331 | print sprintf("addr: 0x%08X\n", $addr); |
| 332 | print "file_name returned: $str\n"; |
| 333 | } |
| 334 | |
| 335 | return $str; |
| 336 | } |
| 337 | |
| 338 | #**************************************************************************** |
| 339 | # subroutine: get_int32 |
| 340 | # input: $byte0 |
| 341 | # $byte1 |
| 342 | # $byte2 |
| 343 | # $byte3 |
| 344 | #**************************************************************************** |
| 345 | sub get_int32 |
| 346 | { |
| 347 | my ($byte0, $byte1, $byte2, $byte3) = @_; |
| 348 | return ($byte3 << 24) | ($byte2 << 16) | ($byte1 << 8) | $byte0; |
| 349 | } |
| 350 | |
| 351 | #**************************************************************************** |
| 352 | # subroutine: error_handler |
| 353 | # input: $error_msg: error message |
| 354 | # $file: filename |
| 355 | # $line_no: line number |
| 356 | #**************************************************************************** |
| 357 | sub error_handler |
| 358 | { |
| 359 | my ($error_msg, $file, $line_no) = @_; |
| 360 | |
| 361 | my $final_error_msg = "PARSER ERROR: $error_msg at $file line $line_no\n"; |
| 362 | die $final_error_msg; |
| 363 | } |