@@ -941,6 +941,52 @@ bool DWARFExpression::Evaluate(ExecutionContext *exe_ctx,
941
941
object_address_ptr, result, error_ptr);
942
942
}
943
943
944
+ namespace {
945
+ // / The location description kinds described by the DWARF v5
946
+ // / specification. Composite locations are handled out-of-band and
947
+ // / thus aren't part of the enum.
948
+ enum LocationDescriptionKind {
949
+ Empty,
950
+ Memory,
951
+ Register,
952
+ Implicit
953
+ /* Composite*/
954
+ };
955
+ // / Adjust value's ValueType according to the kind of location description.
956
+ void UpdateValueTypeFromLocationDescription (Log *log, const DWARFUnit *dwarf_cu,
957
+ LocationDescriptionKind kind,
958
+ Value *value = nullptr ) {
959
+ // Note that this function is conflating DWARF expressions with
960
+ // DWARF location descriptions. Perhaps it would be better to define
961
+ // a wrapper for DWARFExpresssion::Eval() that deals with DWARF
962
+ // location descriptions (which consist of one or more DWARF
963
+ // expressions). But doing this would mean we'd also need factor the
964
+ // handling of DW_OP_(bit_)piece out of this function.
965
+ if (dwarf_cu && dwarf_cu->GetVersion () >= 4 ) {
966
+ const char *log_msg = " DWARF location description kind: %s" ;
967
+ switch (kind) {
968
+ case Empty:
969
+ LLDB_LOGF (log, log_msg, " Empty" );
970
+ break ;
971
+ case Memory:
972
+ LLDB_LOGF (log, log_msg, " Memory" );
973
+ if (value->GetValueType () == Value::eValueTypeScalar)
974
+ value->SetValueType (Value::eValueTypeLoadAddress);
975
+ break ;
976
+ case Register:
977
+ LLDB_LOGF (log, log_msg, " Register" );
978
+ value->SetValueType (Value::eValueTypeScalar);
979
+ break ;
980
+ case Implicit:
981
+ LLDB_LOGF (log, log_msg, " Implicit" );
982
+ if (value->GetValueType () == Value::eValueTypeLoadAddress)
983
+ value->SetValueType (Value::eValueTypeScalar);
984
+ break ;
985
+ }
986
+ }
987
+ }
988
+ } // namespace
989
+
944
990
bool DWARFExpression::Evaluate (
945
991
ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
946
992
lldb::ModuleSP module_sp, const DataExtractor &opcodes,
@@ -989,6 +1035,11 @@ bool DWARFExpression::Evaluate(
989
1035
!is_signed));
990
1036
};
991
1037
1038
+ // The default kind is a memory location. This is updated by any
1039
+ // operation that changes this, such as DW_OP_stack_value, and reset
1040
+ // by composition operations like DW_OP_piece.
1041
+ LocationDescriptionKind dwarf4_location_description_kind = Memory;
1042
+
992
1043
while (opcodes.ValidOffset (offset)) {
993
1044
const lldb::offset_t op_offset = offset;
994
1045
const uint8_t op = opcodes.GetU8 (&offset);
@@ -1981,6 +2032,7 @@ bool DWARFExpression::Evaluate(
1981
2032
case DW_OP_reg29:
1982
2033
case DW_OP_reg30:
1983
2034
case DW_OP_reg31: {
2035
+ dwarf4_location_description_kind = Register;
1984
2036
reg_num = op - DW_OP_reg0;
1985
2037
1986
2038
if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
@@ -1993,6 +2045,7 @@ bool DWARFExpression::Evaluate(
1993
2045
// ULEB128 literal operand that encodes the register.
1994
2046
// DESCRIPTION: Push the value in register on the top of the stack.
1995
2047
case DW_OP_regx: {
2048
+ dwarf4_location_description_kind = Register;
1996
2049
reg_num = opcodes.GetULEB128 (&offset);
1997
2050
if (ReadRegisterValueAsScalar (reg_ctx, reg_kind, reg_num, error_ptr, tmp))
1998
2051
stack.push_back (tmp);
@@ -2116,12 +2169,18 @@ bool DWARFExpression::Evaluate(
2116
2169
// provides a way of describing how large a part of a variable a particular
2117
2170
// DWARF expression refers to.
2118
2171
case DW_OP_piece: {
2172
+ LocationDescriptionKind piece_locdesc = dwarf4_location_description_kind;
2173
+ // Reset for the next piece.
2174
+ dwarf4_location_description_kind = Memory;
2175
+
2119
2176
const uint64_t piece_byte_size = opcodes.GetULEB128 (&offset);
2120
2177
2121
2178
if (piece_byte_size > 0 ) {
2122
2179
Value curr_piece;
2123
2180
2124
2181
if (stack.empty ()) {
2182
+ UpdateValueTypeFromLocationDescription (
2183
+ log, dwarf_cu, LocationDescriptionKind::Empty);
2125
2184
// In a multi-piece expression, this means that the current piece is
2126
2185
// not available. Fill with zeros for now by resizing the data and
2127
2186
// appending it
@@ -2137,6 +2196,8 @@ bool DWARFExpression::Evaluate(
2137
2196
// Extract the current piece into "curr_piece"
2138
2197
Value curr_piece_source_value (stack.back ());
2139
2198
stack.pop_back ();
2199
+ UpdateValueTypeFromLocationDescription (log, dwarf_cu, piece_locdesc,
2200
+ &curr_piece_source_value);
2140
2201
2141
2202
const Value::ValueType curr_piece_source_value_type =
2142
2203
curr_piece_source_value.GetValueType ();
@@ -2245,11 +2306,19 @@ bool DWARFExpression::Evaluate(
2245
2306
2246
2307
case DW_OP_bit_piece: // 0x9d ULEB128 bit size, ULEB128 bit offset (DWARF3);
2247
2308
if (stack.size () < 1 ) {
2309
+ UpdateValueTypeFromLocationDescription (log, dwarf_cu,
2310
+ LocationDescriptionKind::Empty);
2311
+ // Reset for the next piece.
2312
+ dwarf4_location_description_kind = Memory;
2248
2313
if (error_ptr)
2249
2314
error_ptr->SetErrorString (
2250
2315
" Expression stack needs at least 1 item for DW_OP_bit_piece." );
2251
2316
return false ;
2252
2317
} else {
2318
+ UpdateValueTypeFromLocationDescription (
2319
+ log, dwarf_cu, dwarf4_location_description_kind, &stack.back ());
2320
+ // Reset for the next piece.
2321
+ dwarf4_location_description_kind = Memory;
2253
2322
const uint64_t piece_bit_size = opcodes.GetULEB128 (&offset);
2254
2323
const uint64_t piece_bit_offset = opcodes.GetULEB128 (&offset);
2255
2324
switch (stack.back ().GetValueType ()) {
@@ -2288,6 +2357,8 @@ bool DWARFExpression::Evaluate(
2288
2357
// DESCRIPTION: Value is immediately stored in block in the debug info with
2289
2358
// the memory representation of the target.
2290
2359
case DW_OP_implicit_value: {
2360
+ dwarf4_location_description_kind = Implicit;
2361
+
2291
2362
const uint32_t len = opcodes.GetULEB128 (&offset);
2292
2363
const void *data = opcodes.GetData (&offset, len);
2293
2364
@@ -2303,6 +2374,12 @@ bool DWARFExpression::Evaluate(
2303
2374
break ;
2304
2375
}
2305
2376
2377
+ case DW_OP_implicit_pointer: {
2378
+ dwarf4_location_description_kind = Implicit;
2379
+ LLDB_ERRORF (error_ptr, " Could not evaluate %s." , DW_OP_value_to_name (op));
2380
+ return false ;
2381
+ }
2382
+
2306
2383
// OPCODE: DW_OP_push_object_address
2307
2384
// OPERANDS: none
2308
2385
// DESCRIPTION: Pushes the address of the object currently being
@@ -2374,6 +2451,7 @@ bool DWARFExpression::Evaluate(
2374
2451
// rather is a constant value. The value from the top of the stack is the
2375
2452
// value to be used. This is the actual object value and not the location.
2376
2453
case DW_OP_stack_value:
2454
+ dwarf4_location_description_kind = Implicit;
2377
2455
if (stack.empty ()) {
2378
2456
if (error_ptr)
2379
2457
error_ptr->SetErrorString (
@@ -2594,25 +2672,28 @@ bool DWARFExpression::Evaluate(
2594
2672
// or DW_OP_bit_piece opcodes
2595
2673
if (pieces.GetBuffer ().GetByteSize ()) {
2596
2674
result = pieces;
2597
- } else {
2598
- if (error_ptr)
2599
- error_ptr->SetErrorString (" Stack empty after evaluation." );
2600
- return false ;
2675
+ return true ;
2601
2676
}
2602
- } else {
2603
- if (log && log->GetVerbose ()) {
2604
- size_t count = stack.size ();
2605
- LLDB_LOGF (log, " Stack after operation has %" PRIu64 " values:" ,
2606
- (uint64_t )count);
2607
- for (size_t i = 0 ; i < count; ++i) {
2608
- StreamString new_value;
2609
- new_value.Printf (" [%" PRIu64 " ]" , (uint64_t )i);
2610
- stack[i].Dump (&new_value);
2611
- LLDB_LOGF (log, " %s" , new_value.GetData ());
2612
- }
2677
+ if (error_ptr)
2678
+ error_ptr->SetErrorString (" Stack empty after evaluation." );
2679
+ return false ;
2680
+ }
2681
+
2682
+ UpdateValueTypeFromLocationDescription (
2683
+ log, dwarf_cu, dwarf4_location_description_kind, &stack.back ());
2684
+
2685
+ if (log && log->GetVerbose ()) {
2686
+ size_t count = stack.size ();
2687
+ LLDB_LOGF (log,
2688
+ " Stack after operation has %" PRIu64 " values:" , (uint64_t )count);
2689
+ for (size_t i = 0 ; i < count; ++i) {
2690
+ StreamString new_value;
2691
+ new_value.Printf (" [%" PRIu64 " ]" , (uint64_t )i);
2692
+ stack[i].Dump (&new_value);
2693
+ LLDB_LOGF (log, " %s" , new_value.GetData ());
2613
2694
}
2614
- result = stack.back ();
2615
2695
}
2696
+ result = stack.back ();
2616
2697
return true ; // Return true on success
2617
2698
}
2618
2699
0 commit comments