Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2011-08-31 21:21:44 +0000
committereutarass2011-08-31 21:21:44 +0000
commit7463eb8579edff3124184ee51beb6ba2e22aec5e (patch)
treed2959411bb71d6661fc5d0b378c6f307e31f3774
parent840c6a544350f23f2f439be5bb8d8d3b11430e23 (diff)
downloadorg.eclipse.tcf.agent-7463eb8579edff3124184ee51beb6ba2e22aec5e.tar.gz
org.eclipse.tcf.agent-7463eb8579edff3124184ee51beb6ba2e22aec5e.tar.xz
org.eclipse.tcf.agent-7463eb8579edff3124184ee51beb6ba2e22aec5e.zip
TCF Agent: added support for OP_piece and OP_bit_piece in DWARF location expressions.
-rw-r--r--services/dwarfcache.c4
-rw-r--r--services/dwarfcache.h11
-rw-r--r--services/dwarfexpr.c105
-rw-r--r--services/symbols_elf.c83
4 files changed, 177 insertions, 26 deletions
diff --git a/services/dwarfcache.c b/services/dwarfcache.c
index 06b1cfdc..e4ba697c 100644
--- a/services/dwarfcache.c
+++ b/services/dwarfcache.c
@@ -737,8 +737,8 @@ static void get_object_property_callback(U2_T Tag, U2_T Attr, U2_T Form) {
U8_T get_numeric_property_value(PropertyValue * Value) {
U8_T Res = 0;
- if (Value->mRegister != NULL) {
- str_exception(ERR_INV_CONTEXT, "Register variable");
+ if (Value->mPieces != NULL || Value->mRegister != NULL) {
+ str_exception(ERR_INV_CONTEXT, "Constant DWARF attribute value expected");
}
else if (Value->mAddr != NULL) {
size_t i;
diff --git a/services/dwarfcache.h b/services/dwarfcache.h
index e7665754..93bec126 100644
--- a/services/dwarfcache.h
+++ b/services/dwarfcache.h
@@ -38,6 +38,7 @@ typedef struct PubNamesInfo PubNamesInfo;
typedef struct PubNamesTable PubNamesTable;
typedef struct ObjectArray ObjectArray;
typedef struct SymbolInfo SymbolInfo;
+typedef struct PropertyValuePiece PropertyValuePiece;
typedef struct PropertyValue PropertyValue;
typedef struct LineNumbersState LineNumbersState;
typedef struct CompUnit CompUnit;
@@ -118,6 +119,14 @@ struct PubNamesTable {
unsigned mMax;
};
+struct PropertyValuePiece {
+ int mBigEndian;
+ ContextAddress mAddress;
+ RegisterDefinition * mRegister;
+ U4_T mBitOffset;
+ U4_T mBitSize;
+};
+
struct PropertyValue {
Context * mContext;
int mFrame;
@@ -129,6 +138,8 @@ struct PropertyValue {
size_t mSize;
int mBigEndian;
RegisterDefinition * mRegister;
+ PropertyValuePiece * mPieces;
+ U4_T mPieceCnt;
};
#define LINE_IsStmt 0x01
diff --git a/services/dwarfexpr.c b/services/dwarfexpr.c
index 6def5985..33b8c9bc 100644
--- a/services/dwarfexpr.c
+++ b/services/dwarfexpr.c
@@ -23,6 +23,7 @@
#include <assert.h>
#include <stdio.h>
+#include <framework/events.h>
#include <framework/myalloc.h>
#include <framework/exceptions.h>
#include <framework/errors.h>
@@ -33,10 +34,58 @@
#include <services/stacktrace.h>
#include <services/vm.h>
+typedef struct ValuePieces {
+ U4_T mCnt;
+ U4_T mMax;
+ PropertyValuePiece * mArray;
+ struct ValuePieces * mNext;
+} ValuePieces;
+
static VMState sState;
static ELF_Section * sSection = NULL;
static U8_T sSectionOffs = 0;
static PropertyValue * sValue = NULL;
+static ValuePieces * sValuePieces = NULL;
+
+static ValuePieces * sFreeValuePieces = NULL;
+static ValuePieces * sBusyValuePieces = NULL;
+static unsigned sValuePiecesCnt = 0;
+static int sValuePiecesPosted = 0;
+
+static void free_value_pieces(void * args) {
+ while (sBusyValuePieces != NULL) {
+ ValuePieces * Pieces = sBusyValuePieces;
+ sBusyValuePieces = Pieces->mNext;
+ Pieces->mNext = sFreeValuePieces;
+ sFreeValuePieces = Pieces;
+ }
+ while (sFreeValuePieces != NULL && sValuePiecesCnt > 16) {
+ ValuePieces * Pieces = sFreeValuePieces;
+ sFreeValuePieces = sFreeValuePieces->mNext;
+ sValuePiecesCnt--;
+ loc_free(Pieces->mArray);
+ loc_free(Pieces);
+ }
+}
+
+static ValuePieces * alloc_value_pieces(void) {
+ ValuePieces * Pieces = sFreeValuePieces;
+ if (Pieces == NULL) {
+ Pieces = (ValuePieces *)loc_alloc_zero(sizeof(ValuePieces));
+ sValuePiecesCnt++;
+ }
+ else {
+ sFreeValuePieces = sFreeValuePieces->mNext;
+ }
+ Pieces->mNext = sBusyValuePieces;
+ sBusyValuePieces = Pieces;
+ if (!sValuePiecesPosted && sValuePiecesCnt > 8) {
+ post_event(free_value_pieces, NULL);
+ sValuePiecesPosted = 1;
+ }
+ Pieces->mCnt = 0;
+ return Pieces;
+}
static StackFrame * get_stack_frame(PropertyValue * sValue) {
StackFrame * Info = NULL;
@@ -81,6 +130,7 @@ static U8_T get_fbreg(void) {
{
PropertyValue * OrgValue = sValue;
+ ValuePieces * OrgValuePieces = sValuePieces;
ELF_Section * OrgSection = sSection;
U8_T OrgSectionOffs = sSectionOffs;
VMState OrgState = sState;
@@ -97,6 +147,7 @@ static U8_T get_fbreg(void) {
sState.object_address = OrgState.object_address;
sSectionOffs = OrgSectionOffs;
sSection = OrgSection;
+ sValuePieces = OrgValuePieces;
sValue = OrgValue;
}
@@ -138,13 +189,34 @@ static void evaluate_expression(ELF_Section * Section, U1_T * Buf, size_t Size)
sSectionOffs = Buf - (U1_T *)Section->data;
dio_EnterSection(&Unit->mDesc, sSection, sSectionOffs);
if (evaluate_vm_expression(&sState) < 0) error = errno;
+ if (!error && sState.piece_bits) {
+ sValuePieces = alloc_value_pieces();
+ while (!error) {
+ PropertyValuePiece * Piece;
+ if (sValuePieces->mCnt >= sValuePieces->mMax) {
+ sValuePieces->mMax += 8;
+ sValuePieces->mArray = (PropertyValuePiece *)loc_realloc(sValuePieces->mArray,
+ sizeof(PropertyValuePiece) * sValuePieces->mMax);
+ }
+ Piece = sValuePieces->mArray + sValuePieces->mCnt++;
+ memset(Piece, 0, sizeof(PropertyValuePiece));
+ if (sState.reg) {
+ Piece->mRegister = sState.reg;
+ Piece->mBigEndian = sState.reg->big_endian;
+ }
+ else {
+ Piece->mAddress = sState.stk[--sState.stk_pos];
+ Piece->mBigEndian = sState.big_endian;
+ }
+ Piece->mBitOffset = sState.piece_offs;
+ Piece->mBitSize = sState.piece_bits;
+ if (sState.code_pos >= sState.code_len) break;
+ if (evaluate_vm_expression(&sState) < 0) error = errno;
+ }
+ }
dio_ExitSection();
+ assert(error || sState.code_pos == sState.code_len);
if (error) exception(error);
- if (sState.reg) {
- sValue->mSize = sState.reg->size;
- sValue->mBigEndian = sState.reg->big_endian;
- sValue->mRegister = sState.reg;
- }
}
static void evaluate_location(void) {
@@ -200,6 +272,7 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) {
CompUnit * Unit = v->mObject->mCompUnit;
sValue = v;
+ sValuePieces = NULL;
sState.ctx = sValue->mContext;
sState.addr_size = Unit->mDesc.mAddressSize;
sState.big_endian = Unit->mFile->big_endian;
@@ -229,12 +302,26 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * v) {
evaluate_expression(Unit->mDesc.mSection, sValue->mAddr, sValue->mSize);
}
- if (sValue->mRegister == NULL) {
- assert(sState.stk_pos > 0);
+ sValue->mAddr = NULL;
+ sValue->mValue = 0;
+ sValue->mSize = 0;
+ sValue->mBigEndian = sState.big_endian;
+ sValue->mRegister = NULL;
+ sValue->mPieces = NULL;
+ sValue->mPieceCnt = 0;
+
+ if (sValuePieces) {
+ sValue->mPieces = sValuePieces->mArray;
+ sValue->mPieceCnt = sValuePieces->mCnt;
+ }
+ else if (sState.reg) {
+ sValue->mSize = sState.reg->size;
+ sValue->mBigEndian = sState.reg->big_endian;
+ sValue->mRegister = sState.reg;
+ }
+ else {
sValue->mValue = sState.stk[--sState.stk_pos];
- sValue->mSize = 0;
}
- sValue->mAddr = NULL;
if (sState.stk_pos != stk_pos) {
str_exception(ERR_INV_DWARF, "Invalid DWARF expression stack");
diff --git a/services/symbols_elf.c b/services/symbols_elf.c
index 9fccf9ce..b142a71a 100644
--- a/services/symbols_elf.c
+++ b/services/symbols_elf.c
@@ -1757,22 +1757,29 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big
if (obj != NULL) {
Trap trap;
PropertyValue v;
+ static U1_T * bf = NULL;
+ static size_t bf_size = 0;
if (set_trap(&trap)) {
read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_const_value, &v);
if (v.mAddr != NULL) {
*size = v.mSize;
*value = v.mAddr;
}
+ else if (v.mRegister != NULL || v.mPieces != NULL) {
+ str_exception(ERR_INV_CONTEXT, "Constant DWARF attribute value expected");
+ }
else {
- static U1_T bf[sizeof(v.mValue)];
U8_T n = v.mValue;
size_t i = 0;
- if (v.mRegister != NULL) exception(ERR_INV_CONTEXT);
- for (i = 0; i < sizeof(bf); i++) {
- bf[v.mBigEndian ? sizeof(bf) - i - 1 : i] = n & 0xffu;
+ if (bf_size < sizeof(v.mValue)) {
+ bf_size = sizeof(v.mValue);
+ bf = (U1_T *)loc_realloc(bf, bf_size);
+ }
+ for (i = 0; i < sizeof(v.mValue); i++) {
+ bf[v.mBigEndian ? sizeof(v.mValue) - i - 1 : i] = n & 0xffu;
n = n >> 8;
}
- *size = sizeof(bf);
+ *size = sizeof(v.mValue);
*value = bf;
}
*big_endian = v.mBigEndian;
@@ -1784,11 +1791,48 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big
}
if (set_trap(&trap)) {
read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_location, &v);
- if (v.mRegister == NULL) {
- exception(ERR_INV_CONTEXT);
+ if (v.mPieces != NULL) {
+ U4_T n = 0;
+ U4_T bf_offs = 0;
+ while (n < v.mPieceCnt) {
+ U4_T i;
+ U1_T pbf[32];
+ PropertyValuePiece * piece = v.mPieces + n++;
+ U4_T piece_size = (piece->mBitSize + 7) / 8;
+ if (piece_size > sizeof(pbf)) exception(ERR_BUFFER_OVERFLOW);
+ if (bf_size < bf_offs / 8 + piece_size + 1) {
+ bf_size = bf_offs / 8 + piece_size + 1;
+ bf = (U1_T *)loc_realloc(bf, bf_size);
+ }
+ if (piece->mRegister) {
+ StackFrame * frame = NULL;
+ RegisterDefinition * def = piece->mRegister;
+ if (get_frame_info(v.mContext, v.mFrame, &frame) < 0) exception(errno);
+ if (read_reg_bytes(frame, def, 0, piece_size, pbf) < 0) exception(errno);
+ }
+ else {
+ if (context_read_mem(v.mContext, piece->mAddress, pbf, piece_size) < 0) exception(errno);
+ }
+ if (!piece->mBigEndian != !v.mBigEndian) swap_bytes(pbf, piece_size);
+ for (i = piece->mBitOffset; i < piece->mBitOffset + piece->mBitSize; i++) {
+ if (pbf[i / 8] & (1u << (i % 8))) {
+ bf[bf_offs / 8] |= (1u << (bf_offs % 8));
+ }
+ else {
+ bf[bf_offs / 8] &= ~(1u << (bf_offs % 8));
+ }
+ bf_offs++;
+ }
+ }
+ while (bf_offs % 8) {
+ bf[bf_offs / 8] &= ~(1u << (bf_offs % 8));
+ bf_offs++;
+ }
+ *value = bf;
+ *size = bf_offs / 8;
+ *big_endian = v.mBigEndian;
}
- else {
- static U1_T bf[32];
+ else if (v.mRegister != NULL) {
StackFrame * frame = NULL;
RegisterDefinition * def = v.mRegister;
ContextAddress sym_size = def->size;
@@ -1796,7 +1840,10 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big
unsigned val_size = 0;
if (get_symbol_size(sym, &sym_size) < 0) exception(errno);
- if (sym_size > sizeof(bf)) exception(ERR_BUFFER_OVERFLOW);
+ if (bf_size < sym_size) {
+ bf_size = (size_t)sym_size;
+ bf = (U1_T *)loc_realloc(bf, bf_size);
+ }
if (get_frame_info(v.mContext, v.mFrame, &frame) < 0) exception(errno);
val_size = def->size < sym_size ? (unsigned)def->size : (unsigned)sym_size;
if (def->big_endian) val_offs = (unsigned)def->size - val_size;
@@ -1805,6 +1852,9 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big
*size = val_size;
*big_endian = def->big_endian;
}
+ else {
+ exception(ERR_INV_CONTEXT);
+ }
clear_trap(&trap);
return 0;
}
@@ -1884,17 +1934,20 @@ int get_symbol_address(const Symbol * sym, ContextAddress * address) {
if (!set_trap(&trap)) return -1;
if ((type->mTag != TAG_pointer_type && type->mTag != TAG_mod_pointer) || type->mType == NULL) exception(ERR_INV_CONTEXT);
read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, sym->var, AT_location, &v);
- if (v.mRegister == NULL) {
- if (elf_read_memory_word(sym_ctx, sym->var->mCompUnit->mFile,
- (ContextAddress)get_numeric_property_value(&v), &base) < 0) exception(errno);
+ if (v.mPieces != NULL) {
+ str_exception(ERR_UNSUPPORTED, "Unsupported location of 'this' pointer");
}
- else {
+ else if (v.mRegister != NULL) {
U8_T rv = 0;
StackFrame * frame = NULL;
if (get_frame_info(v.mContext, v.mFrame, &frame) < 0) exception(errno);
if (read_reg_value(frame, v.mRegister, &rv) < 0) exception(errno);
base = (ContextAddress)rv;
}
+ else {
+ if (elf_read_memory_word(sym_ctx, sym->var->mCompUnit->mFile,
+ (ContextAddress)get_numeric_property_value(&v), &base) < 0) exception(errno);
+ }
type = get_original_type(type->mType);
if (!calc_member_offset(type, obj, &offs)) exception(ERR_INV_CONTEXT);
clear_trap(&trap);
@@ -1938,8 +1991,8 @@ int get_symbol_register(const Symbol * sym, Context ** ctx, int * frame, Registe
if (unpack(sym) < 0) return -1;
if (obj != NULL && obj->mTag != TAG_member && obj->mTag != TAG_inheritance) {
Trap trap;
- PropertyValue v;
if (set_trap(&trap)) {
+ PropertyValue v;
read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_location, &v);
*ctx = sym_ctx;
*frame = sym_frame;

Back to the top