@@ -904,6 +904,52 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
904
904
object_address_ptr, result, error_ptr);
905
905
}
906
906
907
+ namespace {
908
+ // / The location description kinds described by the DWARF v5
909
+ // / specification. Composite locations are handled out-of-band and
910
+ // / thus aren't part of the enum.
911
+ enum LocationDescriptionKind {
912
+ Empty,
913
+ Memory,
914
+ Register,
915
+ Implicit
916
+ /* Composite*/
917
+ };
918
+ // / Adjust value's ValueType according to the kind of location description.
919
+ void UpdateValueTypeFromLocationDescription (Log *log, const DWARFUnit *dwarf_cu,
920
+ LocationDescriptionKind kind,
921
+ Value *value = nullptr ) {
922
+ // Note that this function is conflating DWARF expressions with
923
+ // DWARF location descriptions. Perhaps it would be better to define
924
+ // a wrapper for DWARFExpresssion::Eval() that deals with DWARF
925
+ // location descriptions (which consist of one or more DWARF
926
+ // expressions). But doing this would mean we'd also need factor the
927
+ // handling of DW_OP_(bit_)piece out of this function.
928
+ if (dwarf_cu && dwarf_cu->GetVersion () >= 4 ) {
929
+ const char *log_msg = " DWARF location description kind: %s" ;
930
+ switch (kind) {
931
+ case Empty:
932
+ LLDB_LOGF (log , log_msg, " Empty" );
933
+ break ;
934
+ case Memory:
935
+ LLDB_LOGF (log , log_msg, " Memory" );
936
+ if (value->GetValueType () == Value::ValueType::Scalar)
937
+ value->SetValueType (Value::ValueType::LoadAddress);
938
+ break ;
939
+ case Register:
940
+ LLDB_LOGF (log , log_msg, " Register" );
941
+ value->SetValueType (Value::ValueType::Scalar);
942
+ break ;
943
+ case Implicit:
944
+ LLDB_LOGF (log , log_msg, " Implicit" );
945
+ if (value->GetValueType () == Value::ValueType::LoadAddress)
946
+ value->SetValueType (Value::ValueType::Scalar);
947
+ break ;
948
+ }
949
+ }
950
+ }
951
+ } // namespace
952
+
907
953
bool DWARFExpression::Evaluate (
908
954
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
909
955
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
@@ -952,6 +998,11 @@ bool DWARFExpression::Evaluate(
952
998
!is_signed));
953
999
};
954
1000
1001
+ // The default kind is a memory location. This is updated by any
1002
+ // operation that changes this, such as DW_OP_stack_value, and reset
1003
+ // by composition operations like DW_OP_piece.
1004
+ LocationDescriptionKind dwarf4_location_description_kind = Memory;
1005
+
955
1006
while (opcodes.ValidOffset (offset)) {
956
1007
const lldb::offset_t op_offset = offset;
957
1008
const uint8_t op = opcodes.GetU8 (&offset);
@@ -1950,6 +2001,7 @@ bool DWARFExpression::Evaluate(
1950
2001
case DW_OP_reg29:
1951
2002
case DW_OP_reg30:
1952
2003
case DW_OP_reg31: {
2004
+ dwarf4_location_description_kind = Register;
1953
2005
reg_num = op - DW_OP_reg0;
1954
2006
1955
2007
if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
@@ -1962,6 +2014,7 @@ bool DWARFExpression::Evaluate(
1962
2014
// ULEB128 literal operand that encodes the register.
1963
2015
// DESCRIPTION: Push the value in register on the top of the stack.
1964
2016
case DW_OP_regx: {
2017
+ dwarf4_location_description_kind = Register;
1965
2018
reg_num = opcodes.GetULEB128 (&offset);
1966
2019
if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
1967
2020
stack.push_back (tmp);
@@ -2085,12 +2138,18 @@ bool DWARFExpression::Evaluate(
2085
2138
// provides a way of describing how large a part of a variable a particular
2086
2139
// DWARF expression refers to.
2087
2140
case DW_OP_piece: {
2141
+ LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
2142
+ // Reset for the next piece.
2143
+ dwarf4_location_description_kind = Memory;
2144
+
2088
2145
const uint64_t piece_byte_size = opcodes.GetULEB128 (&offset);
2089
2146
2090
2147
if (piece_byte_size > 0 ) {
2091
2148
Value curr_piece;
2092
2149
2093
2150
if (stack.empty ()) {
2151
+ UpdateValueTypeFromLocationDescription (
2152
+ log , dwarf_cu, LocationDescriptionKind::Empty);
2094
2153
// In a multi-piece expression, this means that the current piece is
2095
2154
// not available. Fill with zeros for now by resizing the data and
2096
2155
// appending it
@@ -2106,6 +2165,8 @@ bool DWARFExpression::Evaluate(
2106
2165
// Extract the current piece into "curr_piece"
2107
2166
Value curr_piece_source_value (stack.back ());
2108
2167
stack.pop_back ();
2168
+ UpdateValueTypeFromLocationDescription (log , dwarf_cu, piece_locdesc,
2169
+ &curr_piece_source_value);
2109
2170
2110
2171
const Value::ValueType curr_piece_source_value_type =
2111
2172
curr_piece_source_value.GetValueType ();
@@ -2216,11 +2277,19 @@ bool DWARFExpression::Evaluate(
2216
2277
2217
2278
case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
2218
2279
if (stack.size () < 1 ) {
2280
+ UpdateValueTypeFromLocationDescription (log , dwarf_cu,
2281
+ LocationDescriptionKind::Empty);
2282
+ // Reset for the next piece.
2283
+ dwarf4_location_description_kind = Memory;
2219
2284
if (error_ptr)
2220
2285
error_ptr->SetErrorString (
2221
2286
" Expression stack needs at least 1 item for DW_OP_bit_piece." );
2222
2287
return false ;
2223
2288
} else {
2289
+ UpdateValueTypeFromLocationDescription (
2290
+ log , dwarf_cu, dwarf4_location_description_kind, &stack.back ());
2291
+ // Reset for the next piece.
2292
+ dwarf4_location_description_kind = Memory;
2224
2293
const uint64_t piece_bit_size = opcodes.GetULEB128 (&offset);
2225
2294
const uint64_t piece_bit_offset = opcodes.GetULEB128 (&offset);
2226
2295
switch (stack.back ().GetValueType ()) {
@@ -2261,6 +2330,8 @@ bool DWARFExpression::Evaluate(
2261
2330
// DESCRIPTION: Value is immediately stored in block in the debug info with
2262
2331
// the memory representation of the target.
2263
2332
case DW_OP_implicit_value: {
2333
+ dwarf4_location_description_kind = Implicit;
2334
+
2264
2335
const uint32_t len = opcodes.GetULEB128 (&offset);
2265
2336
const void *data = opcodes.GetData (&offset, len);
2266
2337
@@ -2276,6 +2347,12 @@ bool DWARFExpression::Evaluate(
2276
2347
break ;
2277
2348
}
2278
2349
2350
+ case DW_OP_implicit_pointer: {
2351
+ dwarf4_location_description_kind = Implicit;
2352
+ LLDB_ERRORF (error_ptr, " Could not evaluate %s." , DW_OP_value_to_name (op));
2353
+ return false ;
2354
+ }
2355
+
2279
2356
// OPCODE: DW_OP_push_object_address
2280
2357
// OPERANDS: none
2281
2358
// DESCRIPTION: Pushes the address of the object currently being
@@ -2347,6 +2424,7 @@ bool DWARFExpression::Evaluate(
2347
2424
// rather is a constant value. The value from the top of the stack is the
2348
2425
// value to be used. This is the actual object value and not the location.
2349
2426
case DW_OP_stack_value:
2427
+ dwarf4_location_description_kind = Implicit;
2350
2428
if (stack.empty ()) {
2351
2429
if (error_ptr)
2352
2430
error_ptr->SetErrorString (
@@ -2567,25 +2645,28 @@ bool DWARFExpression::Evaluate(
2567
2645
// or DW_OP_bit_piece opcodes
2568
2646
if (pieces.GetBuffer ().GetByteSize ()) {
2569
2647
result = pieces;
2570
- } else {
2571
- if (error_ptr)
2572
- error_ptr->SetErrorString (" Stack empty after evaluation." );
2573
- return false ;
2648
+ return true ;
2574
2649
}
2575
- } else {
2576
- if (log && log ->GetVerbose ()) {
2577
- size_t count = stack.size ();
2578
- LLDB_LOGF (log , " Stack after operation has %" PRIu64 " values:" ,
2579
- (uint64_t )count);
2580
- for (size_t i = 0 ; i < count; ++i) {
2581
- StreamString new_value;
2582
- new_value.Printf (" [%" PRIu64 " ]" , (uint64_t )i);
2583
- stack[i].Dump (&new_value);
2584
- LLDB_LOGF (log , " %s" , new_value.GetData ());
2585
- }
2650
+ if (error_ptr)
2651
+ error_ptr->SetErrorString (" Stack empty after evaluation." );
2652
+ return false ;
2653
+ }
2654
+
2655
+ UpdateValueTypeFromLocationDescription (
2656
+ log , dwarf_cu, dwarf4_location_description_kind, &stack.back ());
2657
+
2658
+ if (log && log ->GetVerbose ()) {
2659
+ size_t count = stack.size ();
2660
+ LLDB_LOGF (log ,
2661
+ " Stack after operation has %" PRIu64 " values:" , (uint64_t )count);
2662
+ for (size_t i = 0 ; i < count; ++i) {
2663
+ StreamString new_value;
2664
+ new_value.Printf (" [%" PRIu64 " ]" , (uint64_t )i);
2665
+ stack[i].Dump (&new_value);
2666
+ LLDB_LOGF (log , " %s" , new_value.GetData ());
2586
2667
}
2587
- result = stack.back ();
2588
2668
}
2669
+ result = stack.back ();
2589
2670
return true ; // Return true on success
2590
2671
}
2591
2672
0 commit comments