hrev45887 adds 1 changeset to branch 'master' old head: a326afa3fca2ccb841b8e8ff6b7a8663eec1dc83 new head: d950dcd9ab426ff5a3a9d04dae8655296bffded9 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=d950dcd+%5Ea326afa ---------------------------------------------------------------------------- d950dcd: Debugger: Implement new expression operands. DWARF4 adds two new expression operands for values that are known, but not located anywhere in memory (e.g. a known constant or a value computed from a composite of other values/locations in the program). These are DW_OP_implicit_value, which supplies the value directly as an LEB128 + data block, and DW_OP_stack_value, which indicates the top of the expression stack is the value. Implements corresponding support in DwarfExpressionEvaluator, ValueLocation and ValueLoader. [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- Revision: hrev45887 Commit: d950dcd9ab426ff5a3a9d04dae8655296bffded9 URL: http://cgit.haiku-os.org/haiku/commit/?id=d950dcd Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sun Jul 21 03:34:31 2013 UTC ---------------------------------------------------------------------------- 5 files changed, 83 insertions(+), 6 deletions(-) src/apps/debugger/dwarf/Dwarf.h | 2 ++ .../debugger/dwarf/DwarfExpressionEvaluator.cpp | 31 ++++++++++++++++++++ src/apps/debugger/types/ValueLocation.cpp | 6 ++++ src/apps/debugger/types/ValueLocation.h | 27 +++++++++++++++-- src/apps/debugger/value/ValueLoader.cpp | 23 ++++++++++++--- ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/dwarf/Dwarf.h b/src/apps/debugger/dwarf/Dwarf.h index 09d7eba..1fbfc2f 100644 --- a/src/apps/debugger/dwarf/Dwarf.h +++ b/src/apps/debugger/dwarf/Dwarf.h @@ -306,6 +306,8 @@ enum { DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, DW_OP_bit_piece = 0x9d, + DW_OP_implicit_value = 0x9e, + DW_OP_stack_value = 0x9f, DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff }; diff --git a/src/apps/debugger/dwarf/DwarfExpressionEvaluator.cpp b/src/apps/debugger/dwarf/DwarfExpressionEvaluator.cpp index f47d542..d0ee3ae 100644 --- a/src/apps/debugger/dwarf/DwarfExpressionEvaluator.cpp +++ b/src/apps/debugger/dwarf/DwarfExpressionEvaluator.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx. * Distributed under the terms of the MIT License. */ @@ -631,6 +632,36 @@ DwarfExpressionEvaluator::_Evaluate(ValuePieceLocation* _piece) TRACE_EXPR(" DW_OP_nop\n"); break; + case DW_OP_implicit_value: + { + TRACE_EXPR(" DW_OP_implicit_value\n"); + if (_piece == NULL) { + throw EvaluationException( + "DW_OP_implicit_value in non-location expression"); + } + uint32 length = fDataReader.ReadUnsignedLEB128(0); + if (length == 0) + return B_BAD_DATA; + + if (fDataReader.BytesRemaining() < length) + return B_BAD_DATA; + + _piece->SetToValue(fDataReader.Data(), length); + return B_OK; + } + case DW_OP_stack_value: + { + TRACE_EXPR(" DW_OP_stack_value\n"); + if (_piece == NULL) { + throw EvaluationException( + "DW_OP_stack_value in non-location expression"); + } + if (fStackSize == 0) + return B_BAD_DATA; + target_addr_t value = _Pop(); + _piece->SetToValue(&value, sizeof(target_addr_t)); + return B_OK; + } default: if (opcode >= DW_OP_lit0 && opcode <= DW_OP_lit31) { TRACE_EXPR(" DW_OP_lit%u\n", opcode - DW_OP_lit0); diff --git a/src/apps/debugger/types/ValueLocation.cpp b/src/apps/debugger/types/ValueLocation.cpp index 887b63b..9a83c4d 100644 --- a/src/apps/debugger/types/ValueLocation.cpp +++ b/src/apps/debugger/types/ValueLocation.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx. * Distributed under the terms of the MIT License. */ @@ -258,6 +259,11 @@ ValueLocation::Dump() const case VALUE_PIECE_LOCATION_REGISTER: printf(" register %" B_PRIu32, piece.reg); break; + case VALUE_PIECE_LOCATION_IMPLICIT: + printf(" implicit value: "); + for (uint32 j = 0; j < piece.size; j++) + printf("%x ", ((char *)piece.value)[j]); + break; } printf(" size: %" B_PRIu64 " (%" B_PRIu64 " bits), offset: %" B_PRIu64 diff --git a/src/apps/debugger/types/ValueLocation.h b/src/apps/debugger/types/ValueLocation.h index 1ff9f61..25cb64a 100644 --- a/src/apps/debugger/types/ValueLocation.h +++ b/src/apps/debugger/types/ValueLocation.h @@ -1,5 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@xxxxxx. + * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx. * Distributed under the terms of the MIT License. */ #ifndef VALUE_LOCATION_H @@ -16,7 +17,8 @@ enum value_piece_location_type { VALUE_PIECE_LOCATION_INVALID, // structure is invalid VALUE_PIECE_LOCATION_UNKNOWN, // location unknown, but size is valid VALUE_PIECE_LOCATION_MEMORY, // piece is in memory - VALUE_PIECE_LOCATION_REGISTER // piece is in a register + VALUE_PIECE_LOCATION_REGISTER, // piece is in a register + VALUE_PIECE_LOCATION_IMPLICIT // value isn't stored anywhere in memory but is known }; @@ -31,11 +33,20 @@ struct ValuePieceLocation { uint64 bitOffset; // bit offset (to the most // significant bit) value_piece_location_type type; + void* value; // used for storing implicit values + ValuePieceLocation() : - type(VALUE_PIECE_LOCATION_INVALID) + type(VALUE_PIECE_LOCATION_INVALID), + value(NULL) + { + } + + ~ValuePieceLocation() { + if (value != NULL) + free(value); } bool IsValid() const @@ -74,6 +85,18 @@ struct ValuePieceLocation { this->bitOffset = bitOffset; } + bool SetToValue(const void* data, target_size_t size) + { + char* valueData = (char*)malloc(size); + if (valueData == NULL) + return false; + memcpy(valueData, data, size); + SetSize(size); + type = VALUE_PIECE_LOCATION_IMPLICIT; + value = valueData; + return true; + } + ValuePieceLocation& Normalize(bool bigEndian); }; diff --git a/src/apps/debugger/value/ValueLoader.cpp b/src/apps/debugger/value/ValueLoader.cpp index 9d973eb..47bc151 100644 --- a/src/apps/debugger/value/ValueLoader.cpp +++ b/src/apps/debugger/value/ValueLoader.cpp @@ -74,6 +74,7 @@ ValueLoader::LoadValue(ValueLocation* location, type_code valueType, return B_ENTRY_NOT_FOUND; case VALUE_PIECE_LOCATION_MEMORY: case VALUE_PIECE_LOCATION_REGISTER: + case VALUE_PIECE_LOCATION_IMPLICIT: break; } @@ -133,15 +134,29 @@ ValueLoader::LoadValue(ValueLocation* location, type_code valueType, case VALUE_PIECE_LOCATION_UNKNOWN: return B_ENTRY_NOT_FOUND; case VALUE_PIECE_LOCATION_MEMORY: + case VALUE_PIECE_LOCATION_IMPLICIT: { target_addr_t address = piece.address; - TRACE_LOCALS(" piece %" B_PRId32 ": memory address: %#" - B_PRIx64 ", bits: %" B_PRIu32 "\n", i, address, bitSize); + if (piece.type == VALUE_PIECE_LOCATION_MEMORY) { + TRACE_LOCALS(" piece %" B_PRId32 ": memory address: %#" + B_PRIx64 ", bits: %" B_PRIu32 "\n", i, address, + bitSize); + } else { + TRACE_LOCALS(" piece %" B_PRId32 ": implicit value, " + "bits: %" B_PRIu32 "\n", i, bitSize); + } uint8 pieceBuffer[kMaxPieceSize]; - ssize_t bytesRead = fTeamMemory->ReadMemory(address, - pieceBuffer, bytesToRead); + ssize_t bytesRead; + if (piece.type == VALUE_PIECE_LOCATION_MEMORY) { + bytesRead = fTeamMemory->ReadMemory(address, + pieceBuffer, bytesToRead); + } else { + memcpy(pieceBuffer, piece.value, piece.size); + bytesRead = piece.size; + } + if (bytesRead < 0) return bytesRead; if ((uint32)bytesRead != bytesToRead)