1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
4 for INTEL64(R), AMD64(R)
6 Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
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.
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.
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
31 /* File Info -----------------------------------------------------------
35 ----------------------------------------------------------------------*/
37 #define DRD64_SRC_LIBGOBLIN_DWARF_EXPRESSION
38 #include"drd64_libgoblin.h"
40 /*----------------------------------------------------------------------
41 ----------------------------------------------------------------------*/
42 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
44 DWARF_Expression_ClearValue(
45 LibGoblin_DWARF_Expression *p_exp )
48 LibGoblin_DWARF_Expression *p_next;
50 assert( NULL != p_exp );
53 p_next = p_exp->p_next;
54 memset( p_exp, 0x00, sizeof( LibGoblin_DWARF_Expression ) );
56 p_exp->p_next = p_next;
58 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_NOTEVALUATE;
65 /*----------------------------------------------------------------------
66 ----------------------------------------------------------------------*/
67 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
69 DWARF_Expression_SetDefaultValue(
70 LibGoblin_DWARF_Expression *p_exp,
71 LibGoblin_BinaryInfo *p_binfo )
77 if( NULL == p_binfo ) {
81 p_exp->dw_setdata = LIBGOBLIN_DWARF_REQUEST_NONE;
83 if( LIBGOBLIN_BINFO_TYPE_ELF32 == p_binfo->b_type )
84 { p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_ADDRSIZE ] = 4; }
85 else // LIBGOBLIN_BINFO_TYPE_ELF64
86 { p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_ADDRSIZE ] = 8; }
87 p_exp->dw_setdata |= LIBGOBLIN_DWARF_REQUEST_ADDRSIZE;
93 /*----------------------------------------------------------------------
94 ----------------------------------------------------------------------*/
95 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
97 DWARF_Expression_Evaluate(
98 LibGoblin_DWARF_Expression *p_exp,
110 DWord dw_depth_resume;
121 #define PUSH_DWARF(m,n) \
122 { (m)->t_stack[(m)->dw_depth].value.qw_value = (n); \
123 (m)->t_stack[(m)->dw_depth].b_flag = LIBGOBLIN_DWARF_FLAG_LOCATION; \
125 #define PUSH_DWARF_SIGN(m,n) \
126 { (m)->t_stack[(m)->dw_depth].value.ii_value = (n); \
127 (m)->t_stack[(m)->dw_depth].b_flag \
128 = (LIBGOBLIN_DWARF_FLAG_SIGN | LIBGOBLIN_DWARF_FLAG_LOCATION); \
130 #define POP_DWARF(m) (m)->t_stack[--((m)->dw_depth)].value.qw_value
131 #define POP_DWARF_SIGN(m) (m)->t_stack[--((m)->dw_depth)].value.ii_value
133 // ------------------------
134 if( NULL == p_exp ) {
135 return (LIBGOBLIN_DWARF_STATUS_ERROR | 0x01);
138 if( NULL == pb_data ) {
139 return (LIBGOBLIN_DWARF_STATUS_ERROR | 0x01);
143 return (LIBGOBLIN_DWARF_STATUS_ERROR | 0x02);
146 if( 0 == p_exp->b_dwsize ) { p_exp->b_dwsize = 8; }
148 // ------------------------
149 if( NULL != p_exp->resume.pb_resume ) {
150 // XXX Position Check!!
151 pb_now = p_exp->resume.pb_resume;
152 qw_remain = p_exp->resume.qw_remain;
154 p_exp->resume.pb_resume = NULL;
155 p_exp->resume.qw_remain = 0;
157 else if( LIBGOBLIN_DWARF_STATUS_RETCALL == p_exp->dw_status ) {
158 // XXX Position Check!!
159 if( 0 == p_exp->b_callers )
160 { goto goto_DWARF_Expression_Evaluate_post; }
164 assert( NULL != p_exp->caller[ p_exp->b_callers ].pb_return );
165 pb_now = p_exp->caller[ p_exp->b_callers ].pb_return;
166 qw_remain = p_exp->caller[ p_exp->b_callers ].qw_retremain;
168 p_exp->caller[ p_exp->b_callers ].pb_return = NULL;
169 p_exp->caller[ p_exp->b_callers ].qw_retremain = 0;
173 qw_remain = (QWord)dw_size;
175 if( 0 == p_exp->b_callers ) {
177 memset( &((p_exp)->t_stack), 0x00,
178 sizeof( LibGoblin_DWARF_Expression_Stack ) * LIBGOBLIN_DWARF_EXPRESSION_STACK_DEPTH );
181 qw_value = 0x00000000;
183 p_exp->dw_requested = LIBGOBLIN_DWARF_REQUEST_NONE;
184 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_ERROR;
185 if( LIBGOBLIN_DWARF_REQUEST_NONE != p_exp->dw_setdata )
186 { p_exp->dw_reqsize = 0; }
190 qw_resume = qw_remain;
191 dw_depth_resume = p_exp->dw_depth;
193 b_opcode = *pb_now++;
197 // Constant Opcodes ----
198 case DW_OP_lit0: // 0x30
199 case DW_OP_lit1: // 0x31
200 case DW_OP_lit2: // 0x32
201 case DW_OP_lit3: // 0x33
202 case DW_OP_lit4: // 0x34
203 case DW_OP_lit5: // 0x35
204 case DW_OP_lit6: // 0x36
205 case DW_OP_lit7: // 0x37
206 case DW_OP_lit8: // 0x38
207 case DW_OP_lit9: // 0x39
208 case DW_OP_lit10: // 0x3a
209 case DW_OP_lit11: // 0x3b
210 case DW_OP_lit12: // 0x3c
211 case DW_OP_lit13: // 0x3d
212 case DW_OP_lit14: // 0x3e
213 case DW_OP_lit15: // 0x3f
214 case DW_OP_lit16: // 0x40
215 case DW_OP_lit17: // 0x41
216 case DW_OP_lit18: // 0x42
217 case DW_OP_lit19: // 0x43
218 case DW_OP_lit20: // 0x44
219 case DW_OP_lit21: // 0x45
220 case DW_OP_lit22: // 0x46
221 case DW_OP_lit23: // 0x47
222 case DW_OP_lit24: // 0x48
223 case DW_OP_lit25: // 0x49
224 case DW_OP_lit26: // 0x4a
225 case DW_OP_lit27: // 0x4b
226 case DW_OP_lit28: // 0x4c
227 case DW_OP_lit29: // 0x4d
228 case DW_OP_lit30: // 0x4e
229 case DW_OP_lit31: // 0x4f
230 b_value = b_opcode - DW_OP_lit0;
231 PUSH_DWARF( p_exp, (QWord)b_value );
234 case DW_OP_addr: // 0x03
235 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_ADDRSIZE ) {
236 PUSH_DWARF( p_exp, p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_ADDRSIZE ] );
237 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_ADDRSIZE);
240 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_ADDRSIZE;
241 qw_remain = 0; // for Loop-Break
245 case DW_OP_const1u: // 0x08
247 { goto goto_DWARF_Expression_Evaluate_post; }
248 qw_value = (QWord)*pb_now++;
250 PUSH_DWARF( p_exp, qw_value );
252 case DW_OP_const1s: // 0x09
254 { goto goto_DWARF_Expression_Evaluate_post; }
255 ii_value = (Int64)*((char *)pb_now);
258 PUSH_DWARF_SIGN( p_exp, ii_value );
260 case DW_OP_const2u: // 0x0a
262 { goto goto_DWARF_Expression_Evaluate_post; }
263 qw_value = (QWord)*((Word *)pb_now);
266 PUSH_DWARF( p_exp, qw_value );
268 case DW_OP_const2s: // 0x0b
270 { goto goto_DWARF_Expression_Evaluate_post; }
271 ii_value = (Int64)*((short *)pb_now);
274 PUSH_DWARF_SIGN( p_exp, ii_value );
276 case DW_OP_const4u: // 0x0c
278 { goto goto_DWARF_Expression_Evaluate_post; }
279 qw_value = (QWord)*((DWord *)pb_now);
282 PUSH_DWARF( p_exp, qw_value );
284 case DW_OP_const4s: // 0x0d
286 { goto goto_DWARF_Expression_Evaluate_post; }
287 ii_value = (Int64)*((int *)pb_now);
290 PUSH_DWARF_SIGN( p_exp, ii_value );
292 case DW_OP_const8u: // 0x0e
294 { goto goto_DWARF_Expression_Evaluate_post; }
295 qw_value = (QWord)*((QWord *)pb_now);
298 PUSH_DWARF( p_exp, qw_value );
300 case DW_OP_const8s: // 0x0f
302 { goto goto_DWARF_Expression_Evaluate_post; }
303 ii_value = (Int64)*((Int64 *)pb_now);
306 PUSH_DWARF_SIGN( p_exp, ii_value );
308 case DW_OP_constu: // 0x10
309 pb_now = DWARF_Common_DecodeULEB128( &qw_value, pb_now, &qw_remain );
310 PUSH_DWARF( p_exp, qw_value );
312 case DW_OP_consts: // 0x11
313 pb_now = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
314 PUSH_DWARF_SIGN( p_exp, ii_value );
317 // Register-Base Opcodes ----
318 case DW_OP_fbreg: // 0x91
319 pb_now = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
320 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_FRAME_BASE ) {
323 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_FRAME_BASE ]
324 - (QWord)(-1 * ii_value);
327 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_FRAME_BASE ]
331 PUSH_DWARF( p_exp, qw_value );
332 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_FRAME_BASE);
335 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_FRAME_BASE;
336 qw_remain = 0; // for Loop-Break
339 case DW_OP_breg0: // 0x70
340 case DW_OP_breg1: // 0x71
341 case DW_OP_breg2: // 0x72
342 case DW_OP_breg3: // 0x73
343 case DW_OP_breg4: // 0x74
344 case DW_OP_breg5: // 0x75
345 case DW_OP_breg6: // 0x76
346 case DW_OP_breg7: // 0x77
347 case DW_OP_breg8: // 0x78
348 case DW_OP_breg9: // 0x79
349 case DW_OP_breg10: // 0x7a
350 case DW_OP_breg11: // 0x7b
351 case DW_OP_breg12: // 0x7c
352 case DW_OP_breg13: // 0x7d
353 case DW_OP_breg14: // 0x7e
354 case DW_OP_breg15: // 0x7f
355 case DW_OP_breg16: // 0x80
356 case DW_OP_breg17: // 0x81
357 case DW_OP_breg18: // 0x82
358 case DW_OP_breg19: // 0x83
359 case DW_OP_breg20: // 0x84
360 case DW_OP_breg21: // 0x85
361 case DW_OP_breg22: // 0x86
362 case DW_OP_breg23: // 0x87
363 case DW_OP_breg24: // 0x88
364 case DW_OP_breg25: // 0x89
365 case DW_OP_breg26: // 0x8a
366 case DW_OP_breg27: // 0x8b
367 case DW_OP_breg28: // 0x8c
368 case DW_OP_breg29: // 0x8d
369 case DW_OP_breg30: // 0x8e
370 case DW_OP_breg31: // 0x8f
371 b_reg = b_opcode - DW_OP_breg0;
372 pb_now = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
374 if( p_exp->dw_setdata & (LIBGOBLIN_DWARF_REQUEST_REG | b_reg) ) {
376 { qw_value = p_exp->qw_reqdata[b_reg] - (QWord)(-1 * ii_value); }
378 { qw_value = p_exp->qw_reqdata[b_reg] + (QWord)ii_value; }
380 PUSH_DWARF( p_exp, qw_value );
381 p_exp->dw_setdata &= (~(LIBGOBLIN_DWARF_REQUEST_REG | b_reg));
384 p_exp->dw_requested |= (LIBGOBLIN_DWARF_REQUEST_REG | b_reg);
385 qw_remain = 0; // for Loop-Break
388 case DW_OP_bregx: // 0x92
390 pb_now = DWARF_Common_DecodeULEB128( &qw_value, pb_now, &qw_remain );
391 p_exp->dw_regid = (DWord)(qw_value & 0xffffffff);
394 pb_now = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
396 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_REGX ) {
398 { qw_value = p_exp->qw_reqdata[LIBGOBLIN_DWARF_DATAID_REGX]
399 - (QWord)(-1 * ii_value); }
401 { qw_value = p_exp->qw_reqdata[LIBGOBLIN_DWARF_DATAID_REGX]
404 PUSH_DWARF( p_exp, qw_value );
405 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_REGX);
408 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_REGX;
409 qw_remain = 0; // for Loop-Break
414 // Stack Opcodes ----
415 case DW_OP_dup: // 0x12
416 if( 0 == p_exp->dw_depth )
417 { goto goto_DWARF_Expression_Evaluate_post; }
419 qw_value = p_exp->t_stack[p_exp->dw_depth - 1].value.qw_value;
420 PUSH_DWARF( p_exp, qw_value );
422 case DW_OP_drop: // 0x13
423 if( 0 == p_exp->dw_depth )
424 { goto goto_DWARF_Expression_Evaluate_post; }
425 qw_pop[0] = POP_DWARF( p_exp );
427 case DW_OP_pick: // 0x15
429 { goto goto_DWARF_Expression_Evaluate_post; }
433 if( p_exp->dw_depth <= (DWord)b_value )
434 { goto goto_DWARF_Expression_Evaluate_post; }
436 dw_value = p_exp->dw_depth - (DWord)b_value - 1;
437 qw_value = p_exp->t_stack[dw_value].value.qw_value;
438 PUSH_DWARF( p_exp, qw_value );
440 case DW_OP_over: // 0x14
441 if( 2 > p_exp->dw_depth )
442 { goto goto_DWARF_Expression_Evaluate_post; }
444 dw_value = p_exp->dw_depth - 2;
445 qw_value = p_exp->t_stack[dw_value].value.qw_value;
446 PUSH_DWARF( p_exp, qw_value );
448 case DW_OP_swap: // 0x16
449 if( 2 > p_exp->dw_depth )
450 { goto goto_DWARF_Expression_Evaluate_post; }
451 qw_value = p_exp->t_stack[p_exp->dw_depth - 2].value.qw_value;
452 p_exp->t_stack[p_exp->dw_depth - 2].value.qw_value
453 = p_exp->t_stack[p_exp->dw_depth - 1].value.qw_value;
454 p_exp->t_stack[p_exp->dw_depth - 1].value.qw_value = qw_value;
456 case DW_OP_rot: // 0x17
457 if( 3 > p_exp->dw_depth )
458 { goto goto_DWARF_Expression_Evaluate_post; }
459 qw_value = p_exp->t_stack[p_exp->dw_depth - 1].value.qw_value;
460 p_exp->t_stack[p_exp->dw_depth - 1].value.qw_value
461 = p_exp->t_stack[p_exp->dw_depth - 2].value.qw_value;
462 p_exp->t_stack[p_exp->dw_depth - 2].value.qw_value
463 = p_exp->t_stack[p_exp->dw_depth - 3].value.qw_value;
464 p_exp->t_stack[p_exp->dw_depth - 3].value.qw_value = qw_value;
466 case DW_OP_deref: // 0x06
467 if( 0 == p_exp->dw_depth )
468 { goto goto_DWARF_Expression_Evaluate_post; }
469 qw_pop[0] = POP_DWARF( p_exp );
471 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_DEREF ) {
472 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_DEREF ];
473 PUSH_DWARF( p_exp, qw_value );
474 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_DEREF);
477 p_exp->ptr_reference.value = (PtrValue)qw_pop[0];
478 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_DEREF;
479 qw_remain = 0; // for Loop-Break
482 case DW_OP_deref_size: // 0x94
483 if( 0 == p_exp->dw_depth )
484 { goto goto_DWARF_Expression_Evaluate_post; }
486 { goto goto_DWARF_Expression_Evaluate_post; }
487 qw_pop[0] = POP_DWARF( p_exp );
492 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_DEREF ) {
493 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_DEREF ];
494 PUSH_DWARF( p_exp, qw_value );
495 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_DEREF);
498 p_exp->dw_reqsize = (DWord)b_value;
499 p_exp->ptr_reference.value = (PtrValue)qw_pop[0];
500 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_DEREF;
501 qw_remain = 0; // for Loop-Break
504 case DW_OP_xderef: // 0x18
505 if( 2 > p_exp->dw_depth )
506 { goto goto_DWARF_Expression_Evaluate_post; }
507 qw_pop[0] = POP_DWARF( p_exp );
508 qw_pop[1] = POP_DWARF( p_exp );
510 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_XDEREF ) {
511 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_XDEREF ];
512 PUSH_DWARF( p_exp, qw_value );
513 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_XDEREF);
516 p_exp->ptr_reference.value = (PtrValue)qw_pop[0];
517 p_exp->qw_ident_addrspace = qw_pop[1];
518 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_XDEREF;
519 qw_remain = 0; // for Loop-Break
522 case DW_OP_xderef_size: // 0x95
523 if( 2 > p_exp->dw_depth )
524 { goto goto_DWARF_Expression_Evaluate_post; }
525 qw_pop[0] = POP_DWARF( p_exp );
526 qw_pop[1] = POP_DWARF( p_exp );
531 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_XDEREF ) {
532 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_XDEREF ];
533 PUSH_DWARF( p_exp, qw_value );
534 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_XDEREF);
537 p_exp->dw_reqsize = (DWord)b_value;
538 p_exp->ptr_reference.value = (PtrValue)qw_pop[0];
539 p_exp->qw_ident_addrspace = qw_pop[1];
540 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_XDEREF;
541 qw_remain = 0; // for Loop-Break
544 case DW_OP_push_object_address: // 0x97
545 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_OBJADDR ) {
546 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_OBJADDR ];
547 PUSH_DWARF( p_exp, qw_value );
548 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_OBJADDR);
551 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_OBJADDR;
552 qw_remain = 0; // for Loop-Break
555 case DW_OP_form_tls_address: // 0x9b
556 if( 1 > p_exp->dw_depth )
557 { goto goto_DWARF_Expression_Evaluate_post; }
558 qw_pop[0] = POP_DWARF( p_exp );
560 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_TLSADDR ) {
561 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_TLSADDR ];
562 PUSH_DWARF( p_exp, qw_value );
563 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_TLSADDR);
566 p_exp->ptr_tlsbase.value = (PtrValue)qw_pop[0];
567 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_TLSADDR;
568 qw_remain = 0; // for Loop-Break
571 case DW_OP_call_frame_cfa: // 0x9c
572 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_CFAADDR ) {
573 qw_value = p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_CFAADDR ];
574 PUSH_DWARF( p_exp, qw_value );
575 p_exp->dw_setdata &= (~LIBGOBLIN_DWARF_REQUEST_CFAADDR);
578 p_exp->dw_requested |= LIBGOBLIN_DWARF_REQUEST_CFAADDR;
579 qw_remain = 0; // for Loop-Break
583 // Arithmetic & Logical Operation ----
584 case DW_OP_abs: // 0x19
585 if( 0 == p_exp->dw_depth )
586 { goto goto_DWARF_Expression_Evaluate_post; }
587 ii_value = POP_DWARF_SIGN( p_exp );
589 if( LIBGOBLIN_DWARF_FLAG_SIGN & p_exp->t_stack[p_exp->dw_depth].b_flag ) {
590 if( 0 > ii_value ) { ii_value *= -1; }
591 PUSH_DWARF_SIGN( p_exp, ii_value );
595 case DW_OP_and: // 0x1a
596 if( 2 > p_exp->dw_depth )
597 { goto goto_DWARF_Expression_Evaluate_post; }
599 qw_value = POP_DWARF( p_exp );
600 qw_temp = POP_DWARF( p_exp );
602 PUSH_DWARF( p_exp, qw_value );
605 case DW_OP_div: // 0x1b
606 if( 2 > p_exp->dw_depth )
607 { goto goto_DWARF_Expression_Evaluate_post; }
609 ii_temp = POP_DWARF_SIGN( p_exp );
610 ii_value = POP_DWARF_SIGN( p_exp );
612 { goto goto_DWARF_Expression_Evaluate_post; }
615 PUSH_DWARF_SIGN( p_exp, ii_value );
618 case DW_OP_minus: // 0x1c
619 if( 2 > p_exp->dw_depth )
620 { goto goto_DWARF_Expression_Evaluate_post; }
622 qw_temp = POP_DWARF( p_exp );
623 qw_value = POP_DWARF( p_exp );
625 PUSH_DWARF( p_exp, qw_value );
627 case DW_OP_mod: // 0x1d
628 if( 2 > p_exp->dw_depth )
629 { goto goto_DWARF_Expression_Evaluate_post; }
631 ii_temp = POP_DWARF_SIGN( p_exp );
632 ii_value = POP_DWARF_SIGN( p_exp );
634 { goto goto_DWARF_Expression_Evaluate_post; }
637 PUSH_DWARF_SIGN( p_exp, ii_value );
639 case DW_OP_mul: // 0x1e
640 if( 2 > p_exp->dw_depth )
641 { goto goto_DWARF_Expression_Evaluate_post; }
643 qw_temp = POP_DWARF( p_exp );
644 qw_value = POP_DWARF( p_exp );
646 PUSH_DWARF( p_exp, qw_value );
648 case DW_OP_neg: // 0x1f
649 if( 1 > p_exp->dw_depth )
650 { goto goto_DWARF_Expression_Evaluate_post; }
652 ii_value = POP_DWARF_SIGN( p_exp );
654 PUSH_DWARF_SIGN( p_exp, ii_value );
656 case DW_OP_not: // 0x20
657 if( 1 > p_exp->dw_depth )
658 { goto goto_DWARF_Expression_Evaluate_post; }
660 qw_value = POP_DWARF( p_exp );
661 qw_value = ~qw_value;
662 PUSH_DWARF( p_exp, qw_value );
664 case DW_OP_or: // 0x21
665 if( 2 > p_exp->dw_depth )
666 { goto goto_DWARF_Expression_Evaluate_post; }
668 qw_value = POP_DWARF( p_exp );
669 qw_temp = POP_DWARF( p_exp );
671 PUSH_DWARF( p_exp, qw_value );
673 case DW_OP_plus: // 0x22
674 if( 2 > p_exp->dw_depth )
675 { goto goto_DWARF_Expression_Evaluate_post; }
677 qw_temp = POP_DWARF( p_exp );
678 qw_value = POP_DWARF( p_exp );
680 PUSH_DWARF( p_exp, qw_value );
682 case DW_OP_plus_uconst: // 0x23
683 if( 1 > p_exp->dw_depth )
684 { goto goto_DWARF_Expression_Evaluate_post; }
686 qw_value = POP_DWARF( p_exp );
687 pb_now = DWARF_Common_DecodeULEB128( &qw_temp, pb_now, &qw_remain );
690 PUSH_DWARF( p_exp, qw_value );
692 case DW_OP_shl: // 0x24
693 if( 2 > p_exp->dw_depth )
694 { goto goto_DWARF_Expression_Evaluate_post; }
696 qw_temp = POP_DWARF( p_exp );
697 qw_value = POP_DWARF( p_exp );
698 qw_value <<= qw_temp;
699 PUSH_DWARF( p_exp, qw_value );
701 case DW_OP_shr: // 0x25
702 if( 2 > p_exp->dw_depth )
703 { goto goto_DWARF_Expression_Evaluate_post; }
705 qw_temp = POP_DWARF( p_exp );
706 qw_value = POP_DWARF( p_exp );
707 qw_value >>= qw_temp;
708 PUSH_DWARF( p_exp, qw_value );
710 case DW_OP_shra: // 0x26
711 if( 2 > p_exp->dw_depth )
712 { goto goto_DWARF_Expression_Evaluate_post; }
714 qw_temp = POP_DWARF( p_exp );
715 ii_value = POP_DWARF_SIGN( p_exp );
716 ii_value >>= qw_temp;
717 PUSH_DWARF_SIGN( p_exp, ii_value );
719 case DW_OP_xor: // 0x27
720 if( 2 > p_exp->dw_depth )
721 { goto goto_DWARF_Expression_Evaluate_post; }
723 qw_temp = POP_DWARF( p_exp );
724 qw_value = POP_DWARF( p_exp );
726 PUSH_DWARF( p_exp, qw_value );
729 // Flow Control Operation ----
730 case DW_OP_eq: // 0x29
731 if( 2 > p_exp->dw_depth )
732 { goto goto_DWARF_Expression_Evaluate_post; }
734 ii_temp = POP_DWARF_SIGN( p_exp );
735 ii_value = POP_DWARF_SIGN( p_exp );
736 if( ii_value == ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
737 else { PUSH_DWARF( p_exp, 0x00 ); }
739 case DW_OP_ge: // 0x2a
740 if( 2 > p_exp->dw_depth )
741 { goto goto_DWARF_Expression_Evaluate_post; }
743 ii_temp = POP_DWARF_SIGN( p_exp );
744 ii_value = POP_DWARF_SIGN( p_exp );
745 if( ii_value >= ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
746 else { PUSH_DWARF( p_exp, 0x00 ); }
748 case DW_OP_gt: // 0x2b
749 if( 2 > p_exp->dw_depth )
750 { goto goto_DWARF_Expression_Evaluate_post; }
752 ii_temp = POP_DWARF_SIGN( p_exp );
753 ii_value = POP_DWARF_SIGN( p_exp );
754 if( ii_value > ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
755 else { PUSH_DWARF( p_exp, 0x00 ); }
757 case DW_OP_le: // 0x2c
758 if( 2 > p_exp->dw_depth )
759 { goto goto_DWARF_Expression_Evaluate_post; }
761 ii_temp = POP_DWARF_SIGN( p_exp );
762 ii_value = POP_DWARF_SIGN( p_exp );
763 if( ii_value <= ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
764 else { PUSH_DWARF( p_exp, 0x00 ); }
766 case DW_OP_lt: // 0x2d
767 if( 2 > p_exp->dw_depth )
768 { goto goto_DWARF_Expression_Evaluate_post; }
770 ii_temp = POP_DWARF_SIGN( p_exp );
771 ii_value = POP_DWARF_SIGN( p_exp );
772 if( ii_value < ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
773 else { PUSH_DWARF( p_exp, 0x00 ); }
775 case DW_OP_ne: // 0x2e
776 if( 2 > p_exp->dw_depth )
777 { goto goto_DWARF_Expression_Evaluate_post; }
779 ii_temp = POP_DWARF_SIGN( p_exp );
780 ii_value = POP_DWARF_SIGN( p_exp );
781 if( ii_value != ii_temp ) { PUSH_DWARF( p_exp, 0x01 ); }
782 else { PUSH_DWARF( p_exp, 0x00 ); }
784 case DW_OP_skip: // 0x2f
786 { goto goto_DWARF_Expression_Evaluate_post; }
787 s_value = *((short *)pb_now);
792 pb_now -= (-1 * s_value);
793 qw_remain += (-1 * s_value);
797 qw_remain -= s_value;
800 case DW_OP_bra: // 0x28
802 { goto goto_DWARF_Expression_Evaluate_post; }
803 qw_temp = POP_DWARF( p_exp );
805 s_value = *((short *)pb_now);
811 pb_now -= (-1 * s_value);
812 qw_remain += (-1 * s_value);
816 qw_remain -= s_value;
821 case DW_OP_call2: // 0x98
823 { goto goto_DWARF_Expression_Evaluate_post; }
824 w_value = *((Word *)pb_now);
828 p_exp->qw_calloffset = (QWord)w_value;
829 p_exp->caller[ p_exp->b_callers ].pb_return = pb_now;
830 p_exp->caller[ p_exp->b_callers ].qw_retremain = qw_remain;
832 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_CALLING;
834 goto goto_DWARF_Expression_Evaluate_post;
836 case DW_OP_call4: // 0x99
838 { goto goto_DWARF_Expression_Evaluate_post; }
839 dw_value = *((DWord *)pb_now);
843 p_exp->qw_calloffset = (QWord)dw_value;
844 p_exp->caller[ p_exp->b_callers ].pb_return = pb_now;
845 p_exp->caller[ p_exp->b_callers ].qw_retremain = qw_remain;
847 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_CALLING;
849 goto goto_DWARF_Expression_Evaluate_post;
851 case DW_OP_call_ref: // 0x9a
852 if( p_exp->b_dwsize > qw_remain )
853 { goto goto_DWARF_Expression_Evaluate_post; }
854 if( 8 == p_exp->b_dwsize ) { qw_value = *((QWord *)pb_now); }
855 else { qw_value = (QWord)(*((DWord *)pb_now)); }
856 pb_now += p_exp->b_dwsize;
857 qw_remain -= p_exp->b_dwsize;
859 p_exp->qw_calloffset = qw_value;
860 p_exp->caller[ p_exp->b_callers ].pb_return = pb_now;
861 p_exp->caller[ p_exp->b_callers ].qw_retremain = qw_remain;
863 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_CALLING;
865 goto goto_DWARF_Expression_Evaluate_post;
868 // Special Operation ----
869 case DW_OP_nop: // 0x96
874 case DW_OP_reg0: // 0x50
875 case DW_OP_reg1: // 0x51
876 case DW_OP_reg2: // 0x52
877 case DW_OP_reg3: // 0x53
878 case DW_OP_reg4: // 0x54
879 case DW_OP_reg5: // 0x55
880 case DW_OP_reg6: // 0x56
881 case DW_OP_reg7: // 0x57
882 case DW_OP_reg8: // 0x58
883 case DW_OP_reg9: // 0x59
884 case DW_OP_reg10: // 0x5a
885 case DW_OP_reg11: // 0x5b
886 case DW_OP_reg12: // 0x5c
887 case DW_OP_reg13: // 0x5d
888 case DW_OP_reg14: // 0x5e
889 case DW_OP_reg15: // 0x5f
890 case DW_OP_reg16: // 0x60
891 case DW_OP_reg17: // 0x61
892 case DW_OP_reg18: // 0x62
893 case DW_OP_reg19: // 0x63
894 case DW_OP_reg20: // 0x64
895 case DW_OP_reg21: // 0x65
896 case DW_OP_reg22: // 0x66
897 case DW_OP_reg23: // 0x67
898 case DW_OP_reg24: // 0x68
899 case DW_OP_reg25: // 0x69
900 case DW_OP_reg26: // 0x6a
901 case DW_OP_reg27: // 0x6b
902 case DW_OP_reg28: // 0x6c
903 case DW_OP_reg29: // 0x6d
904 case DW_OP_reg30: // 0x6e
905 case DW_OP_reg31: // 0x6f
907 b_reg = b_opcode - DW_OP_reg0;
908 p_exp->result[ p_exp->b_results ].b_type = b_reg;
909 p_exp->result[ p_exp->b_results ].value.qw_value = b_reg; // reg.id
910 //p_exp->b_results++;
912 case DW_OP_regx: // 0x90
914 pb_now = DWARF_Common_DecodeULEB128( &qw_temp, pb_now, &qw_remain );
915 p_exp->result[ p_exp->b_results ].b_type = LIBGOBLIN_DWARF_FLAG_REGX;
916 p_exp->result[ p_exp->b_results ].value.qw_value = qw_temp; // reg.id
917 //p_exp->b_results++;
920 case DW_OP_piece: // 0x93
922 pb_now = DWARF_Common_DecodeULEB128( &qw_temp, pb_now, &qw_remain );
923 dw_value = (DWord)(qw_temp & 0xffffffff);
925 b_value = p_exp->result[ p_exp->b_results ].b_type;
926 if( !(LIBGOBLIN_DWARF_FLAG_REG & b_value)
927 && !(LIBGOBLIN_DWARF_FLAG_REGX & b_value)) {
928 if( 0 < p_exp->dw_depth ) {
929 p_exp->result[p_exp->b_results].b_type
930 = p_exp->t_stack[ p_exp->dw_depth - 1 ].b_flag;
931 p_exp->result[p_exp->b_results].value.qw_value
932 = p_exp->t_stack[ p_exp->dw_depth - 1 ].value.qw_value;
935 p_exp->result[p_exp->b_results].dw_bytes = dw_value;
939 case DW_OP_bit_piece: // 0x9d
941 // 1st Operand: bit size
942 pb_now = DWARF_Common_DecodeULEB128( &qw_temp, pb_now, &qw_remain );
943 // 2nd Operand: bit offset from prev-bit-piece (under-bits)
944 pb_now = DWARF_Common_DecodeULEB128( &qw_value, pb_now, &qw_remain );
945 dw_bitoffset += (DWord)(qw_value & 0xffffffff);
947 b_value = p_exp->result[ p_exp->b_results ].b_type;
948 if( (LIBGOBLIN_DWARF_FLAG_REG & b_value)
949 || (LIBGOBLIN_DWARF_FLAG_REGX & b_value) ) {
951 p_exp->result[ p_exp->b_results ].dw_bit_offset = dw_bitoffset;
952 p_exp->result[ p_exp->b_results ].dw_bit_size = (DWord)(qw_temp & 0xffffffff);
953 p_exp->result[p_exp->b_results].dw_bytes = 0;
956 else if( 0 < p_exp->dw_depth ) {
957 p_exp->result[p_exp->b_results].b_type
958 = p_exp->t_stack[ p_exp->dw_depth - 1 ].b_flag;
959 p_exp->result[p_exp->b_results].value.qw_value
960 = p_exp->t_stack[ p_exp->dw_depth - 1 ].value.qw_value;
962 p_exp->result[ p_exp->b_results ].dw_bit_offset = dw_bitoffset;
963 p_exp->result[ p_exp->b_results ].dw_bit_size = (DWord)(qw_temp & 0xffffffff);
964 p_exp->result[p_exp->b_results].dw_bytes = 0;
968 case DW_OP_implicit_value: // 0x9e
970 case DW_OP_stack_value: // 0x9f
972 // case DW_OP_lo_user: // 0xe0
974 // case DW_OP_hi_user: // 0xff
976 case DW_OP_GNU_push_tls_address: // 0xe0
978 case DW_OP_GNU_uninit: // 0xf0
980 case DW_OP_GNU_encoded_addr: // 0xf1
982 case DW_OP_GNU_implicit_pointer: // 0xf2
984 case DW_OP_GNU_entry_value: // 0xf3
986 case DW_OP_GNU_const_type: // 0xf4
988 case DW_OP_GNU_regval_type: // 0xf5
990 case DW_OP_GNU_deref_type: // 0xf6
992 case DW_OP_GNU_convert: // 0xf7
994 case DW_OP_GNU_reinterpret: // 0xf9
996 case DW_OP_GNU_parameter_ref: // 0xfa
998 case DW_OP_GNU_addr_index: // 0xfb
1000 case DW_OP_GNU_const_index: // 0xfc
1006 }while( 0 < qw_remain );
1008 if( LIBGOBLIN_DWARF_REQUEST_NONE != p_exp->dw_requested ) {
1009 if( 0 == p_exp->dw_reqsize ) {
1010 if( p_exp->dw_setdata & LIBGOBLIN_DWARF_REQUEST_ADDRSIZE )
1011 { p_exp->dw_reqsize = (DWord)p_exp->qw_reqdata[ LIBGOBLIN_DWARF_DATAID_ADDRSIZE ]; }
1012 else { p_exp->dw_reqsize = 8; }
1014 p_exp->resume.pb_resume = pb_resume;
1015 p_exp->resume.qw_remain = qw_resume;
1016 p_exp->dw_depth = dw_depth_resume;
1017 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_REQUESTED;
1018 goto goto_DWARF_Expression_Evaluate_post;
1021 if( 0 < p_exp->b_callers ) {
1022 assert( NULL != p_exp->caller[ p_exp->b_callers - 1 ].pb_return );
1023 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_RETCALL;
1024 goto goto_DWARF_Expression_Evaluate_post;
1027 if( 0 < p_exp->dw_depth ) {
1028 p_exp->dw_status = LIBGOBLIN_DWARF_STATUS_EVALUATED;
1029 p_exp->result[p_exp->b_results].b_type
1030 = p_exp->t_stack[ p_exp->dw_depth - 1 ].b_flag;
1031 p_exp->result[p_exp->b_results].value.qw_value
1032 = p_exp->t_stack[ p_exp->dw_depth - 1 ].value.qw_value;
1036 goto_DWARF_Expression_Evaluate_post:
1037 return p_exp->dw_status;
1041 /*----------------------------------------------------------------------
1042 ----------------------------------------------------------------------*/
1043 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
1044 LibGoblin_DWARF_Expression *
1045 DWARF_Expression_Alloc(
1049 LibGoblin_DWARF_Expression *p_exp;
1051 if( NULL == gp_dweempty ) {
1055 p_exp = gp_dweempty;
1056 gp_dweempty = p_exp->p_next;
1059 memset( p_exp, 0x00, sizeof( LibGoblin_DWARF_Expression ) );
1061 p_exp->p_next = NULL;
1067 /*----------------------------------------------------------------------
1068 ----------------------------------------------------------------------*/
1069 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
1071 DWARF_Expression_Free(
1072 LibGoblin_DWARF_Expression *p_exp )
1074 LibGoblin_DWARF_Expression *p_next;
1076 if( NULL == p_exp ) {
1080 assert( NULL == p_exp->p_next );
1082 p_next = gp_dweempty;
1083 gp_dweempty = p_exp;
1084 p_exp->p_next = p_next;
1090 /*----------------------------------------------------------------------
1091 ----------------------------------------------------------------------*/
1092 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
1094 DWARF_Expression_Init(
1099 LibGoblin_DWARF_Expression *p_exp;
1101 if( NULL != gp_dwexpression ) {
1105 dw_size = sizeof( LibGoblin_DWARF_Expression )
1106 * LIBGOBLIN_DWARF_EXPRESSION_UNITS;
1107 gp_dwexpression = (LibGoblin_DWARF_Expression *)malloc( dw_size );
1108 if( NULL == gp_dwexpression ) {
1111 memset( gp_dwexpression, 0x00, dw_size );
1113 for( i_cnt = 0; i_cnt < LIBGOBLIN_DWARF_EXPRESSION_UNITS; i_cnt++ ) {
1114 p_exp = gp_dwexpression + i_cnt;
1115 p_exp->i_id = i_cnt;
1116 p_exp->p_next = gp_dwexpression + i_cnt + 1;
1118 p_exp->p_next = NULL;
1120 gp_dweempty = gp_dwexpression;
1126 /*----------------------------------------------------------------------
1127 ----------------------------------------------------------------------*/
1128 LIBGOBLIN_DWARF_EXPRESSION_EXTERN
1130 DWARF_Expression_Term(
1133 assert( NULL != gp_dwexpression );
1134 free( gp_dwexpression );
1136 gp_dwexpression = NULL;
1142 /* EOF of drd64_.c ----------------------------------- */