OSDN Git Service

(LibGoblin)
authorKoine Yuusuke <koinec@users.osdn.me>
Mon, 2 Sep 2019 03:47:56 +0000 (12:47 +0900)
committerKoine Yuusuke <koinec@users.osdn.me>
Mon, 2 Sep 2019 03:47:56 +0000 (12:47 +0900)
  * Implement: DW_OP_bregx/dup/drop/over/pick
      (NON-Tested!!)

libgoblin/drd64_libgoblin_dwarf_expression.c

index 050a43d..dafd3c2 100644 (file)
@@ -104,6 +104,7 @@ DWord
                { t_stack[dw_depth].value.ii_value = (n); \
                  t_stack[dw_depth].b_flag = LIBGOBLIN_DWARF_STACK_SIGN; \
                  dw_depth++; } 
+#define        POP_DWARF()             t_stack[dw_depth--].value.qw_value 
 
        // ------------------------
        if( NULL == p_exp )     {
@@ -121,6 +122,7 @@ DWord
        qw_value                                = 0x00000000;
        p_exp->result.qw_value  = 0x00000000;
        p_exp->dw_requested             = LIBGOBLIN_DWARF_DATA_NONE;
+       p_exp->dw_status                        = LIBGOBLIN_DWARF_STATUS_ERROR;
 
        memset( &t_stack, 0x00,
                sizeof( LibGoblin_DWARF_Expression_Stack ) * LIBGOBLIN_DWARF_EXPRESSION_STACK_DEPTH );
@@ -195,12 +197,34 @@ DWord
                                break;
 
                        case DW_OP_dup:                                 // 0x12
+                               // 2019/09/02 Lunch-Coding (Required TEST!!)
+                               qw_value        = t_stack[dw_depth].value.qw_value;
+                               PUSH_DWARF( qw_value );
                                break;
                        case DW_OP_drop:                                // 0x13
+                               // 2019/09/02 Lunch-Coding (Required TEST!!)
+                               qw_value        = POP_DWARF();
                                break;
                        case DW_OP_over:                                // 0x14
+                               // 2019/09/02 Lunch-Coding (Required TEST!!)
+                               if( dw_depth < 1 )
+                                       { goto  goto_DWARF_Expression_Evaluate_post; }
+
+                               dw_value        = dw_depth - (DWord)1;
+                               qw_value        = t_stack[dw_value].value.qw_value;
+                               PUSH_DWARF( qw_value );
                                break;
                        case DW_OP_pick:                                // 0x15
+                               // 2019/09/02 Lunch-Coding (Required TEST!!)
+                               b_value = *pb_now++
+                               qw_remain--;
+
+                               if( dw_depth < (DWord)b_value )
+                                       { goto  goto_DWARF_Expression_Evaluate_post; }
+
+                               dw_value        = dw_depth - (DWord)b_value;
+                               qw_value        = t_stack[dw_value].value.qw_value;
+                               PUSH_DWARF( qw_value );
                                break;
                        case DW_OP_swap:                                // 0x16
                                break;
@@ -421,6 +445,24 @@ DWord
 
                                break;
                        case DW_OP_bregx:                               // 0x92
+                               // 2019/09/02 Lunch-Coding (Required TEST!!)
+                               // Get RegID
+                               pb_now  = DWARF_Common_DecodeULEB128( &qw_value, pb_now, &qw_remain );
+                               b_reg   = (Byte)(qw_value & 0x1f);
+
+                               // Get Offset
+                               pb_now  = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
+
+                               if( p_exp->dw_setdata & (LIBGOBLIN_DWARF_DATA_REG | b_reg) )    {
+                                       if( 0 > ii_value )
+                                               { qw_value      = p_exp->qw_reg[b_reg] - (QWord)(-1 * ii_value); }
+                                       else
+                                               { qw_value      = p_exp->qw_reg[b_reg] + (QWord)ii_value; }
+
+                                       PUSH_DWARF( qw_value );
+                               }
+                               else
+                                       { p_exp->dw_requested |= (LIBGOBLIN_DWARF_DATA_REG | b_reg); }
                                break;
                        case DW_OP_piece:                               // 0x93
                                break;
@@ -491,6 +533,7 @@ DWord
                p_exp->result.qw_value  = t_stack[ 0 ].value.qw_value;
        }
 
+goto_DWARF_Expression_Evaluate_post:
        return p_exp->dw_status;
 }