OSDN Git Service

(LibGoblin)
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 1 Sep 2019 13:23:50 +0000 (22:23 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 1 Sep 2019 13:23:50 +0000 (22:23 +0900)
  * WorkBackup

libgoblin/drd64_libgoblin_dwarf_expression.c
libgoblin/drd64_libgoblin_type_dwarf.h
libgoblin/test_libgoblin_dwarf_expression.c

index 0cb6e3a..050a43d 100644 (file)
@@ -89,6 +89,8 @@ DWord
                        DWord   dw_size )
 {
        Byte    b_opcode;
+       Byte    b_value;
+       Byte    b_reg;
        Byte    *pb_now;
        QWord   qw_remain;
        DWord   dw_depth;
@@ -254,69 +256,40 @@ DWord
                                break;
 
                        case DW_OP_lit0:                                // 0x30
-                               PUSH_DWARF(  0 );       break;
                        case DW_OP_lit1:                                // 0x31
-                               PUSH_DWARF(  1 );       break;
                        case DW_OP_lit2:                                // 0x32
-                               PUSH_DWARF(  2 );       break;
                        case DW_OP_lit3:                                // 0x33
-                               PUSH_DWARF(  3 );       break;
                        case DW_OP_lit4:                                // 0x34
-                               PUSH_DWARF(  4 );       break;
                        case DW_OP_lit5:                                // 0x35
-                               PUSH_DWARF(  5 );       break;
                        case DW_OP_lit6:                                // 0x36
-                               PUSH_DWARF(  6 );       break;
                        case DW_OP_lit7:                                // 0x37
-                               PUSH_DWARF(  7 );       break;
                        case DW_OP_lit8:                                // 0x38
-                               PUSH_DWARF(  8 );       break;
                        case DW_OP_lit9:                                // 0x39
-                               PUSH_DWARF(  9 );       break;
                        case DW_OP_lit10:                               // 0x3a
-                               PUSH_DWARF( 10 );       break;
                        case DW_OP_lit11:                               // 0x3b
-                               PUSH_DWARF( 11 );       break;
                        case DW_OP_lit12:                               // 0x3c
-                               PUSH_DWARF( 12 );       break;
                        case DW_OP_lit13:                               // 0x3d
-                               PUSH_DWARF( 13 );       break;
                        case DW_OP_lit14:                               // 0x3e
-                               PUSH_DWARF( 14 );       break;
                        case DW_OP_lit15:                               // 0x3f
-                               PUSH_DWARF( 15 );       break;
                        case DW_OP_lit16:                               // 0x40
-                               PUSH_DWARF( 16 );       break;
                        case DW_OP_lit17:                               // 0x41
-                               PUSH_DWARF( 17 );       break;
                        case DW_OP_lit18:                               // 0x42
-                               PUSH_DWARF( 18 );       break;
                        case DW_OP_lit19:                               // 0x43
-                               PUSH_DWARF( 19 );       break;
                        case DW_OP_lit20:                               // 0x44
-                               PUSH_DWARF( 20 );       break;
                        case DW_OP_lit21:                               // 0x45
-                               PUSH_DWARF( 21 );       break;
                        case DW_OP_lit22:                               // 0x46
-                               PUSH_DWARF( 22 );       break;
                        case DW_OP_lit23:                               // 0x47
-                               PUSH_DWARF( 23 );       break;
                        case DW_OP_lit24:                               // 0x48
-                               PUSH_DWARF( 24 );       break;
                        case DW_OP_lit25:                               // 0x49
-                               PUSH_DWARF( 25 );       break;
                        case DW_OP_lit26:                               // 0x4a
-                               PUSH_DWARF( 26 );       break;
                        case DW_OP_lit27:                               // 0x4b
-                               PUSH_DWARF( 27 );       break;
                        case DW_OP_lit28:                               // 0x4c
-                               PUSH_DWARF( 28 );       break;
                        case DW_OP_lit29:                               // 0x4d
-                               PUSH_DWARF( 29 );       break;
                        case DW_OP_lit30:                               // 0x4e
-                               PUSH_DWARF( 30 );       break;
                        case DW_OP_lit31:                               // 0x4f
-                               PUSH_DWARF( 31 );       break;
+                               b_value = b_opcode - DW_OP_lit0;
+                               PUSH_DWARF( (QWord)b_value );
+                               break;
 
                        case DW_OP_reg0:                                // 0x50
                                break;
@@ -382,73 +355,70 @@ DWord
                                break;
                        case DW_OP_reg31:                               // 0x6f
                                break;
+
                        case DW_OP_breg0:                               // 0x70
-                               break;
                        case DW_OP_breg1:                               // 0x71
-                               break;
                        case DW_OP_breg2:                               // 0x72
-                               break;
                        case DW_OP_breg3:                               // 0x73
-                               break;
                        case DW_OP_breg4:                               // 0x74
-                               break;
                        case DW_OP_breg5:                               // 0x75
-                               break;
                        case DW_OP_breg6:                               // 0x76
-                               break;
                        case DW_OP_breg7:                               // 0x77
-                               break;
                        case DW_OP_breg8:                               // 0x78
-                               break;
                        case DW_OP_breg9:                               // 0x79
-                               break;
                        case DW_OP_breg10:                              // 0x7a
-                               break;
                        case DW_OP_breg11:                              // 0x7b
-                               break;
                        case DW_OP_breg12:                              // 0x7c
-                               break;
                        case DW_OP_breg13:                              // 0x7d
-                               break;
                        case DW_OP_breg14:                              // 0x7e
-                               break;
                        case DW_OP_breg15:                              // 0x7f
-                               break;
                        case DW_OP_breg16:                              // 0x80
-                               break;
                        case DW_OP_breg17:                              // 0x81
-                               break;
                        case DW_OP_breg18:                              // 0x82
-                               break;
                        case DW_OP_breg19:                              // 0x83
-                               break;
                        case DW_OP_breg20:                              // 0x84
-                               break;
                        case DW_OP_breg21:                              // 0x85
-                               break;
                        case DW_OP_breg22:                              // 0x86
-                               break;
                        case DW_OP_breg23:                              // 0x87
-                               break;
                        case DW_OP_breg24:                              // 0x88
-                               break;
                        case DW_OP_breg25:                              // 0x89
-                               break;
                        case DW_OP_breg26:                              // 0x8a
-                               break;
                        case DW_OP_breg27:                              // 0x8b
-                               break;
                        case DW_OP_breg28:                              // 0x8c
-                               break;
                        case DW_OP_breg29:                              // 0x8d
-                               break;
                        case DW_OP_breg30:                              // 0x8e
-                               break;
                        case DW_OP_breg31:                              // 0x8f
+                               b_reg   = b_opcode - DW_OP_breg0;
+                               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_regx:                                // 0x90
                                break;
                        case DW_OP_fbreg:                               // 0x91
+                               pb_now  = DWARF_Common_DecodeLEB128( &ii_value, pb_now, &qw_remain );
+                               if( p_exp->dw_setdata & LIBGOBLIN_DWARF_DATA_FRAME_BASE )       {
+
+                                       if( 0 > ii_value )
+                                               { qw_value      = p_exp->qw_frame_base - (QWord)(-1 * ii_value); }
+                                       else
+                                               { qw_value      = p_exp->qw_frame_base + (QWord)ii_value; }
+
+                                       PUSH_DWARF( qw_value );
+                               }
+                               else
+                                       { p_exp->dw_requested |= LIBGOBLIN_DWARF_DATA_FRAME_BASE; }
+
                                break;
                        case DW_OP_bregx:                               // 0x92
                                break;
index e5a08e2..6f0405a 100644 (file)
@@ -44,8 +44,11 @@ Comment:
 #define        LIBGOBLIN_DWARF_STATUS_REQUESTED        0x01
 #define        LIBGOBLIN_DWARF_STATUS_ERROR            0x10
 
-#define        LIBGOBLIN_DWARF_DATA_NONE                       0x00
-#define        LIBGOBLIN_DWARF_DATA_ADDRSIZE           0x01
+// bit 4-0 is REG num. (MASK: 0x1f)
+#define        LIBGOBLIN_DWARF_DATA_NONE                       0x00000000
+#define        LIBGOBLIN_DWARF_DATA_REG                        0x00000100
+#define        LIBGOBLIN_DWARF_DATA_ADDRSIZE           0x00000200
+#define        LIBGOBLIN_DWARF_DATA_FRAME_BASE         0x00000400
 
 /*=====================================================================*/
 #define        LIBGOBLIN_DWARF_STACK_SIGN      0x01
@@ -69,7 +72,9 @@ typedef       struct  {
                Int64   ii_value;
        } result;
 
+       QWord   qw_reg[32];             // for DW_OP_bregX
        DWord   dw_addrsize;    // for DW_OP_addr
+       QWord   qw_frame_base;  // for DW_OP_fbreg (value is DW_AT_frame_base)
 } LibGoblin_DWARF_Expression;
 
 /*=====================================================================*/
index 17de78d..4152ecc 100644 (file)
@@ -267,6 +267,125 @@ void Test_LibGoblin_DWARF_Expression_Constant_test00_001( void )
 }
 
 
+/*--------------------------------------------------------------------*/
+void Test_LibGoblin_DWARF_Expression_RegBase_bregX( Byte b_opcode )
+{
+       Byte    b_reg;
+       Byte    b_data[16];
+       DWord   dw_result;
+       LibGoblin_DWARF_Expression      t_exp;
+       
+       b_reg   = b_opcode - DW_OP_breg0;
+
+       b_data[0]       = b_opcode;
+       b_data[1]       = 0x81;
+       b_data[2]       = 0x01;         // value = 129 (0x81 0x01)
+       DWARF_Expression_ClearValue( &t_exp );
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_REQUESTED,
+                               (LIBGOBLIN_DWARF_DATA_REG | b_reg), LIBGOBLIN_DWARF_DATA_NONE );
+
+       t_exp.qw_reg[b_reg]     = 0x80000000;
+       t_exp.dw_setdata        |= (LIBGOBLIN_DWARF_DATA_REG | b_reg);
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_EVALUATED,
+                               LIBGOBLIN_DWARF_DATA_NONE, (LIBGOBLIN_DWARF_DATA_REG | b_reg) );
+       CU_ASSERT( t_exp.result.qw_value == (0x80000000 + 129) );
+
+
+       b_data[0]       = b_opcode;
+       b_data[1]       = 0xff;
+       b_data[2]       = 0x7e;         // value = -129 (0xff 0x7e)
+       DWARF_Expression_ClearValue( &t_exp );
+       t_exp.qw_reg[b_reg]     = 0x80000000;
+       t_exp.dw_setdata        |= (LIBGOBLIN_DWARF_DATA_REG | b_reg);
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_EVALUATED,
+                               LIBGOBLIN_DWARF_DATA_NONE, (LIBGOBLIN_DWARF_DATA_REG | b_reg) );
+       CU_ASSERT( t_exp.result.qw_value == (0x80000000 - 129) );
+
+       return;
+}
+
+
+void Test_LibGoblin_DWARF_Expression_RegBase_test01_001( void )
+{
+       Byte    b_data[16];
+       DWord   dw_result;
+       LibGoblin_DWARF_Expression      t_exp;
+
+       // DW_OP_fbreg --------------
+       b_data[0]       = DW_OP_fbreg;
+       b_data[1]       = 0x81;
+       b_data[2]       = 0x01;         // value = 129 (0x81 0x01)
+       DWARF_Expression_ClearValue( &t_exp );
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_REQUESTED,
+                               LIBGOBLIN_DWARF_DATA_FRAME_BASE, LIBGOBLIN_DWARF_DATA_NONE );
+
+       t_exp.qw_frame_base     = 0x80000000;
+       t_exp.dw_setdata        |= LIBGOBLIN_DWARF_DATA_FRAME_BASE;
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_EVALUATED,
+                               LIBGOBLIN_DWARF_DATA_NONE, LIBGOBLIN_DWARF_DATA_FRAME_BASE );
+       CU_ASSERT( t_exp.result.qw_value == (0x80000000 + 129) );
+
+
+       b_data[0]       = DW_OP_fbreg;
+       b_data[1]       = 0xff;
+       b_data[2]       = 0x7e;         // value = -129 (0xff 0x7e)
+       DWARF_Expression_ClearValue( &t_exp );
+       t_exp.qw_frame_base     = 0x80000000;
+       t_exp.dw_setdata        |= LIBGOBLIN_DWARF_DATA_FRAME_BASE;
+       dw_result       = DWARF_Expression_Evaluate( &t_exp, b_data, 3 );
+       Test_LibGoblin_DWARF_Expression_CheckStruct( &t_exp,
+                               LIBGOBLIN_DWARF_STATUS_EVALUATED,
+                               LIBGOBLIN_DWARF_DATA_NONE, LIBGOBLIN_DWARF_DATA_FRAME_BASE );
+       CU_ASSERT( t_exp.result.qw_value == (0x80000000 - 129) );
+
+
+       // DW_OP_bregX --------------
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg0 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg1 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg2 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg3 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg4 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg5 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg6 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg7 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg8 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg9 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg10 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg11 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg12 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg13 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg14 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg15 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg16 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg17 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg18 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg19 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg20 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg21 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg22 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg23 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg24 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg25 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg26 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg27 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg28 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg29 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg30 );
+       Test_LibGoblin_DWARF_Expression_RegBase_bregX( DW_OP_breg31 );
+
+       return;
+}
+
 /*----------------------------------------------------------------------
 ----------------------------------------------------------------------*/
 DRD64_TEST_LIBGOBLIN_DWARF_EXPRESSION_EXTERN
@@ -280,6 +399,8 @@ int
 
        CU_add_test( pt_goblin, "LibGoblin_DWARF_Expression_Constant_test00_001",
                                                                 Test_LibGoblin_DWARF_Expression_Constant_test00_001 );
+       CU_add_test( pt_goblin, "LibGoblin_DWARF_Expression_RegBase_test01_001",
+                                                                Test_LibGoblin_DWARF_Expression_RegBase_test01_001 );
 
 
        return 0x00;