OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_dwarf_line.c
1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
2
3                          D r . D e a m o n  6 4
4                         for INTEL64(R), AMD64(R)
5         
6    Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11  1. Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in the
15     documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
30
31 /* File Info -----------------------------------------------------------
32 File: drd64_.c
33 Function: 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #define DRD64_SRC_LIBGOBLIN_DWARF_ABBREV
38 #include"drd64_libgoblin.h"
39
40
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
43 Byte *
44         LibGoblin_DwarfLine_Read_LineHeader_FileNameData(
45                 LibGoblin_Dwarf_LineSection *pt_line,
46                 Byte    *pb_data,
47                 QWord   *pqw_remain,
48                 int             i_files )
49 {
50         QWord   qw_qword;
51         Byte    b_byte;
52
53         /* Read FileName */
54         b_byte  = *pb_data;
55         pt_line->t_filename[ i_files ].pstr_srcfilename
56                                                                         = (char *)(pb_data - 1);
57         while( ( 0 < *pqw_remain) && ('\0' != b_byte) ) {
58                 (*pqw_remain)--;
59                 b_byte  = *pb_data++;
60         }
61
62         /* Read Directory Index */
63         pb_data = DWARF_Common_DecodeULEB128(
64                                         &qw_qword, pb_data, pqw_remain );
65         if( NULL == pb_data )   { return NULL; }
66         pt_line->t_filename[ i_files ].dw_dirindex      = (DWord)qw_qword;
67
68         /* Read File-Date */
69         pb_data = DWARF_Common_DecodeULEB128(
70                                         &qw_qword, pb_data, pqw_remain );
71         if( NULL == pb_data )   { return NULL; }
72         pt_line->t_filename[ i_files ].qw_date  = qw_qword;
73
74         /* Read File-Size */
75         pb_data = DWARF_Common_DecodeULEB128(
76                                         &qw_qword, pb_data, pqw_remain );
77         if( NULL == pb_data )   { return NULL; }
78         pt_line->t_filename[ i_files ].qw_filesize      = qw_qword;
79
80         return pb_data;
81 }
82
83
84 /*----------------------------------------------------------------------
85 ----------------------------------------------------------------------*/
86 Byte *
87         LibGoblin_DwarfLine_Read_LineHeader_FileNames(
88                 LibGoblin_Dwarf_LineSection *pt_line,
89                 Byte    *pb_data,
90                 QWord   *pqw_remain )
91 {
92         int             i_files;
93         //QWord qw_qword;
94         Byte    b_byte;
95
96         i_files = 0;
97
98         if( 1 > (*pqw_remain)-- )       { return NULL; }
99         b_byte  = *pb_data++;
100
101         while( '\0' != b_byte)  {
102                 pb_data = LibGoblin_DwarfLine_Read_LineHeader_FileNameData(
103                                                 pt_line, pb_data, pqw_remain, i_files );
104
105                 /* Read FileName */
106 /*              pt_line->t_filename[ i_files ].pstr_srcfilename
107                                                                         = (char *)(pb_data - 1);
108                 while( ( 0 < *pqw_remain) && ('\0' != b_byte) ) {
109                         (*pqw_remain)--;
110                         b_byte  = *pb_data++;
111                 }
112 */
113                 /* Read Directory Index */
114                 /*pb_data       = DWARF_Common_DecodeULEB128(
115                                                 &qw_qword, pb_data, pqw_remain );
116                 if( NULL == pb_data )   { return NULL; }
117                 pt_line->t_filename[ i_files ].dw_dirindex      = (DWord)qw_qword;
118 */
119                 /* Read File-Date */
120                 /*pb_data       = DWARF_Common_DecodeULEB128(
121                                                 &qw_qword, pb_data, pqw_remain );
122                 if( NULL == pb_data )   { return NULL; }
123                 pt_line->t_filename[ i_files ].qw_date  = qw_qword;
124 */
125                 /* Read File-Size */
126                 /*pb_data       = DWARF_Common_DecodeULEB128(
127                                                 &qw_qword, pb_data, pqw_remain );
128                 if( NULL == pb_data )   { return NULL; }
129                 pt_line->t_filename[ i_files ].qw_filesize      = qw_qword;
130 */
131                 if( 1 > (*pqw_remain)-- )       { return NULL; }
132                 b_byte  = *pb_data++;
133         
134                 i_files++;
135         }
136
137         pt_line->i_num_filename = i_files;
138
139         return pb_data;
140 }
141
142
143 /*----------------------------------------------------------------------
144 ----------------------------------------------------------------------*/
145 Byte *
146         LibGoblin_DwarfLine_Read_LineHeader_IncludePath(
147                 LibGoblin_Dwarf_LineSection *pt_line,
148                 Byte    *pb_data,
149                 QWord   *qw_remain )
150 {
151         int             i_cnt;
152         Byte    b_byte;
153
154         i_cnt   = 0;
155
156         if( 1 > (*qw_remain)-- )        { return NULL; }
157         pt_line->pstr_includepath       = (char *)pb_data;
158         b_byte  = *pb_data++;
159
160         while( '\0' != b_byte ) { 
161                 if( 1 > (*qw_remain)-- )        { return NULL; }
162                 b_byte  = *pb_data++;
163
164                 if( '\0' == b_byte )    {
165                         if( 1 > (*qw_remain)-- )        { return NULL; }
166                         b_byte  = *pb_data++;
167                         i_cnt++;
168                 }
169         }
170         pt_line->i_num_includepath      = i_cnt;
171
172         return pb_data;
173 }
174
175
176 /*----------------------------------------------------------------------
177 ----------------------------------------------------------------------*/
178 Byte *
179         LibGoblin_DwarfLine_Read_LineHeader(
180                 LibGoblin_Dwarf_LineSection *pt_line,
181                 Byte    *pb_data,
182                 QWord   *pqw_size_linesec )
183 {
184         int             i_bitflag;
185         int             i_readbytes;
186         int             i_cnt;
187         Byte    b_byte;
188         DWord   dw_dword;
189         QWord   qw_qword;
190         QWord   qw_remain;
191
192         assert( NULL != pt_line );
193         assert( NULL != pb_data );
194
195
196         i_readbytes     = 0;
197         i_bitflag       = 32;
198         pt_line->b_bits = 32;
199         qw_remain       = *pqw_size_linesec;
200
201         puts("now");
202         /* Read unit_length (4Byte(32bit) or 8Byte(64bit)) */
203         pb_data = DWARF_Common_Read_DWord(
204                                                 &dw_dword, pb_data, &qw_remain );
205         if( NULL == pb_data )   { return NULL; }
206
207     if( ((DWord)0xffffffff) == dw_dword )   {
208                 pb_data = DWARF_Common_Read_QWord(
209                                         &qw_qword, pb_data, &qw_remain );
210                 if( NULL == pb_data )   { return NULL; }
211                 
212                 i_bitflag       = 64;
213                 pt_line->b_bits = 64;
214                 qw_remain       = qw_qword;
215         }
216         else    {
217                 qw_remain       = (QWord)dw_dword;
218         }
219         
220         /* Read version (2Byte) */
221         pb_data = DWARF_Common_Read_Word(
222                                         &(pt_line->w_version), pb_data, &qw_remain );
223         if( NULL == pb_data )   { return NULL; }
224         i_readbytes     += 2;
225
226         /* Read Header Length (4Byte(32bit), 8Byte(64bit)) */
227     if( 64 == i_bitflag )       {
228                 pb_data = DWARF_Common_Read_QWord(
229                                         &qw_qword, pb_data, &qw_remain );
230                 if( NULL == pb_data )   { return NULL; }
231                 i_readbytes += 8;
232
233                 pt_line->qw_headerlength        = qw_qword;
234     }
235     else    {
236                 pb_data = DWARF_Common_Read_DWord(
237                                         &dw_dword, pb_data, &qw_remain );
238                 if( NULL == pb_data )   { return NULL; }
239                 i_readbytes += 4;
240
241                 pt_line->qw_headerlength        = (QWord)dw_dword;
242     }
243
244         /* Read minimum Instruction Length (1Byte) */
245         pb_data = DWARF_Common_Read_Byte(
246                                         &(pt_line->b_minimum_inst_length), pb_data, &qw_remain );
247         if( NULL == pb_data )   { return NULL; }
248         i_readbytes     += 1;
249
250         /* Read default isStatement (1Byte) */
251         pb_data = DWARF_Common_Read_Byte(
252                                         &(pt_line->b_default_is_stmt), pb_data, &qw_remain );
253         if( NULL == pb_data )   { return NULL; }
254         i_readbytes     += 1;
255
256         /* Read LineBase (1Byte) */
257         pb_data = DWARF_Common_Read_Byte(
258                                         &b_byte, pb_data, &qw_remain );
259         if( NULL == pb_data )   { return NULL; }
260         i_readbytes     += 1;
261         pt_line->i_line_base    = (INT)((char)b_byte);
262
263         /* Read LineRange (1Byte) */
264         pb_data = DWARF_Common_Read_Byte(
265                                         &b_byte, pb_data, &qw_remain );
266         if( NULL == pb_data )   { return NULL; }
267         i_readbytes     += 1;
268         pt_line->i_line_range   = (INT)((DWord)b_byte);
269
270         /* Read Opcode Base (1Byte) */
271         pb_data = DWARF_Common_Read_Byte(
272                                         &(pt_line->b_opcode_base), pb_data, &qw_remain );
273         if( NULL == pb_data )   { return NULL; }
274         i_readbytes     += 1;
275
276         /* Read Operand length of the Standard Opecode */
277         for( i_cnt = 1; i_cnt < (pt_line->b_opcode_base); i_cnt++)      {
278                 pb_data = DWARF_Common_DecodeULEB128(
279                                                 &qw_qword, pb_data, &qw_remain );
280                 pt_line->dw_stdoperand_length[i_cnt]    = (int)((DWord)qw_qword);
281         }
282
283         /* Read Include File-Path  */
284         pb_data = LibGoblin_DwarfLine_Read_LineHeader_IncludePath(
285                                         pt_line, pb_data, &qw_remain );
286         if( NULL == pb_data )   { return NULL; }
287
288         /* Read FileNames */
289         pb_data = LibGoblin_DwarfLine_Read_LineHeader_FileNames(
290                                         pt_line, pb_data, &qw_remain );
291         if( NULL == pb_data )   { return NULL; }
292         
293
294         printf("  version: %d \n", pt_line->w_version );
295         printf("  header length: %ld\n", pt_line->qw_headerlength );
296         printf("  min. Inst. length: %d\n", pt_line->b_minimum_inst_length );
297         printf("  default isStmt: %x\n", pt_line->b_default_is_stmt );
298         printf("  line_base: %d\n", pt_line->i_line_base );
299         printf("  line_range: %d\n", pt_line->i_line_range );
300         printf("  opcode_base: %d\n", pt_line->b_opcode_base );
301         for( i_cnt = 0; i_cnt < pt_line->b_opcode_base; i_cnt++ )       {
302                 printf("    Std.Operand(%x) : %d \n", i_cnt, 
303                         pt_line->dw_stdoperand_length[i_cnt] );
304         }
305         printf("  include path nums: %d\n", pt_line->i_num_includepath );
306         printf("  include file nums: %d\n", pt_line->i_num_filename );
307         for( i_cnt = 0; i_cnt < pt_line->i_num_filename; i_cnt++ )      {
308                 printf("    SrcFile[%d] filename: %s  Dir.Index: %d  Date: %ld  Size: %ld \n", 
309                                                 i_cnt, 
310                                                 pt_line->t_filename[i_cnt].pstr_srcfilename,
311                                                 pt_line->t_filename[i_cnt].dw_dirindex,
312                                                 pt_line->t_filename[i_cnt].qw_date,
313                                                 pt_line->t_filename[i_cnt].qw_date );
314         }
315
316         //*pqw_size_linesec     = qw_remain;
317
318         return pb_data;
319 }
320
321
322 /*----------------------------------------------------------------------
323 ----------------------------------------------------------------------*/
324 QWord
325         LibGoblin_DwarfLine_CalcAddress(
326                 Byte    b_opcode,
327                 LibGoblin_Dwarf_LineSection             *pt_line )
328 {
329         QWord   qw_value;
330
331         assert( NULL != pt_line );
332
333         qw_value        = ((INT)(b_opcode - pt_line->b_opcode_base)
334                                                 / pt_line->i_line_range)
335                                         * (INT)pt_line->b_minimum_inst_length;
336
337         return qw_value;
338 }
339
340
341 /*----------------------------------------------------------------------
342 ----------------------------------------------------------------------*/
343 Int64
344         LibGoblin_DwarfLine_CalcLine(
345                 Byte    b_opcode,
346                 LibGoblin_Dwarf_LineSection             *pt_line )
347 {
348         Int64   ii_value;
349
350         assert( NULL != pt_line );
351
352         ii_value        = (Int64)(((INT)(b_opcode - pt_line->b_opcode_base)
353                                                         % pt_line->i_line_range) + pt_line->i_line_base);
354
355         return ii_value;
356 }
357
358
359 /*----------------------------------------------------------------------
360 ----------------------------------------------------------------------*/
361 int     
362         LibGoblin_DwarfLine_DebugPrint_Register(
363                 LibGoblin_Dwarf_Line_Register   *pt_reg )
364 {
365         if( NULL == pt_reg )    {
366                 puts(" Error: DebugRegister is NULL ");
367                 return 0xff;
368         }
369
370         printf("  [Line] File:%3d, PC:%08lx, Line:%5ld, Col:%2ld, ISA:%2ld, Option: %s%s%s%s\n",
371                         pt_reg->dw_file, pt_reg->qw_address, pt_reg->qw_line,
372                 pt_reg->qw_column,pt_reg->qw_isa,
373                         ((pt_reg->b_is_stmt != 0x00 ) ? "Stmt : " : "" ),
374                         ((pt_reg->b_basic_block != 0x00 ) ? "BasicBlk : " : "" ),
375                         ((pt_reg->b_prologue_end != 0x00 ) ? "PrologueEnd : " : "" ),
376                         ((pt_reg->b_epilogue_begin != 0x00 ) ? "EpilogueBegin" : "" ));
377
378         return 0x00;
379 }
380
381
382 /*----------------------------------------------------------------------
383 ----------------------------------------------------------------------*/
384 int     
385         LibGoblin_DwarfLine_InitRegister(
386                 LibGoblin_Dwarf_Line_Register   *pt_reg, 
387                 LibGoblin_Dwarf_LineSection     *pt_line )
388 {
389         assert( NULL != pt_reg );
390         assert( NULL != pt_line );
391
392         pt_reg->qw_address                      = 0x0000000000000000;
393     pt_reg->qw_line                             = 1;
394     pt_reg->dw_file                             = 1;
395         pt_reg->b_is_stmt
396                         = (pt_line->b_default_is_stmt == 0x00 ? 0x00 : 0x01 );
397     pt_reg->b_basic_block               = 0x00;
398     pt_reg->b_prologue_end              = 0x00;
399     pt_reg->b_epilogue_begin    = 0x00;
400     pt_reg->qw_column                   = 0;
401     pt_reg->qw_isa                              = 0;
402
403         return 0x00;
404 }
405
406
407 /*----------------------------------------------------------------------
408 ----------------------------------------------------------------------*/
409 Byte *
410         LibGoblin_DwarfLine_Read_LineData(
411                 LibGoblin_Dwarf_LineSection *pt_line,
412                 Byte    *pb_data,
413                 QWord   *pqw_remain )
414 {
415         Byte    *pb_temp;
416         Byte    b_opcode;
417         QWord   qw_qword;
418         Int64   ii_value;
419         Word    w_value;
420         LibGoblin_Dwarf_Line_Register   t_reg;
421         
422         assert( NULL != pt_line );
423         assert( NULL != pb_data );
424
425         LibGoblin_DwarfLine_InitRegister( &t_reg, pt_line );
426
427         do      {
428                 /* Read Opecode */
429                 pb_data = DWARF_Common_Read_Byte(
430                                         &b_opcode, pb_data, pqw_remain );
431                 if( NULL == pb_data )   { return NULL; }
432
433                 /* Read & Proc. by Opcode */
434                 if( 0x00 == b_opcode )          {
435                         /* Extended Opcode */
436                         pb_data = DWARF_Common_DecodeULEB128(
437                                                         &qw_qword, pb_data, pqw_remain );
438                         pb_temp = pb_data + qw_qword;
439
440                         /* XXX: unsupport user-more_than_2byte_opcode */
441                         pb_data = DWARF_Common_Read_Byte(
442                                                 &b_opcode, pb_data, pqw_remain );
443                         if( NULL == pb_data )   { return NULL; }
444
445                         /* dispatch for Extendee Opcode */
446                         if( DW_LNE_end_sequence == b_opcode )   {
447                                 /* No Operand */
448                                 puts("  DW_LNE_end_sequence <NoOperand>");
449                                 break;
450                         }
451                         else if( DW_LNE_set_address == b_opcode )       {
452                                 /* Operand: 4Byte(32bit) or 8Byte(64bit) */
453                                         pb_data = DWARF_Common_Read_QWord(
454                                                                         &qw_qword, pb_data, pqw_remain );
455                                         t_reg.qw_address        = qw_qword;
456                                 /*if( 64 == pt_line->b_bits )   {
457                                         pb_data = DWARF_Common_Read_QWord(
458                                                                         &qw_qword, pb_data, pqw_remain );
459                                         t_reg.qw_address        = qw_qword;
460                                 }
461                                 else    {
462                                         pb_data = DWARF_Common_Read_DWord(
463                                                                         &dw_value, pb_data, pqw_remain );
464                                         t_reg.qw_address        = (QWord)dw_value;
465                                 }*/
466                                 printf("  DW_LNE_set_address %08lx\n", t_reg.qw_address );
467                         }
468                         else if( DW_LNE_define_file == b_opcode )       {
469                                 /* Operand: Filename Data Struct(Line Header) */
470                                 pb_data = LibGoblin_DwarfLine_Read_LineHeader_FileNameData(
471                                                                 pt_line, pb_data, pqw_remain,
472                                                                 pt_line->i_num_filename );
473                                 pt_line->i_num_filename++;
474                                 printf("  DW_LNE_define_file \n");
475                         }
476                         else    {
477                                 pb_data = pb_temp;
478                         }
479                 
480                 }
481                 else if( pt_line->b_opcode_base > b_opcode )    {
482                         /* Standard Opcode */
483                         switch( b_opcode )      {
484                                 case DW_LNS_copy:                               /* 0x01 */
485                                         /* No Operand */
486                                         t_reg.b_basic_block             = 0x00;
487                                         t_reg.b_prologue_end    = 0x00;
488                                         t_reg.b_epilogue_begin  = 0x00;
489                                         puts("  DW_LNS_copy <NoOperand>");
490                                         break;
491
492                                 case DW_LNS_advance_pc:                 /* 0x02 */
493                                         /* Operand: uLEB128 */
494                                         pb_data = DWARF_Common_DecodeULEB128(
495                                                                         &qw_qword, pb_data, pqw_remain );
496                                         t_reg.qw_address
497                                                 += pt_line->b_minimum_inst_length * qw_qword;
498                                         printf("  DW_LNS_advance_pc %08lx\n", qw_qword);
499                                         
500                                         break;
501
502                                 case DW_LNS_advance_line:               /* 0x03 */
503                                         /* Operand: sLEB128 */
504                                         pb_data = DWARF_Common_DecodeLEB128(
505                                                                         &ii_value, pb_data, pqw_remain );
506                                         t_reg.qw_line
507                                                 = (QWord)((Int64)(t_reg.qw_line) + ii_value);
508                                         printf("  DW_LNS_advance_line %8ld\n", ii_value);
509                                         break;
510
511                                 case DW_LNS_set_file:                   /* 0x04 */
512                                         /* Operand: uLEB128 */
513                                         pb_data = DWARF_Common_DecodeULEB128(
514                                                                         &qw_qword, pb_data, pqw_remain );
515                                         t_reg.dw_file   = (DWord)qw_qword;
516                                         printf("  DW_LNS_set_file %ld\n", qw_qword);
517                                         break;
518
519                                 case DW_LNS_set_column:                 /* 0x05 */
520                                         /* Operand: uLEB128 */
521                                         pb_data = DWARF_Common_DecodeULEB128(
522                                                                         &qw_qword, pb_data, pqw_remain );
523                                         t_reg.qw_column = qw_qword;
524                                         printf("  DW_LNS_set_column %ld\n", qw_qword);
525                                         break;
526
527                                 case DW_LNS_negate_stmt:                /* 0x06 */
528                                         /* No Operand */
529                                         t_reg.b_is_stmt
530                                                 = ((t_reg.b_is_stmt == 0x00) ? 0x01 : 0x00 );
531                                         puts("  DW_LNS_negate_stmt");
532                                         break;
533
534                                 case DW_LNS_set_basic_block:    /* 0x07 */
535                                         /* No Operand */
536                                         t_reg.b_basic_block     = 0x01;
537                                         puts("  DW_LNS_set_basic_block");
538                                         break;
539
540                                 case DW_LNS_const_add_pc:               /* 0x08 */
541                                         qw_qword
542                                                 = LibGoblin_DwarfLine_CalcAddress( 0xff, pt_line);
543                                         t_reg.qw_address        += qw_qword;
544                                         printf("  DW_LNS_const_add_pc %08lx\n", qw_qword);
545                                         break;
546
547                                 case DW_LNS_fixed_advance_pc:   /* 0x09 */
548                                         /* Operand: uhalf(short) */
549                                         pb_data = DWARF_Common_Read_Word(
550                                                                 &w_value, pb_data, pqw_remain );
551                                         t_reg.qw_address += (QWord)w_value;
552                                         printf("  DW_LNS_fixed_advance_pc %08lx\n", (QWord)w_value);
553                                         break;
554
555                                 case DW_LNS_set_prologue_end:   /* 0x0a */
556                                         t_reg.b_prologue_end    = 0x01;
557                                         puts("  DW_LNS_set_prologue_end");
558                                         break;
559
560                                 case DW_LNS_set_epilogue_begin: /* 0x0b */
561                                         t_reg.b_epilogue_begin  = 0x01;
562                                         puts("  DW_LNS_set_epilogue_begin");
563                                         break;
564
565                                 case DW_LNS_set_isa:                    /* 0x0c */
566                                         /* Operand: uLEB128 */
567                                         pb_data = DWARF_Common_DecodeULEB128(
568                                                                         &qw_qword, pb_data, pqw_remain );
569                                         t_reg.qw_isa    += qw_qword;
570                                         printf("  DW_LNS_set_isa %08lx\n", qw_qword);
571                                         break;
572
573                                 default:
574                                         break;
575                         }
576                 }
577                 else    {
578                         /* Special Opcode */
579                         qw_qword = LibGoblin_DwarfLine_CalcAddress( b_opcode, pt_line);
580                         ii_value = LibGoblin_DwarfLine_CalcLine( b_opcode, pt_line);
581
582                         t_reg.qw_address        += (qw_qword * pt_line->b_minimum_inst_length);
583                         t_reg.qw_line           = (QWord)((Int64)t_reg.qw_line + ii_value);
584
585                         t_reg.b_basic_block             = 0x00;
586                         t_reg.b_prologue_end    = 0x00;
587                         t_reg.b_epilogue_begin  = 0x00;
588
589                 }
590
591                 LibGoblin_DwarfLine_DebugPrint_Register( &t_reg );
592
593         }while( 0 != *pqw_remain );
594
595         return pb_data;
596 }
597
598
599 /*----------------------------------------------------------------------
600 ----------------------------------------------------------------------*/
601 Byte *
602         LibGoblin_DwarfLine_ReadCompileUnit(
603                 LibGoblin_Dwarf_SourceFile *p_src,
604                 Byte    *pb_data,
605                 QWord   *pqw_remain )
606 {
607         LibGoblin_Dwarf_LineSection     *pt_line;
608
609         assert( NULL != p_src );
610         assert( NULL != pb_data );
611
612         pt_line = &(p_src->t_linesec);
613
614         /* Read & SetInfo LineHeader (in CU) */
615         pt_line->pb_header      = pb_data;
616         pb_data = LibGoblin_DwarfLine_Read_LineHeader(
617                                 pt_line, pb_data, pqw_remain );
618         if( NULL == pb_data )   {
619                 return NULL;
620         }
621
622         /* Read & Check LineData */
623         pb_data = LibGoblin_DwarfLine_Read_LineData(
624                                                 pt_line, pb_data, pqw_remain );
625
626         
627         return pb_data;
628 }
629
630
631
632 /*----------------------------------------------------------------------
633 ----------------------------------------------------------------------*/
634 LIBGOBLIN_DWARF_LINE_EXTERN
635 int
636         LibGoblin_DwarfLine_Analyze(
637                 LibGoblin_BinaryInfo    *p_bin )
638 {
639         int             i_srcfiles;
640         Byte    *pb_data;
641         QWord   qw_size;
642         LibGoblin_Dwarf_SourceFile      *p_src;
643         LibGoblin_Debug_Dwarf           *p_dwarf;
644
645         assert( NULL != p_bin );
646
647         p_dwarf = (LibGoblin_Debug_Dwarf *)p_bin->p_debug;
648         assert( NULL != p_dwarf );
649
650         i_srcfiles      = p_dwarf->i_srcfilenum;
651
652         p_src   = p_dwarf->p_src;
653         assert( NULL != p_src );
654
655         /* Get .debug_abbrev section Info */
656         pb_data = ELF_GetSection(
657                                         &qw_size, p_bin,
658                                         LIBGOBLIN_SECTION_ID_DEBUG_LINE );
659         if( NULL == pb_data )   { return 0x01; }
660
661         do      {
662                 p_src->t_linesec.pb_header      = pb_data;
663
664                 /* Analyze .debug_info compile unit */
665                 pb_data = LibGoblin_DwarfLine_ReadCompileUnit(
666                                                 p_src, pb_data, &qw_size );
667                 if( NULL == pb_data)    { return 0x02; }
668
669                 p_src++;
670                 i_srcfiles--;
671
672         }while((qw_size > 0) && (i_srcfiles > 0));
673         
674         return 0x00;
675 }
676
677
678
679 /* EOF of drd64_.c ----------------------------------- */