OSDN Git Service

(LibGoblin)
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_dwarf_info.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_INFO
38 #include"drd64_libgoblin.h"
39
40
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
43 Byte *
44         DWARF_Info_ReadCUHeader(
45                 LibGoblin_DWARF_Info_CUHeader   *p_cuhead,
46                 Byte    *pb_info,
47                 QWord   *pqw_size_info )
48 {
49         int             i_bitflag;
50         int             i_readbytes;
51         DWord   dw_dword;
52         QWord   qw_qword;
53
54         assert( NULL != p_cuhead );
55         assert( NULL != pb_info );
56
57         i_readbytes     = 0;
58         i_bitflag       = 32;
59
60         // Read unit_length (4Byte + 8Byte(64bit)) ---
61         pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
62         if( NULL == pb_info )   { return NULL; }
63
64         //     64bit - First 4Byte = 0xffffffff
65         if( ((DWord)0xffffffff) == dw_dword )   {
66                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
67                 if( NULL == pb_info )   { return NULL; }
68
69                 p_cuhead->qw_unitsize   = (QWord)qw_qword;
70                 i_bitflag                               = 64;
71                 p_cuhead->b_bits                = 64;
72                 p_cuhead->b_offsetsize  = 8;
73         }
74         //     32bit - First 4Byte = value.
75         else    {
76                 p_cuhead->qw_unitsize   = (QWord)dw_dword;
77                 p_cuhead->b_bits                = 32;
78                 p_cuhead->b_offsetsize  = 4;
79         }
80
81         // Read version (2Byte) ---
82         pb_info = DWARF_Common_Read_Word( &(p_cuhead->w_version), pb_info, pqw_size_info );
83         if( NULL == pb_info )   { return NULL; }
84         i_readbytes     = 2;
85
86         // Read abbrev_offset (4Byte(32bit), 8Byte(64bit)) ---
87         if( 64 == i_bitflag )   {
88                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
89                 if( NULL == pb_info )   { return NULL; }
90                 i_readbytes     += 8;
91
92                 p_cuhead->qw_abbrev_offset      = qw_qword;
93         }
94         else    {
95                 pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
96                 if( NULL == pb_info )   { return NULL; }
97                 i_readbytes     += 4;
98
99                 p_cuhead->qw_abbrev_offset      = (QWord)dw_dword;
100         }
101
102         // Read address_size (1Byte) ---
103         pb_info = DWARF_Common_Read_Byte( &(p_cuhead->b_pointersize), pb_info, pqw_size_info);
104         if( NULL == pb_info )   { return NULL; }
105         i_readbytes     += 1;
106
107         p_cuhead->qw_unitsize   -= i_readbytes;
108
109         // for DWARF4 ---
110         if( 4 == p_cuhead->w_version )  {
111                 // Read type-signature (8Byte) ---
112                 pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
113                 if( NULL == pb_info )   { return NULL; }
114                 i_readbytes     += 8;
115
116                 p_cuhead->qw_type_signature     = qw_qword;
117
118                 // Read type_offset (4Byte(32bit), 8Byte(64bit)) ---
119                 if( 64 == i_bitflag )   {
120                         pb_info = DWARF_Common_Read_QWord( &qw_qword, pb_info, pqw_size_info );
121                         if( NULL == pb_info )   { return NULL; }
122                         i_readbytes     += 8;
123
124                         p_cuhead->qw_type_offset        = qw_qword;
125                 }
126                 else    {
127                         pb_info = DWARF_Common_Read_DWord( &dw_dword, pb_info, pqw_size_info );
128                         if( NULL == pb_info )   { return NULL; }
129                         i_readbytes     += 4;
130
131                         p_cuhead->qw_type_offset        = (QWord)dw_dword;
132                 }
133
134         }
135         
136         return pb_info;
137 }
138
139
140 /*----------------------------------------------------------------------
141 ----------------------------------------------------------------------*/
142 LibGoblin_SrcFile *
143         DWARF_Info_RegistSrcFile_fromTagCompileUnit(
144                 LibGoblin_BinaryInfo    *p_binfo,
145                 LibGoblin_BinaryFile    *p_bfile,
146                 Byte                                    *pb_info,
147                 DWARF_AbbrevEntry               *p_abbrev,
148                 QWord                                   qw_size_cu,
149                 LibGoblin_DWARF_Info_CUHeader   *pt_cuheader )
150 {
151         int                                                     i_childlv;
152         char                                            *pstr_srcpath   = NULL;
153         char                                            str_temp[DRD64_MAX_PATH+1];
154         DWord                                           dw_arvid;
155         QWord                                           qw_temp;
156         DWARF_AbbrevEntry                       *p_arvnow;
157         LibGoblin_DWARF_DIEValue        *p_val;
158         LibGoblin_SrcFile                       *p_srcfile;
159
160         assert( NULL != p_binfo );
161         assert( NULL != p_bfile );
162
163         i_childlv       = 0;
164         do      {
165                 // Read Reference Abbrev-ID ---
166                 pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
167                 dw_arvid        = (DWord)qw_temp;
168
169                 if( 0 == dw_arvid )     {
170                         i_childlv--;
171                         continue;
172                 }
173
174                 p_arvnow        = p_abbrev + (dw_arvid - 1);
175
176                 // Read Debug Information Entry (DIE) ---
177                 pb_info = DWARF_AttrForm_ReadDIEValue(
178                                                 pb_info, &qw_size_cu, p_arvnow, p_binfo, pt_cuheader );
179
180                 if( 0x00 != p_arvnow->b_children )      { i_childlv++; }
181
182                 // Check compile unit tag ---
183                 if( DW_TAG_compile_unit == p_arvnow->dw_tag )   { break; }
184
185         }while( 0 != qw_size_cu ); 
186
187         if( DW_TAG_compile_unit != p_arvnow->dw_tag )   {
188                 return NULL;
189         }
190
191         p_val   = DWARF_AttrForm_GetDIEValue( p_binfo, DW_AT_name );
192         if( NULL != p_val )     { pstr_srcpath  = p_val->value.pstr_value; }
193         if( NULL == pstr_srcpath )      {
194                 return NULL;            
195         }
196
197         strncpy( str_temp, pstr_srcpath, DRD64_MAX_PATH );
198         p_srcfile       = SrcFile_DispenseSrcFile( p_bfile, basename( str_temp ) );
199         if( NULL == p_srcfile ) {
200                 return NULL;
201         }
202
203         strncpy( p_srcfile->str_srcpath, dirname( str_temp ), DRD64_MAX_PATH );
204
205         return p_srcfile;
206 }
207
208
209 /*----------------------------------------------------------------------
210 ----------------------------------------------------------------------*/
211 LIBGOBLIN_DWARF_INFO_EXTERN
212 int
213         DWARF_Info_Read(
214                 LibGoblin_BinaryInfo    *p_binfo )
215 {
216         int                                                     i_childlv;
217         int                                                     i_result;
218         int                                                     i_srcfiles;
219         int                                                     i_abbrevs;
220         Byte                                            *pb_info;
221         Byte                                            *pb_custart;
222         DWord                                           dw_arvid;
223         QWord                                           qw_temp;
224         QWord                                           qw_size_cu;
225         QWord                                           qw_size_info;
226         LibGoblin_SectionInfo           *psec_info;
227         LibGoblin_BinaryFile            *p_bfile;
228         DWARF_AbbrevEntry                       *p_abbrev;
229         DWARF_AbbrevEntry                       *p_arvnow;
230         LibGoblin_DWARF_Info_CUHeader   t_cuheader;
231         LibGoblin_SrcFile                       *p_srcfile;
232
233         assert( NULL != p_binfo );
234
235         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
236         assert( NULL != p_bfile );
237
238         i_srcfiles      = p_bfile->dwarf.i_srcfiles;
239
240         // Get section Info ---
241         psec_info       = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_INFO );
242         assert( NULL != psec_info );
243         if( NULL == psec_info->pb_data )        {
244                 return 0x01;
245         }
246         pb_info                 = psec_info->pb_data;
247         qw_size_info    = psec_info->qw_size;
248
249         do      {
250                 // Read Compile Unit Header ---
251                 pb_custart      = pb_info;
252                 pb_info = DWARF_Info_ReadCUHeader( &t_cuheader, pb_info, &qw_size_info );
253                 if( NULL == pb_info )   {
254                         return 0x02;
255                 }
256
257                 t_cuheader.pb_custart   = pb_custart;
258                 qw_size_cu                              = t_cuheader.qw_unitsize;
259
260                 // Read Abbrev for the now compile unit ---
261                 i_result        = DWARF_Abbrev_ReadAbbrevEntry(
262                                                                 &p_abbrev, &i_abbrevs,
263                                                                 p_binfo, p_bfile, t_cuheader.qw_abbrev_offset );
264
265                 // Read DW_TAG_compile_unit & Regist SrcFile struct. ---
266                 p_srcfile       = DWARF_Info_RegistSrcFile_fromTagCompileUnit(
267                                                                 p_binfo, p_bfile, pb_info, p_abbrev, qw_size_cu, &t_cuheader );
268                 if( NULL != p_srcfile ) {
269                         p_srcfile->dwarf.i_abbrevs      = i_abbrevs;
270                         p_srcfile->dwarf.p_abbrev       = p_abbrev;
271
272                         //printf( "\n SrcFile: %s,  Orig.Path: %s\n", p_srcfile->str_filename, p_srcfile->str_srcpath );
273                 }
274 /*
275                 printf( "    size: %ld, ver:%d, abbrev off.:%ld, addr.size: %d\n",
276                         t_cuheader.qw_unitsize,
277                         t_cuheader.w_version,
278                         t_cuheader.qw_abbrev_offset,
279                         t_cuheader.b_pointersize);
280 */
281
282                 // Read & Process DWARF info TAG ---
283                 i_childlv       = 0;
284                 do      {
285                         // Read Reference Abbrev-ID ---
286                         pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
287                         dw_arvid        = (DWord)qw_temp;
288
289                         if( 0 == dw_arvid )     {
290                                 i_childlv--;
291                                 continue;
292                         }
293
294                         p_arvnow        = p_abbrev + (dw_arvid - 1);
295
296                         // Read Debug Information Entry (DIE) ---
297                         pb_info = DWARF_AttrForm_ReadDIEValue(
298                                                         pb_info, &qw_size_cu, p_arvnow, p_binfo, &t_cuheader );
299
300                         // Dispatch for generate Rapid-Access Table by DIE-tag
301                         i_result        = DWARF_Tag_Dispatch( p_binfo, p_bfile, p_srcfile, p_arvnow );
302
303                         Debug_DWARF_PrintDIE( p_binfo, p_abbrev, dw_arvid, i_childlv );
304
305                         if( 0x00 != p_arvnow->b_children )      { i_childlv++; }
306
307                 }while( 0 != qw_size_cu ); 
308                 qw_size_info    -= t_cuheader.qw_unitsize;
309
310         }while((qw_size_info > 0) && (i_srcfiles > 0));
311
312         
313         return 0x00;
314 }
315
316
317 /* EOF of drd64_.c ----------------------------------- */