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_LINE
38 #include"drd64_libgoblin.h"
39
40
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
43 /*
44 Byte *
45         LibGoblin_DwarfLine_Read_LineHeader_FileNameData(
46                 LibGoblin_Dwarf_LineSection *pt_line,
47                 Byte    *pb_data,
48                 QWord   *pqw_remain,
49                 int             i_files )
50 {
51         QWord   qw_qword;
52         Byte    b_byte;
53
54         // Read FileName ---
55         b_byte  = *pb_data;
56         pt_line->t_filename[ i_files ].pstr_srcfilename
57                                                                         = (char *)(pb_data - 1);
58         while( ( 0 < *pqw_remain) && ('\0' != b_byte) ) {
59                 (*pqw_remain)--;
60                 b_byte  = *pb_data++;
61         }
62
63         // Read Directory Index ---
64         pb_data = DWARF_Common_DecodeULEB128(
65                                         &qw_qword, pb_data, pqw_remain );
66         if( NULL == pb_data )   { return NULL; }
67         pt_line->t_filename[ i_files ].dw_dirindex      = (DWord)qw_qword;
68
69         // Read File-Date ---
70         pb_data = DWARF_Common_DecodeULEB128(
71                                         &qw_qword, pb_data, pqw_remain );
72         if( NULL == pb_data )   { return NULL; }
73         pt_line->t_filename[ i_files ].qw_date  = qw_qword;
74
75         // Read File-Size ---
76         pb_data = DWARF_Common_DecodeULEB128(
77                                         &qw_qword, pb_data, pqw_remain );
78         if( NULL == pb_data )   { return NULL; }
79         pt_line->t_filename[ i_files ].qw_filesize      = qw_qword;
80
81         return pb_data;
82 }
83 */
84
85 /*----------------------------------------------------------------------
86 ----------------------------------------------------------------------*/
87 /*
88 Byte *
89         LibGoblin_DwarfLine_Read_LineHeader_FileNames(
90                 LibGoblin_Dwarf_LineSection *pt_line,
91                 Byte    *pb_data,
92                 QWord   *pqw_remain )
93 {
94         int             i_files;
95         Byte    b_byte;
96
97         i_files = 0;
98
99         if( 1 > (*pqw_remain)-- )       { return NULL; }
100         b_byte  = *pb_data++;
101
102         while( '\0' != b_byte)  {
103                 pb_data = LibGoblin_DwarfLine_Read_LineHeader_FileNameData(
104                                                 pt_line, pb_data, pqw_remain, i_files );
105
106                 if( 1 > (*pqw_remain)-- )       { return NULL; }
107                 b_byte  = *pb_data++;
108         
109                 i_files++;
110         }
111
112         pt_line->i_num_filename = i_files;
113
114         return pb_data;
115 }
116 */
117
118 /*----------------------------------------------------------------------
119 ----------------------------------------------------------------------*/
120 char *
121         DWARF_Line_GetPath_fromLineHeader(
122                 Byte    *pb_path,
123                 DWord   dw_dirindex )
124 {
125         char    *pstr_path;
126         DWord   dw_cnt;
127
128         if( 0 == dw_dirindex )
129                 { return NULL; }
130
131         dw_dirindex--;
132         pstr_path       = pb_path;
133
134         while(( '\0' != *pb_path ) && ( 0 < dw_dirindex ))      { 
135                 while( '\0' != *pb_path++ );
136                 pstr_path       = pb_path;
137                 dw_dirindex--;
138         }
139
140         if( '\0' == *pb_path )
141                 { pstr_path     = NULL; }
142
143         return pstr_path;
144 }
145
146
147 /*----------------------------------------------------------------------
148 ----------------------------------------------------------------------*/
149 Byte *
150         DWARF_Line_Read_LineHeader(
151                 LibGoblin_DWARF_Line_Header     *pt_line,
152                 Byte    *pb_data,
153                 QWord   *pqw_size_linesec )
154 {
155         int             i_bitflag;
156         int             i_cnt;
157         Byte    b_byte;
158         DWord   dw_dword;
159         QWord   qw_qword;
160         QWord   qw_remain;
161
162         assert( NULL != pt_line );
163         assert( NULL != pb_data );
164
165         i_bitflag       = 32;
166         pt_line->b_bits = 32;
167         qw_remain       = *pqw_size_linesec;
168
169         // Read unit_length (4Byte(32bit) or 8Byte(64bit)) ---
170         pb_data = DWARF_Common_Read_DWord( &dw_dword, pb_data, &qw_remain );
171         if( NULL == pb_data )   { return NULL; }
172
173     if( ((DWord)0xffffffff) == dw_dword )   {
174                 pb_data = DWARF_Common_Read_QWord( &qw_qword, pb_data, &qw_remain );
175                 if( NULL == pb_data )   { return NULL; }
176                 
177                 i_bitflag               = 64;
178                 pt_line->b_bits = 64;
179                 qw_remain               = qw_qword;
180         }
181         else    {
182                 qw_remain               = (QWord)dw_dword;
183         }
184         
185         // Read version (2Byte) ---
186         pb_data = DWARF_Common_Read_Word( &(pt_line->w_version), pb_data, &qw_remain );
187         if( NULL == pb_data )   { return NULL; }
188
189         // Read Header Length (4Byte(32bit), 8Byte(64bit)) ---
190     if( 64 == i_bitflag )       {
191                 pb_data = DWARF_Common_Read_QWord( &qw_qword, pb_data, &qw_remain );
192                 if( NULL == pb_data )   { return NULL; }
193
194                 pt_line->qw_headerlength        = qw_qword;
195     }
196     else    {
197                 pb_data = DWARF_Common_Read_DWord( &dw_dword, pb_data, &qw_remain );
198                 if( NULL == pb_data )   { return NULL; }
199
200                 pt_line->qw_headerlength        = (QWord)dw_dword;
201     }
202
203         // Read minimum Instruction Length (1Byte) ---
204         pb_data = DWARF_Common_Read_Byte(
205                                         &(pt_line->b_minimum_inst_length), pb_data, &qw_remain );
206         if( NULL == pb_data )   { return NULL; }
207
208         // Read default isStatement (1Byte) ---
209         pb_data = DWARF_Common_Read_Byte(
210                                         &(pt_line->b_default_is_stmt), pb_data, &qw_remain );
211         if( NULL == pb_data )   { return NULL; }
212
213         // Read LineBase (1Byte) ---
214         pb_data = DWARF_Common_Read_Byte( &b_byte, pb_data, &qw_remain );
215         if( NULL == pb_data )   { return NULL; }
216         pt_line->i_line_base    = (INT)((char)b_byte);
217
218         // Read LineRange (1Byte) ---
219         pb_data = DWARF_Common_Read_Byte( &b_byte, pb_data, &qw_remain );
220         if( NULL == pb_data )   { return NULL; }
221         pt_line->i_line_range   = (INT)((DWord)b_byte);
222
223         // Read Opcode Base (1Byte) ---
224         pb_data = DWARF_Common_Read_Byte(
225                                         &(pt_line->b_opcode_base), pb_data, &qw_remain );
226         if( NULL == pb_data )   { return NULL; }
227
228         // Read Operand length of the Standard Opecode ---
229         for( i_cnt = 1; i_cnt < (pt_line->b_opcode_base); i_cnt++)      {
230                 pb_data = DWARF_Common_DecodeULEB128( &qw_qword, pb_data, &qw_remain );
231                 pt_line->dw_stdoperand_length[i_cnt]    = (int)((DWord)qw_qword);
232         }
233
234 /*
235         printf("  Length: %ld \n", qw_remain );
236         printf("  version: %d \n", pt_line->w_version );
237         printf("  header length: %ld\n", pt_line->qw_headerlength );
238         printf("  min. Inst. length: %d\n", pt_line->b_minimum_inst_length );
239         printf("  default isStmt: %x\n", pt_line->b_default_is_stmt );
240         printf("  line_base: %d\n", pt_line->i_line_base );
241         printf("  line_range: %d\n", pt_line->i_line_range );
242         printf("  opcode_base: %d\n", pt_line->b_opcode_base );
243         for( i_cnt = 1; i_cnt < pt_line->b_opcode_base; i_cnt++ )       {
244                 printf("    Std.Operand(%x) : %d \n", i_cnt, pt_line->dw_stdoperand_length[i_cnt] );
245         }
246 */
247
248         *pqw_size_linesec       = qw_remain;
249
250         return pb_data;
251 }
252
253
254 /*----------------------------------------------------------------------
255 ----------------------------------------------------------------------*/
256 LIBGOBLIN_DWARF_LINE_EXTERN
257 int
258         DWARF_Line_ReadSrcFile(
259                         LibGoblin_BinaryInfo    *p_binfo,
260                         DWord   dw_offset )
261 {
262         int             i_pos;
263         int             i_path;
264         int             i_files;
265         Byte    b_byte;
266         Byte    *pb_line;
267         DWord   dw_dirindex;
268         QWord   qw_qword;
269         QWord   qw_date;
270         QWord   qw_filesize;
271         QWord   qw_remain;
272         char    *pstr_path;
273         char    str_filename[DRD64_MAX_PATH + 1];
274         LibGoblin_SectionInfo   *psec_line;
275         LibGoblin_DWARF_Line_Header             t_linehdr;
276         LibGoblin_BinaryFile    *p_bfile;
277
278         psec_line       = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_LINE );
279         assert( NULL != psec_line );
280
281         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
282         assert( NULL != p_bfile );
283
284         pb_line         = psec_line->pb_data + dw_offset;
285         qw_remain       = psec_line->qw_size - dw_offset;
286
287         // (Phase1) Read .debug_line Header ===============================
288         pb_line = DWARF_Line_Read_LineHeader( &t_linehdr, pb_line, &qw_remain );
289
290
291         // (Phase2) Skip Path Section in .debug_line Header ===============
292         t_linehdr.pb_path       = pb_line;
293         i_path  = 0;
294
295         if( 1 > qw_remain-- )   { return -0x01; }
296         b_byte  = *pb_line++;
297
298         while( '\0' != b_byte ) { 
299                 if( 1 > qw_remain-- )   { return -0x01; }
300                 b_byte  = *pb_line++;
301
302                 if( '\0' == b_byte )    {
303                         if( 1 > qw_remain-- )   { return -0x01; }
304                         b_byte  = *pb_line++;
305                         i_path++;
306                 }
307         }
308         t_linehdr.i_path        = i_path;
309         //printf("  path nums: %d\n", t_linehdr.i_path );
310
311
312         // (Phase3) Read FileName Section in .debug_line Header ===========
313         if( 1 > qw_remain-- )   { return -0x01; }
314         b_byte  = *pb_line++;
315
316         i_files = 0;
317         while( '\0' != b_byte)  {
318                 // Read FileName ---
319                 i_pos   = 0;
320                 while( ( 0 < qw_remain) && ('\0' != b_byte) )   {
321                         str_filename[i_pos++]   = (char)b_byte;
322                         b_byte                                  = *pb_line++;
323                         qw_remain--;
324                 }
325                 str_filename[i_pos++]   = (char)b_byte;
326
327                 // Read Directory Index ---
328                 pb_line = DWARF_Common_DecodeULEB128( &qw_qword, pb_line, &qw_remain );
329                 if( NULL == pb_line )   { return -0x01; }
330                 dw_dirindex     = (DWord)qw_qword;
331
332                 // Read File-Date ---
333                 pb_line = DWARF_Common_DecodeULEB128( &qw_qword, pb_line, &qw_remain );
334                 if( NULL == pb_line )   { return -0x01; }
335                 qw_date = qw_qword;
336
337                 // Read File-Size ---
338                 pb_line = DWARF_Common_DecodeULEB128( &qw_qword, pb_line, &qw_remain );
339                 if( NULL == pb_line )   { return -0x01; }
340                 qw_filesize     = qw_qword;
341
342                 if( 0 == dw_dirindex )
343                         { pstr_path     = p_bfile->str_remotepath; }
344                 else
345                         { pstr_path     = DWARF_Line_GetPath_fromLineHeader( t_linehdr.pb_path, dw_dirindex ); }
346
347 /*
348                 printf("    SrcFile[%2d] %30s  Dir.Index: %d  Date: %ld  Size: %ld  Path: %s\n", 
349                                                 i_files, str_filename, dw_dirindex, qw_date, qw_filesize, pstr_path );
350 */
351
352                 i_files++;
353
354                 if( 1 > qw_remain-- )   { return -0x01; }
355                 b_byte  = *pb_line++;
356         }
357
358         return 0x00;
359 }
360
361
362 /* EOF of drd64_.c ----------------------------------- */