blob: 9a81d58b5c659b65d1b48769f7811493f21eea03 [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2006
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#*****************************************************************************
36#*
37#* Filename:
38#* ---------
39#* 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#****************************************************************************
78my $MY_VERNO = " v0.02";
79 # v0.01 , initial draft
80
81
82#****************************************************************************
83# File Names
84#****************************************************************************
85my $DBGINFO = $ARGV[0];
86my $ADDRESS = $ARGV[1];
87my $AddressInDecimal;
88
89my $DebugPrint = 0; # 1 for debug; 0 for non-debug
90
91printf STDERR "version: $MY_VERNO\n" if($DebugPrint == 1);
92#****************************************************************************
93# 0 >>> Print out input parameters for checking
94#****************************************************************************
95if ($DebugPrint == 1) {
96 printf "DBGINFO: $DBGINFO\n";
97 printf "ADDRESS: $ADDRESS\n";
98 printf "\n";
99}
100
101#****************************************************************************
102# 1 >>> Check Input ADDRESS
103#****************************************************************************
104printf "Starting stage1... (Check input ADDRESS)\n" if($DebugPrint == 1);
105if ($ADDRESS =~ m/0x[a-fA-F0-9]+/) {
106 $AddressInDecimal = hex($ADDRESS);
107 printf "input ADDRESS = 0x%x\n", $AddressInDecimal if($DebugPrint == 1);
108}
109else {
110 &error_handler("Illegal ADDRESS: $ADDRESS! please input address beginning with format \"0x?\"", __FILE__, __LINE__);
111}
112print "\n" if($DebugPrint == 1);
113
114my $func = convert2FuncName($AddressInDecimal);
115my $file = convert2FileName($AddressInDecimal);
116
117if ($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#****************************************************************************
126exit 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#****************************************************************************
180sub 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#****************************************************************************
253sub 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#****************************************************************************
345sub 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#****************************************************************************
357sub 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}