OSDN Git Service

* [libintel64asm] Create Test Binary File.
[drdeamon64/drdeamon64.git] / libgoblin / drd64_libgoblin_dwarf_abbrev.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 LIBGOBLIN_DWARF_ABBREV_EXTERN
43 void
44         Debug_DWARF_Abbrev_Dump(
45                 LibGoblin_BinaryInfo    *p_binfo,
46                 Byte    b_level )
47 {
48         int                                             i_cnt;
49         int                                             i_items;
50         LibGoblin_BinaryFile    *p_bfile;
51         DWARF_AbbrevEntry               *p_arvnow;
52
53         if( 0x00 < b_level )
54                 { puts("[DEBUG] DWARF Abbrev ------------------------------------------------"); }
55
56         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
57         assert( NULL != p_bfile );
58
59         p_arvnow        = p_bfile->dwarf.p_abbrev;
60         for( i_cnt = 0; i_cnt < p_bfile->dwarf.i_abbrevs_max; i_cnt++, p_arvnow++ )     {
61                 
62                 printf("  [ID= %2d] TAG= %02xh Child=%s\n",
63                                                 p_arvnow->dw_id, p_arvnow->dw_tag,
64                                                 ((0x00 == p_arvnow->b_children) ? "NO" : "YES") );
65                 
66                 for( i_items = 0; i_items < p_arvnow->i_items; i_items++ )      {
67                         printf("      Attribute= %02xh , Format= %02xh\n",
68                                                 p_arvnow->dw_attribute[ i_items ],
69                                                 p_arvnow->dw_format[ i_items ] );       
70                 }
71         }
72
73         if( 0x00 < b_level )    {
74                 puts("-----------------------------------------------------------------------");
75                 puts("");
76         }
77
78         return;
79 }
80
81
82 /*----------------------------------------------------------------------
83 ----------------------------------------------------------------------*/
84 LIBGOBLIN_DWARF_ABBREV_EXTERN
85 Byte *
86         LibGoblin_DwarfAbbrev_ReadEntry(
87                 LibGoblin_Dwarf_AbbrevEntry     *p_entry,
88                 Byte    *pb_src,
89                 QWord   *pqw_remain )
90 {
91         int             i_items;
92         DWord   dw_attribute;
93         DWord   dw_format;
94         QWord   qw_temp;
95
96         assert( NULL != p_entry );
97         assert( NULL != pb_src );
98
99         i_items = 0;
100
101         memset( p_entry, 0x00, sizeof( LibGoblin_Dwarf_AbbrevEntry ) );
102
103         /* Read Abbrev Number */
104         pb_src  = DWARF_Common_DecodeULEB128( &qw_temp, pb_src, pqw_remain );
105
106         p_entry->dw_id  = (DWord)qw_temp;
107         if( 0x00000000 == p_entry->dw_id )      {
108                 return pb_src;
109         }
110
111         /* Read TAG */
112         pb_src  = DWARF_Common_DecodeULEB128( &qw_temp, pb_src, pqw_remain );
113         p_entry->dw_tag = (DWord)qw_temp;
114
115         /* Read IsChildren */
116         pb_src  = DWARF_Common_Read_Byte( &(p_entry->b_children), pb_src, pqw_remain );
117         if( NULL == pb_src )    { return NULL; }
118
119 /*
120         printf("%04x : TAG=%04x (Children=%x) %ld\n",
121                                 p_entry->dw_id, p_entry->dw_tag, p_entry->b_children, *pqw_remain);
122 */
123
124         do      {
125                 /* Read Attribute */
126                 pb_src  = DWARF_Common_DecodeULEB128( &qw_temp, pb_src, pqw_remain );
127                 dw_attribute    = (DWord)qw_temp;
128                 p_entry->dw_attribute[i_items]  = dw_attribute;
129         
130                 /* Read Format */
131                 pb_src  = DWARF_Common_DecodeULEB128( &qw_temp, pb_src, pqw_remain );
132                 dw_format               = (DWord)qw_temp;
133                 p_entry->dw_format[i_items]     = dw_format;
134
135 /*
136                 printf("    Attiribute=%02x Format=%02x\n",
137                                         dw_attribute, dw_format);
138 */
139
140                 i_items++;
141
142         }while((0x00 != dw_attribute) && (0x00 != dw_format)
143                                         && (*pqw_remain > 0) );
144
145         p_entry->i_items        = i_items;
146
147         return pb_src;
148 }
149
150
151 /*----------------------------------------------------------------------
152 ----------------------------------------------------------------------*/
153 LIBGOBLIN_DWARF_ABBREV_EXTERN
154 int
155         DWARF_Abbrev_ReadAbbrevEntry(
156                 DWARF_AbbrevEntry               **pp_abbrev,
157                 int                                             *pi_abbrevs,
158                 LibGoblin_BinaryInfo    *p_binfo,
159                 LibGoblin_BinaryFile    *p_bfile,
160                 QWord   qw_offset )
161 {
162         int             i_abbrevs;
163         int             i_items;
164         int             i_count;
165         Byte    *pb_data;
166         Byte    b_children;
167         QWord   qw_temp;
168         QWord   qw_remain;
169         DWord   dw_abbrev_num;
170         DWord   dw_before_num;
171         DWord   dw_tag;
172         DWord   dw_attribute;
173         DWord   dw_format;
174         LibGoblin_SectionInfo           *psec_abbrev;
175         DWARF_AbbrevEntry                       *p_arvnow;
176
177         assert( NULL != pp_abbrev );
178         assert( NULL != pi_abbrevs );
179         assert( NULL != p_binfo );
180         assert( NULL != p_bfile );
181
182         *pp_abbrev      = NULL;
183         *pi_abbrevs     = 0;
184
185         // Get .debug_abbrev section Info ---
186         psec_abbrev     =       Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_ABBREV );
187         assert( NULL != psec_abbrev );
188         if( NULL == psec_abbrev->pb_data )      {
189                 return 0x01;
190         }
191         pb_data         = psec_abbrev->pb_data + qw_offset;
192         qw_remain       = p_bfile->dwarf.qw_abbrev_unreadsz;
193
194         i_abbrevs       = p_bfile->dwarf.i_abbrevs_max;
195         p_arvnow        = p_bfile->dwarf.p_abbrev + i_abbrevs;
196
197         i_count                 = 0;
198         dw_before_num   = 0;
199         do      {
200                 // Read Abbrev Number ---
201                 pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_remain );
202                 dw_abbrev_num   = (DWord)qw_temp;
203
204                 /* Read TAG */
205                 pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_remain );
206                 dw_tag  = (DWord)qw_temp;
207
208                 if(( 0x00 == dw_tag ) || (dw_abbrev_num < dw_before_num ))      { break; }
209
210                 /* Read IsChildren */
211                 b_children      = *pb_data++;
212                 qw_remain--;
213
214                 i_items = -1;
215                 do      {
216                         i_items++;
217
218                         /* Read Attribute */
219                         pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_remain );
220                         dw_attribute    = (DWord)qw_temp;
221         
222                         /* Read Format */
223                         pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_remain );
224                         dw_format       = (DWord)qw_temp;
225
226                         p_arvnow->dw_attribute[ i_items ]       = dw_attribute;
227                         p_arvnow->dw_format[ i_items ]          = dw_format;
228
229                 }while((0x00 != dw_attribute) && (0x00 != dw_format) && (qw_remain > 0) );
230
231                 // Skip Byte for Abbrev
232                 if( 0x00 == *pb_data )  {
233                         pb_data++;
234                         qw_remain--;
235                 }
236
237                 p_arvnow->dw_id                 = dw_abbrev_num;
238                 p_arvnow->dw_tag                = dw_tag;
239                 p_arvnow->b_children    = b_children;
240                 p_arvnow->i_items               = i_items;
241                 p_arvnow++;
242                 p_bfile->dwarf.i_abbrevs_max++;
243                 p_bfile->dwarf.qw_abbrev_unreadsz       = qw_remain;
244                 dw_before_num   = dw_abbrev_num;
245                 i_count++;
246
247         }while((qw_remain > 0) && (dw_tag != 0x00));
248         
249         *pp_abbrev      = p_bfile->dwarf.p_abbrev + i_abbrevs;
250         *pi_abbrevs     = i_count;
251
252         return 0x00;
253 }
254
255
256 /*----------------------------------------------------------------------
257 ----------------------------------------------------------------------*/
258 int
259         DWARF_Abbrev_GetItems(
260                 int             *pi_filenum,
261                 int             *pi_abbrevs,
262                 int             *pi_maxitems,
263                 QWord   *pqw_size,
264                 LibGoblin_BinaryInfo    *p_binfo )
265 {
266         int             i_maxitems;
267         int             i_items;
268         Byte    *pb_data;
269         Byte    b_children;
270         QWord   qw_temp;
271         QWord   qw_size;
272         DWord   dw_abbrev_num;
273         DWord   dw_tag;
274         DWord   dw_attribute;
275         DWord   dw_format;
276         LibGoblin_SectionInfo           *psec_abbrev;
277
278         assert( NULL != p_binfo );
279
280         // Get .debug_abbrev section Info ---
281         psec_abbrev     =       Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DEBUG_ABBREV );
282         assert( NULL != psec_abbrev );
283         if( NULL == psec_abbrev->pb_data )      {
284                 return 0x01;
285         }
286         pb_data         = psec_abbrev->pb_data;
287         qw_size         = psec_abbrev->qw_size;
288         *pqw_size       = psec_abbrev->qw_size;
289
290         *pi_filenum     = 0;
291         *pi_abbrevs     = 0;
292
293         i_maxitems      = 0;
294         do      {
295                 (*pi_abbrevs)++;
296
297                 /* Read Abbrev Number */
298                 pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_size );
299                 dw_abbrev_num   = (DWord)qw_temp;
300
301                 /* Read TAG */
302                 pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_size );
303                 dw_tag  = (DWord)qw_temp;
304                 if( DW_TAG_compile_unit == dw_tag )             {
305                         (*pi_filenum)++;
306                 }
307
308                 /* Read IsChildren */
309                 b_children      = *pb_data++;
310                 qw_size--;
311
312                 i_items = -1;
313                 do      {
314                         i_items++;
315                         /* Read Attribute */
316                         pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_size );
317                         dw_attribute    = (DWord)qw_temp;
318         
319                         /* Read Format */
320                         pb_data = DWARF_Common_DecodeULEB128( &qw_temp, pb_data, &qw_size );
321                         dw_format       = (DWord)qw_temp;
322
323                 }while((0x00 != dw_attribute) && (0x00 != dw_format) && (qw_size > 0) );
324
325                 if( i_maxitems < i_items )      { i_maxitems    = i_items; }
326
327                 /* Skip Byte for Next Compile-Unit Abbrev. */
328                 if( 0x00 == *pb_data )  {
329                         pb_data++;
330                         qw_size--;
331                 }
332
333         }while((qw_size > 0) && (dw_tag != 0x00));
334
335         *pi_maxitems    = i_maxitems;
336         
337         return 0x00;
338 }
339
340
341 /*----------------------------------------------------------------------
342 ----------------------------------------------------------------------*/
343 LIBGOBLIN_DWARF_ABBREV_EXTERN
344 int
345         DWARF_Abbrev_AllocMemory(
346                 LibGoblin_BinaryInfo    *p_binfo )
347 {
348         int             i_result;
349         int             i_maxitems      = 0;
350         int             i_filenums      = 0;
351         int             i_abbrevs       = 0;
352         QWord   qw_size;
353         DWARF_AbbrevEntry       *p_abbrev;
354         LibGoblin_DWARF_DIEValue        *p_dievalue;
355         LibGoblin_BinaryFile    *p_bfile;
356
357         p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
358         assert( NULL != p_bfile );
359         
360         // Count Abbrevs ---
361         i_result        = DWARF_Abbrev_GetItems( &i_filenums, &i_abbrevs, &i_maxitems, &qw_size, p_binfo );
362         if( 0x00 != i_result )  {
363                 return 0x01;
364         }
365
366         // Alloc Abbrev Memory ---
367         p_abbrev        = (DWARF_AbbrevEntry *)malloc( sizeof( DWARF_AbbrevEntry ) * i_abbrevs );
368         if( NULL == p_abbrev )  {
369                 return 0x02;
370         }
371         p_bfile->dwarf.p_abbrev                         = p_abbrev;
372         p_bfile->dwarf.i_abbrevs_alloc          = i_abbrevs;
373         p_bfile->dwarf.i_abbrevs_max            = 0;
374         p_bfile->dwarf.qw_abbrev_unreadsz       = qw_size;
375
376         p_bfile->dwarf.i_objfiles                       = i_filenums;
377
378         // Alloc Abbrev Memory ---
379         p_dievalue      = (LibGoblin_DWARF_DIEValue *)malloc(
380                                                                 sizeof( LibGoblin_DWARF_DIEValue ) * i_maxitems );
381         if( NULL == p_dievalue )        {
382                 return 0x03;
383         }
384         p_bfile->dwarf.i_maxvals        = i_maxitems;
385
386         p_binfo->dwarf.i_maxvals        = i_maxitems;
387         p_binfo->dwarf.p_infoval        = p_dievalue;
388
389         return 0x00;
390 }
391
392
393 /* EOF of drd64_.c ----------------------------------- */