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_DWARF_INFO_EXTERN
143 int
144         DWARF_Info_Read(
145                 LibGoblin_BinaryInfo    *p_binfo )
146 {
147         int                                                     i_childlv;
148         int                                                     i_result;
149         int                                                     i_objid;
150         int                                                     i_objfiles;
151         int                                                     i_abbrevs;
152         Byte                                            *pb_info;
153         Byte                                            *pb_now;
154         Byte                                            *pb_custart;
155         DWord                                           dw_arvid;
156         QWord                                           qw_temp;
157         QWord                                           qw_size_cu;
158         QWord                                           qw_size_info;
159         LibGoblin_SectionInfo           *psec_info;
160         LibGoblin_BinaryFile            *p_bfile;
161         LibGoblin_ObjectInfo            *p_obj;
162         LibGoblin_ProgramInfo           *p_pginfo;
163         DWARF_AbbrevEntry                       *p_abbrev;
164         DWARF_AbbrevEntry                       *p_arvnow;
165         LibGoblin_DWARF_Info_CUHeader   t_cuheader;
166         LibGoblin_DWARF_Info_Ancestry   t_ancestry[DWARF_ANCESTRY_MAX];
167
168         assert( NULL != p_binfo );
169
170         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
171         assert( NULL != p_bfile );
172
173         p_pginfo        = ProgInfo_GetProgInfo( p_binfo->i_pginfo );
174         assert( NULL != p_pginfo );
175
176         i_objfiles      = p_bfile->dwarf.i_objfiles;
177
178         // Get section Info ---
179         psec_info       = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_INFO );
180         assert( NULL != psec_info );
181         if( NULL == psec_info->pb_data )        {
182                 return 0x01;
183         }
184         pb_info                 = psec_info->pb_data;
185         qw_size_info    = psec_info->qw_size;
186
187         do      {
188                 // Read Compile Unit Header ---
189                 pb_custart      = pb_info;
190                 pb_info = DWARF_Info_ReadCUHeader( &t_cuheader, pb_info, &qw_size_info );
191                 if( NULL == pb_info )   {
192                         return 0x02;
193                 }
194
195                 t_cuheader.pb_custart   = pb_custart;
196                 qw_size_cu                              = t_cuheader.qw_unitsize;
197
198                 // Read Abbrev for the now compile unit ---
199                 i_result        = DWARF_Abbrev_ReadAbbrevEntry(
200                                                                 &p_abbrev, &i_abbrevs,
201                                                                 p_binfo, p_bfile, t_cuheader.qw_abbrev_offset );
202
203                 // Read & Process DWARF info TAG ---
204                 i_childlv       = 0;
205                 t_ancestry[0].pb_dwinfo = NULL;
206                 t_ancestry[0].i_objid   = NO_OBJ;
207
208                 do      {
209                         pb_now  = pb_info;
210
211                         // Read Reference Abbrev-ID ---
212                         pb_info = DWARF_Common_DecodeULEB128( &qw_temp, pb_info, &qw_size_cu );
213                         dw_arvid        = (DWord)qw_temp;
214
215                         if( 0 == dw_arvid )     {
216                                 i_childlv--;
217                                 continue;
218                         }
219
220                         p_arvnow        = p_abbrev + (dw_arvid - 1);
221
222                         // Read Debug Information Entry (DIE) ---
223                         pb_info = DWARF_AttrForm_ReadDIEValue(
224                                                         pb_info, &qw_size_cu, p_arvnow, p_binfo, &t_cuheader );
225
226                         // Dispatch for generate Rapid-Access Table by DIE-tag
227                         i_objid = DWARF_Tag_Dispatch( p_binfo, p_arvnow, i_childlv, t_ancestry, &t_cuheader );
228
229                         // Set Compile-Unit data ---
230                         if( NO_OBJ < i_objid )  {
231                                 p_obj   = ObjectInfo_GetObjectInfo( p_pginfo, i_objid );
232                                 assert( NULL != p_obj );
233
234                                 p_obj->dwarf.pb_info    = pb_now;
235
236                                 if( DW_TAG_compile_unit == p_arvnow->dw_tag )   {
237                                         assert( OBJINFO_TYPE_OBJFILE == p_obj->b_type );
238
239                                         p_obj->info.objfile.i_abbrevs   = i_abbrevs;
240                                         p_obj->info.objfile.p_abbrev    = p_abbrev;
241                                         memcpy( &(p_obj->info.objfile.t_cuheader), &t_cuheader,
242                                                                                         sizeof( LibGoblin_DWARF_Info_CUHeader ) );
243                                 }
244                         }
245
246                         t_ancestry[i_childlv].pb_dwinfo = pb_now;
247                         t_ancestry[i_childlv].i_objid   = i_result;
248
249                         Debug_DWARF_PrintDIE( p_binfo, p_abbrev, dw_arvid, i_childlv );
250
251                         if( 0x00 != p_arvnow->b_children )      {
252                                 i_childlv++;
253                                 t_ancestry[i_childlv].pb_dwinfo = NULL;
254                                 t_ancestry[i_childlv].i_objid   = NO_OBJ;
255                         }
256
257                 }while( 0 != qw_size_cu ); 
258                 qw_size_info    -= t_cuheader.qw_unitsize;
259
260         }while((qw_size_info > 0) && (i_objfiles > 0));
261
262         
263         return 0x00;
264 }
265
266
267 /* EOF of drd64_.c ----------------------------------- */