Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2011-03-30 14:50:39 -0400
committereutarass2011-03-30 14:50:39 -0400
commitb626eba6c9dadace28b6376a5b8b53b5fc7ed900 (patch)
tree13553f278dfe0dda8fd6727f066cedb3f601c234
parent989d3ae1dcf88d128d12366291dfe85ee948360f (diff)
downloadorg.eclipse.tcf.agent-b626eba6c9dadace28b6376a5b8b53b5fc7ed900.tar.gz
org.eclipse.tcf.agent-b626eba6c9dadace28b6376a5b8b53b5fc7ed900.tar.xz
org.eclipse.tcf.agent-b626eba6c9dadace28b6376a5b8b53b5fc7ed900.zip
TCF Agent:
1. added support for debugging a code running in compatibility mode, like 32-bit code on 64-bit CPU. 2. fixed: register variable values are always returned as 8 bytes regardless of actual size. 3. improved text for some error messages. 4. added support for big-endian values in expression evaluator.
-rw-r--r--framework/cpudefs.h15
-rw-r--r--machine/cpudefs-ext.h12
-rw-r--r--server/machine/cpudefs-ext.h5
-rw-r--r--services/dwarfcache.c10
-rw-r--r--services/dwarfcache.h4
-rw-r--r--services/dwarfexpr.c33
-rw-r--r--services/dwarfframe.c24
-rw-r--r--services/expressions.c83
-rw-r--r--services/expressions.h1
-rw-r--r--services/symbols.c10
-rw-r--r--services/symbols.h2
-rw-r--r--services/symbols_elf.c17
-rw-r--r--services/symbols_proxy.c5
-rw-r--r--services/symbols_win32.c3
-rw-r--r--services/tcf_elf.c2
-rw-r--r--services/tcf_elf.h21
-rw-r--r--system/GNU/Linux/context-linux.c1
17 files changed, 187 insertions, 61 deletions
diff --git a/framework/cpudefs.h b/framework/cpudefs.h
index 82c29f83..adfd1497 100644
--- a/framework/cpudefs.h
+++ b/framework/cpudefs.h
@@ -110,20 +110,25 @@ typedef struct StackTracingInfo {
#define STACK_NO_FRAME (-1)
#define STACK_TOP_FRAME (-2)
-typedef struct StackFrame StackFrame;
-
-struct StackFrame {
+typedef struct StackFrame {
int is_top_frame;
Context * ctx;
ContextAddress fp; /* frame address */
RegisterData * regs; /* register values */
-};
+} StackFrame;
+
+typedef struct RegisterIdScope {
+ uint16_t machine;
+ uint8_t os_abi;
+ uint8_t big_endian;
+ uint8_t id_type;
+} RegisterIdScope;
/* Return array of CPU register definitions. Last item in the array has name == NULL */
extern RegisterDefinition * get_reg_definitions(Context * ctx);
/* Search register definition for given register ID, return NULL if not found */
-extern RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, unsigned numbering_convention);
+extern RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope * scope);
/* Return register definition of instruction pointer */
extern RegisterDefinition * get_PC_definition(Context * ctx);
diff --git a/machine/cpudefs-ext.h b/machine/cpudefs-ext.h
index 47422081..b0b7dbdb 100644
--- a/machine/cpudefs-ext.h
+++ b/machine/cpudefs-ext.h
@@ -69,12 +69,14 @@ static RegisterDefinition * get_reg_by_eh_frame_id(unsigned id) {
return id < map_length ? map[id] : NULL;
}
-RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, unsigned munbering_convention) {
- switch (munbering_convention) {
- case REGNUM_DWARF: return get_reg_by_dwarf_id(id);
- case REGNUM_EH_FRAME: return get_reg_by_eh_frame_id(id);
+RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope * scope) {
+ RegisterDefinition * def = NULL;
+ switch (scope->id_type) {
+ case REGNUM_DWARF: def = get_reg_by_dwarf_id(id); break;
+ case REGNUM_EH_FRAME: def = get_reg_by_eh_frame_id(id); break;
}
- return NULL;
+ if (def == NULL) set_errno(ERR_OTHER, "Invalid register ID");
+ return def;
}
int read_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf) {
diff --git a/server/machine/cpudefs-ext.h b/server/machine/cpudefs-ext.h
index 3a252400..240da5f7 100644
--- a/server/machine/cpudefs-ext.h
+++ b/server/machine/cpudefs-ext.h
@@ -14,10 +14,10 @@
#include <services/context-proxy.h>
-RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, unsigned munbering_convention) {
+RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope * scope) {
RegisterDefinition * defs = get_reg_definitions(ctx);
while (defs != NULL && defs->name != NULL) {
- switch (munbering_convention) {
+ switch (scope->id_type) {
case REGNUM_DWARF:
if (defs->dwarf_id == (int)id) return defs;
break;
@@ -27,6 +27,7 @@ RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, unsigned munberin
}
defs++;
}
+ set_errno(ERR_OTHER, "Invalid register ID");
return NULL;
}
diff --git a/services/dwarfcache.c b/services/dwarfcache.c
index dfa0b3e3..1caa677a 100644
--- a/services/dwarfcache.c
+++ b/services/dwarfcache.c
@@ -260,6 +260,10 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) {
CompUnit * Unit = add_comp_unit(sDebugSection->addr + dio_gEntryPos);
Unit->mFile = sCache->mFile;
Unit->mDebugRangesOffs = ~(U8_T)0;
+ Unit->mRegIdScope.big_endian = sCache->mFile->big_endian;
+ Unit->mRegIdScope.machine = sCache->mFile->machine;
+ Unit->mRegIdScope.os_abi = sCache->mFile->os_abi;
+ Unit->mRegIdScope.id_type = REGNUM_DWARF;
Info = Unit->mObject;
sCompUnit = Unit;
}
@@ -716,7 +720,11 @@ static void read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Ob
if (RefObj == NULL) exception(ERR_INV_DWARF);
read_and_evaluate_dwarf_object_property(Ctx, Frame, 0, RefObj, AT_location, &ValueAddr);
if (ValueAddr.mAccessFunc != NULL) {
- ValueAddr.mAccessFunc(&ValueAddr, 0, &Value->mValue);
+ static U1_T Buf[8];
+ if (ValueAddr.mAccessFunc(&ValueAddr, 0, Buf) < 0) exception(errno);
+ Value->mAddr = Buf;
+ Value->mSize = ValueAddr.mSize;
+ Value->mBigEndian = ValueAddr.mBigEndian;
}
else {
static U1_T Buf[8];
diff --git a/services/dwarfcache.h b/services/dwarfcache.h
index 8b54a5d9..e8ddd0d0 100644
--- a/services/dwarfcache.h
+++ b/services/dwarfcache.h
@@ -124,7 +124,8 @@ struct PropertyValue {
U1_T * mAddr;
size_t mSize;
int mBigEndian;
- int (*mAccessFunc)(PropertyValue *, int, U8_T *);
+ void * mAccessData;
+ int (*mAccessFunc)(PropertyValue *, int, U1_T *);
};
#define LINE_IsStmt 0x01
@@ -154,6 +155,7 @@ struct CompUnit {
ContextAddress mHighPC;
DIO_UnitDescriptor mDesc;
+ RegisterIdScope mRegIdScope;
U8_T mDebugRangesOffs;
U8_T mLineInfoOffs;
diff --git a/services/dwarfexpr.c b/services/dwarfexpr.c
index 05aacaaa..ac0614cb 100644
--- a/services/dwarfexpr.c
+++ b/services/dwarfexpr.c
@@ -58,13 +58,12 @@ static ObjectInfo * get_parent_function(ObjectInfo * Info) {
return NULL;
}
-static int register_access_func(PropertyValue * Value, int write, U8_T * Data) {
- RegisterDefinition * def;
+static int register_access_func(PropertyValue * Value, int write, U1_T * Data) {
StackFrame * frame;
+ RegisterDefinition * def = (RegisterDefinition *)Value->mAccessData;
if (get_frame_info(Value->mContext, Value->mFrame, &frame) < 0) return -1;
- def = get_reg_by_id(Value->mContext, (unsigned)Value->mValue, REGNUM_DWARF);
- if (write) return write_reg_value(frame, def, *Data);
- return read_reg_value(frame, def, Data);
+ if (write) return write_reg_bytes(frame, def, 0, def->size, Data);
+ return read_reg_bytes(frame, def, 0, def->size, Data);
}
static U8_T read_memory(PropertyValue * Value, U8_T Addr, size_t Size) {
@@ -395,16 +394,26 @@ static void evaluate_expression(U8_T BaseAddress, PropertyValue * Value, ELF_Sec
case OP_reg31:
{
unsigned n = Op - OP_reg0;
+ RegisterDefinition * def = NULL;
if (dio_GetPos() - StartPos < Size) str_exception(ERR_INV_DWARF, "OP_reg must be last instruction");
- Value->mValue = n;
+ def = get_reg_by_id(Value->mContext, n, &Unit->mRegIdScope);
+ if (def == NULL) exception(errno);
+ Value->mSize = def->size;
+ Value->mBigEndian = def->big_endian;
+ Value->mAccessData = def;
Value->mAccessFunc = register_access_func;
}
break;
case OP_regx:
{
unsigned n = dio_ReadULEB128();
+ RegisterDefinition * def = NULL;
if (dio_GetPos() - StartPos < Size) str_exception(ERR_INV_DWARF, "OP_regx must be last instruction");
- Value->mValue = n;
+ def = get_reg_by_id(Value->mContext, n, &Unit->mRegIdScope);
+ if (def == NULL) exception(errno);
+ Value->mSize = def->size;
+ Value->mBigEndian = def->big_endian;
+ Value->mAccessData = def;
Value->mAccessFunc = register_access_func;
}
break;
@@ -441,7 +450,8 @@ static void evaluate_expression(U8_T BaseAddress, PropertyValue * Value, ELF_Sec
case OP_breg30:
case OP_breg31:
{
- RegisterDefinition * def = get_reg_by_id(Value->mContext, Op - OP_breg0, REGNUM_DWARF);
+ RegisterDefinition * def = get_reg_by_id(Value->mContext, Op - OP_breg0, &Value->mObject->mCompUnit->mRegIdScope);
+ if (def == NULL) str_exception(errno, "Cannot evaluate DWARF expression");
if (read_reg_value(get_stack_frame(Value), def, sExprStack + sExprStackLen) < 0) exception(errno);
sExprStack[sExprStackLen++] += dio_ReadS8LEB128();
}
@@ -471,7 +481,8 @@ static void evaluate_expression(U8_T BaseAddress, PropertyValue * Value, ELF_Sec
break;
case OP_bregx:
{
- RegisterDefinition * def = get_reg_by_id(Value->mContext, dio_ReadULEB128(), REGNUM_DWARF);
+ RegisterDefinition * def = get_reg_by_id(Value->mContext, dio_ReadULEB128(), &Value->mObject->mCompUnit->mRegIdScope);
+ if (def == NULL) str_exception(errno, "Cannot evaluate DWARF expression");
if (read_reg_value(get_stack_frame(Value), def, sExprStack + sExprStackLen) < 0) exception(errno);
sExprStack[sExprStackLen++] += dio_ReadS8LEB128();
}
@@ -544,7 +555,7 @@ static void evaluate_location(U8_T BaseAddresss, PropertyValue * Value) {
}
}
dio_ExitSection();
- str_exception(ERR_INV_ADDRESS, "No matching entry in .debug_loc for given IP");
+ str_exception(ERR_OTHER, "Object is not available at this location in the code");
}
void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * Value) {
@@ -575,9 +586,9 @@ void dwarf_evaluate_expression(U8_T BaseAddress, PropertyValue * Value) {
if (Value->mAccessFunc == NULL) {
assert(sExprStackLen > 0);
Value->mValue = sExprStack[--sExprStackLen];
+ Value->mSize = 0;
}
Value->mAddr = NULL;
- Value->mSize = 0;
if (Value->mAttr != AT_frame_base) sExprStackLen = 0;
}
diff --git a/services/dwarfframe.c b/services/dwarfframe.c
index f698406d..2e60047c 100644
--- a/services/dwarfframe.c
+++ b/services/dwarfframe.c
@@ -73,6 +73,7 @@ typedef struct StackFrameRegisters {
typedef struct StackFrameRules {
Context * ctx;
ELF_Section * section;
+ RegisterIdScope reg_id_scope;
int eh_frame;
U1_T version;
U1_T address_size;
@@ -126,12 +127,11 @@ static RegisterRules * get_reg(StackFrameRegisters * regs, int reg) {
RegisterDefinition * reg_def;
int n = regs->regs_cnt++;
memset(regs->regs + n, 0, sizeof(RegisterRules));
- reg_def = get_reg_by_id(rules.ctx, n, rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF);
+ reg_def = get_reg_by_id(rules.ctx, n, &rules.reg_id_scope);
if (reg_def == NULL) continue;
/* Architecture specific implied rules */
- switch (rules.section->file->machine) {
- case 3: /* i386 */
- case 6: /* i486 */
+ switch (rules.reg_id_scope.machine) {
+ case EM_386:
switch (n) {
case 4: /* SP */
regs->regs[n].rule = RULE_VAL_OFFSET;
@@ -143,7 +143,7 @@ static RegisterRules * get_reg(StackFrameRegisters * regs, int reg) {
break;
}
break;
- case 62: /* X86 64 */
+ case EM_X86_64:
switch (n) {
case 6: /* BP */
regs->regs[n].rule = RULE_SAME_VALUE;
@@ -554,8 +554,8 @@ static void add_dwarf_expression_commands(U8_T cmds_offs, U4_T cmds_size) {
case OP_breg31:
{
I8_T offs = dio_ReadS8LEB128();
- RegisterDefinition * def = get_reg_by_id(rules.ctx, op - OP_breg0, rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF);
- if (def == NULL) str_exception(ERR_INV_DWARF, "Invalid register index");
+ RegisterDefinition * def = get_reg_by_id(rules.ctx, op - OP_breg0, &rules.reg_id_scope);
+ if (def == NULL) str_exception(errno, "Cannot read DWARF frame info");
add_command(SFT_CMD_REGISTER)->reg = def;
if (offs != 0) {
add_command(SFT_CMD_NUMBER)->num = offs;
@@ -594,7 +594,7 @@ static void generate_register_commands(RegisterRules * reg, RegisterDefinition *
break;
case RULE_REGISTER:
{
- RegisterDefinition * src_sef = get_reg_by_id(rules.ctx, reg->offset, rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF);
+ RegisterDefinition * src_sef = get_reg_by_id(rules.ctx, reg->offset, &rules.reg_id_scope);
if (src_sef != NULL) add_command(SFT_CMD_REGISTER)->reg = src_sef;
}
break;
@@ -633,14 +633,14 @@ static void generate_commands(void) {
if (i == rules.return_address_register) continue;
reg = get_reg(&frame_regs, i);
if (reg->rule == 0) continue;
- reg_def = get_reg_by_id(rules.ctx, i, rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF);
+ reg_def = get_reg_by_id(rules.ctx, i, &rules.reg_id_scope);
generate_register_commands(reg, reg_def);
}
trace_cmds_cnt = 0;
switch (rules.cfa_rule) {
case RULE_OFFSET:
- reg_def = get_reg_by_id(rules.ctx, rules.cfa_register, rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF);
+ reg_def = get_reg_by_id(rules.ctx, rules.cfa_register, &rules.reg_id_scope);
if (reg_def != NULL) {
add_command(SFT_CMD_REGISTER)->reg = reg_def;
if (rules.cfa_offset != 0) {
@@ -757,6 +757,10 @@ void get_dwarf_stack_frame_info(Context * ctx, ELF_File * file, U8_T IP) {
rules.ctx = ctx;
rules.section = section;
rules.eh_frame = section == cache->mEHFrame;
+ rules.reg_id_scope.big_endian = file->big_endian;
+ rules.reg_id_scope.machine = file->machine;
+ rules.reg_id_scope.os_abi = file->os_abi;
+ rules.reg_id_scope.id_type = rules.eh_frame ? REGNUM_EH_FRAME : REGNUM_DWARF;
rules.cie_pos = ~(U8_T)0;
dio_EnterSection(NULL, section, 0);
while (dio_GetPos() < section->size) {
diff --git a/services/expressions.c b/services/expressions.c
index a9841cf6..38a3907f 100644
--- a/services/expressions.c
+++ b/services/expressions.c
@@ -88,6 +88,8 @@ static int text_ch = 0;
static int text_sy = 0;
static Value text_val;
+static int big_endian = 0;
+
static char str_pool[STR_POOL_SIZE];
static int str_pool_cnt = 0;
static StringValue * str_alloc_list = NULL;
@@ -125,6 +127,7 @@ void set_value(Value * v, void * data, size_t size) {
static void set_int_value(Value * v, uint64_t n) {
v->remote = 0;
+ v->big_endian = big_endian;
v->value = alloc_str((size_t)v->size);
switch (v->size) {
case 1: *(uint8_t *)v->value = (uint8_t)n; break;
@@ -147,6 +150,7 @@ static void string_value(Value * v, char * str) {
if (str != NULL) {
size_t size = strlen(str) + 1;
v->size = size;
+ v->big_endian = expression_context->big_endian;
v->value = alloc_str(size);
memcpy(v->value, str, size);
}
@@ -449,6 +453,7 @@ static void next_sy(void) {
text_val.type_class = TYPE_CLASS_INTEGER;
text_val.size = sizeof(uint16_t);
text_val.value = alloc_str(sizeof(uint16_t));
+ text_val.big_endian = big_endian;
text_val.constant = 1;
*(uint16_t *)text_val.value = (uint16_t)next_char_val();
if (text_ch != '\'') error(ERR_INV_EXPRESSION, "Missing 'single quote'");
@@ -476,6 +481,7 @@ static void next_sy(void) {
text_val.type_class = TYPE_CLASS_CARDINAL;
text_val.size = sizeof(uint64_t);
text_val.value = alloc_str((size_t)text_val.size);
+ text_val.big_endian = big_endian;
text_val.constant = 1;
while ((text_ch >= '0' && text_ch <= '9') ||
(text_ch >= 'A' && text_ch <= 'F') ||
@@ -490,6 +496,7 @@ static void next_sy(void) {
text_val.type_class = TYPE_CLASS_INTEGER;
text_val.size = sizeof(int64_t);
text_val.value = alloc_str((size_t)text_val.size);
+ text_val.big_endian = big_endian;
text_val.constant = 1;
while (text_ch >= '0' && text_ch <= '7') {
value = (value << 3) | next_oct();
@@ -514,12 +521,14 @@ static void next_sy(void) {
text_val.type_class = TYPE_CLASS_REAL;
text_val.size = sizeof(double);
text_val.value = alloc_str((size_t)text_val.size);
+ text_val.big_endian = big_endian;
*(double *)text_val.value = x;
}
else {
text_val.type_class = TYPE_CLASS_INTEGER;
text_val.size = sizeof(int64_t);
text_val.value = alloc_str((size_t)text_val.size);
+ text_val.big_endian = big_endian;
*(int64_t *)text_val.value = value;
}
text_val.constant = 1;
@@ -588,11 +597,13 @@ static int sym2value(Symbol * sym, Value * v) {
switch (sym_class) {
case SYM_CLASS_VALUE:
{
+ int endianness = 0;
size_t size = 0;
void * value = NULL;
- if (get_symbol_value(sym, &value, &size) < 0) {
+ if (get_symbol_value(sym, &value, &size, &endianness) < 0) {
error(errno, "Cannot retrieve symbol value");
}
+ v->big_endian = endianness;
v->constant = 1;
v->size = size;
if (value != NULL) {
@@ -603,11 +614,13 @@ static int sym2value(Symbol * sym, Value * v) {
break;
case SYM_CLASS_REFERENCE:
if (get_symbol_address(sym, &v->address) < 0) {
+ int endianness = 0;
size_t size = 0;
void * value = NULL;
- if (get_symbol_value(sym, &value, &size) < 0) {
+ if (get_symbol_value(sym, &value, &size, &endianness) < 0) {
error(errno, "Cannot retrieve symbol value");
}
+ v->big_endian = endianness;
v->size = size;
if (value != NULL) {
v->value = alloc_str((size_t)v->size);
@@ -801,6 +814,22 @@ static int is_whole_number(Value * v) {
return 0;
}
+static void to_host_endianness(Value * v) {
+ assert(v->type_class != TYPE_CLASS_COMPOSITE);
+ assert(v->type_class != TYPE_CLASS_ARRAY);
+ assert(!v->remote);
+ if (v->big_endian != big_endian) {
+ size_t i = 0;
+ size_t n = (size_t)v->size;
+ uint8_t * buf = (uint8_t *)alloc_str(n);
+ for (i = 0; i < n; i++) {
+ buf[i] = ((uint8_t *)v->value)[n - i - 1];
+ }
+ v->value = buf;
+ v->big_endian = big_endian;
+ }
+}
+
static int64_t to_int(int mode, Value * v) {
if (mode != MODE_NORMAL) {
if (v->remote) {
@@ -812,6 +841,7 @@ static int64_t to_int(int mode, Value * v) {
if (v->type_class == TYPE_CLASS_POINTER) {
load_value(v);
+ to_host_endianness(v);
switch (v->size) {
case 1: return *(uint8_t *)v->value;
case 2: return *(uint16_t *)v->value;
@@ -821,6 +851,7 @@ static int64_t to_int(int mode, Value * v) {
}
if (is_number(v)) {
load_value(v);
+ to_host_endianness(v);
if (v->type_class == TYPE_CLASS_REAL) {
switch (v->size) {
@@ -864,6 +895,7 @@ static uint64_t to_uns(int mode, Value * v) {
}
if (v->type_class == TYPE_CLASS_POINTER) {
load_value(v);
+ to_host_endianness(v);
switch (v->size) {
case 1: return *(uint8_t *)v->value;
case 2: return *(uint16_t *)v->value;
@@ -873,6 +905,7 @@ static uint64_t to_uns(int mode, Value * v) {
}
if (is_number(v)) {
load_value(v);
+ to_host_endianness(v);
if (v->type_class == TYPE_CLASS_REAL) {
switch (v->size) {
@@ -913,6 +946,7 @@ static double to_double(int mode, Value * v) {
if (is_number(v)) {
load_value(v);
+ to_host_endianness(v);
if (v->type_class == TYPE_CLASS_REAL) {
switch (v->size) {
@@ -1015,6 +1049,7 @@ static void op_deref(int mode, Value * v) {
}
if (v->type_class == TYPE_CLASS_POINTER) {
v->address = (ContextAddress)to_uns(mode, v);
+ v->big_endian = expression_context->big_endian;
v->remote = 1;
v->constant = 0;
v->value = NULL;
@@ -1129,7 +1164,7 @@ static void op_field(int mode, Value * v) {
if (mode != MODE_TYPE) v->address += offs;
}
else {
- v->value = (char *)v->value + offs;
+ v->value = (uint8_t *)v->value + offs;
}
v->size = size;
if (get_symbol_type(sym, &v->type) < 0) {
@@ -1164,6 +1199,7 @@ static void op_index(int mode, Value * v) {
}
if (v->type_class == TYPE_CLASS_POINTER) {
v->address = (ContextAddress)to_uns(mode, v);
+ v->big_endian = expression_context->big_endian;
v->remote = 1;
v->constant = 0;
v->value = NULL;
@@ -1314,6 +1350,7 @@ static void unary_expression(int mode, Value * v) {
double * value = (double *)alloc_str(sizeof(double));
*value = -to_double(mode, v);
v->type_class = TYPE_CLASS_REAL;
+ v->big_endian = big_endian;
v->size = sizeof(double);
v->value = value;
}
@@ -1321,6 +1358,7 @@ static void unary_expression(int mode, Value * v) {
int64_t * value = (int64_t *)alloc_str(sizeof(int64_t));
*value = -to_int(mode, v);
v->type_class = TYPE_CLASS_INTEGER;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->value = value;
}
@@ -1339,6 +1377,7 @@ static void unary_expression(int mode, Value * v) {
int * value = (int *)alloc_str(sizeof(int));
*value = !to_int(mode, v);
v->type_class = TYPE_CLASS_INTEGER;
+ v->big_endian = big_endian;
v->size = sizeof(int);
v->value = value;
}
@@ -1356,6 +1395,7 @@ static void unary_expression(int mode, Value * v) {
else {
int64_t * value = (int64_t *)alloc_str(sizeof(int64_t));
*value = ~to_int(mode, v);
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->value = value;
}
@@ -1455,6 +1495,7 @@ static void cast_expression(int mode, Value * v) {
v->type_class = type_class;
v->size = type_size;
v->remote = 0;
+ v->big_endian = big_endian;
v->value = alloc_str((size_t)v->size);
switch (v->size) {
case 4: *(float *)v->value = (float)value; break;
@@ -1469,6 +1510,7 @@ static void cast_expression(int mode, Value * v) {
v->type = type;
v->type_class = type_class;
v->size = type_size;
+ v->big_endian = expression_context->big_endian;
v->remote = 1;
v->constant = 0;
v->value = NULL;
@@ -1511,6 +1553,7 @@ static void multiplicative_expression(int mode, Value * v) {
}
}
v->type_class = TYPE_CLASS_REAL;
+ v->big_endian = big_endian;
v->size = sizeof(double);
v->value = value;
}
@@ -1524,6 +1567,7 @@ static void multiplicative_expression(int mode, Value * v) {
}
}
v->type_class = TYPE_CLASS_CARDINAL;
+ v->big_endian = big_endian;
v->size = sizeof(uint64_t);
v->value = value;
}
@@ -1537,6 +1581,7 @@ static void multiplicative_expression(int mode, Value * v) {
}
}
v->type_class = TYPE_CLASS_INTEGER;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->value = value;
}
@@ -1598,6 +1643,7 @@ static void additive_expression(int mode, Value * v) {
case '-': *value = to_double(mode, v) - to_double(mode, &x); break;
}
v->type_class = TYPE_CLASS_REAL;
+ v->big_endian = big_endian;
v->size = sizeof(double);
v->value = value;
v->type = NULL;
@@ -1609,6 +1655,7 @@ static void additive_expression(int mode, Value * v) {
case '-': *value = to_uns(mode, v) - to_uns(mode, &x); break;
}
v->type_class = TYPE_CLASS_CARDINAL;
+ v->big_endian = big_endian;
v->size = sizeof(uint64_t);
v->value = value;
v->type = NULL;
@@ -1620,6 +1667,7 @@ static void additive_expression(int mode, Value * v) {
case '-': *value = to_int(mode, v) - to_int(mode, &x); break;
}
v->type_class = TYPE_CLASS_INTEGER;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->value = value;
v->type = NULL;
@@ -1673,6 +1721,7 @@ static void shift_expression(int mode, Value * v) {
}
}
v->value = value;
+ v->big_endian = big_endian;
v->size = sizeof(uint64_t);
v->remote = 0;
v->constant = v->constant && x.constant;
@@ -1689,7 +1738,7 @@ static void relational_expression(int mode, Value * v) {
next_sy();
shift_expression(mode, &x);
if (mode != MODE_SKIP) {
- int * value = (int *)alloc_str(sizeof(int));
+ uint32_t * value = (uint32_t *)alloc_str(sizeof(uint32_t));
if (v->type_class == TYPE_CLASS_ARRAY && x.type_class == TYPE_CLASS_ARRAY) {
int n = 0;
load_value(v);
@@ -1729,7 +1778,8 @@ static void relational_expression(int mode, Value * v) {
if (mode != MODE_NORMAL) *value = 0;
v->type_class = TYPE_CLASS_INTEGER;
v->value = value;
- v->size = sizeof(int);
+ v->big_endian = big_endian;
+ v->size = sizeof(uint32_t);
v->remote = 0;
v->constant = v->constant && x.constant;
v->type = NULL;
@@ -1745,7 +1795,7 @@ static void equality_expression(int mode, Value * v) {
next_sy();
relational_expression(mode, &x);
if (mode != MODE_SKIP) {
- int * value = (int *)alloc_str(sizeof(int));
+ uint32_t * value = (uint32_t *)alloc_str(sizeof(uint32_t));
if (v->type_class == TYPE_CLASS_ARRAY && x.type_class == TYPE_CLASS_ARRAY) {
load_value(v);
load_value(&x);
@@ -1761,7 +1811,8 @@ static void equality_expression(int mode, Value * v) {
if (mode != MODE_NORMAL) *value = 0;
v->type_class = TYPE_CLASS_INTEGER;
v->value = value;
- v->size = sizeof(int);
+ v->big_endian = big_endian;
+ v->size = sizeof(uint32_t);
v->remote = 0;
v->constant = v->constant && x.constant;
v->type = NULL;
@@ -1789,6 +1840,7 @@ static void and_expression(int mode, Value * v) {
}
if (mode != MODE_NORMAL) *value = 0;
v->value = value;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->remote = 0;
v->constant = v->constant && x.constant;
@@ -1817,6 +1869,7 @@ static void exclusive_or_expression(int mode, Value * v) {
}
if (mode != MODE_NORMAL) *value = 0;
v->value = value;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->remote = 0;
v->constant = v->constant && x.constant;
@@ -1845,6 +1898,7 @@ static void inclusive_or_expression(int mode, Value * v) {
}
if (mode != MODE_NORMAL) *value = 0;
v->value = value;
+ v->big_endian = big_endian;
v->size = sizeof(int64_t);
v->remote = 0;
v->constant = v->constant && x.constant;
@@ -2442,6 +2496,13 @@ static void command_evaluate_cache_client(void * x) {
cnt++;
}
#endif
+ if (value.big_endian) {
+ if (cnt > 0) write_stream(&c->out, ',');
+ json_write_string(&c->out, "BigEndian");
+ write_stream(&c->out, ':');
+ json_write_boolean(&c->out, 1);
+ cnt++;
+ }
write_stream(&c->out, '}');
write_stream(&c->out, 0);
@@ -2543,6 +2604,12 @@ void add_identifier_callback(ExpressionIdentifierCallBack * callback) {
id_callbacks[id_callback_cnt++] = callback;
}
+static int is_big_endian_host(void) {
+ uint16_t n = 0x0201;
+ uint8_t * p = (uint8_t *)&n;
+ return *p == 0x02;
+}
+
void ini_expressions_service(Protocol * proto) {
unsigned i;
list_init(&expressions);
@@ -2554,6 +2621,8 @@ void ini_expressions_service(Protocol * proto) {
add_command_handler(proto, EXPRESSIONS, "evaluate", command_evaluate);
add_command_handler(proto, EXPRESSIONS, "assign", command_assign);
add_command_handler(proto, EXPRESSIONS, "dispose", command_dispose);
+
+ big_endian = is_big_endian_host();
}
#endif /* if SERVICE_Expressions */
diff --git a/services/expressions.h b/services/expressions.h
index a88b9d19..c99324d7 100644
--- a/services/expressions.h
+++ b/services/expressions.h
@@ -32,6 +32,7 @@ struct Value {
ContextAddress size; /* Value size in bytes */
int remote; /* 1 if value data is in remote target memory, 0 if loaded into a local buffer */
int constant; /* 1 if value is not expected to change during execution of value context */
+ int big_endian; /* 1 if value is big endian */
};
typedef struct Value Value;
diff --git a/services/symbols.c b/services/symbols.c
index 7f6a02df..e053499c 100644
--- a/services/symbols.c
+++ b/services/symbols.c
@@ -50,6 +50,7 @@ static void command_get_context_cache_client(void * x) {
int has_lower_bound = 0;
int has_offset = 0;
int has_address = 0;
+ int big_endian = 0;
ContextAddress size = 0;
ContextAddress length = 0;
int64_t lower_bound = 0;
@@ -80,7 +81,7 @@ static void command_get_context_cache_client(void * x) {
has_address = get_symbol_address(sym, &address) == 0;
}
if (sym_class == SYM_CLASS_VALUE) {
- get_symbol_value(sym, &value, &value_size);
+ get_symbol_value(sym, &value, &value_size, &big_endian);
}
}
@@ -191,6 +192,13 @@ static void command_get_context_cache_client(void * x) {
write_stream(&c->out, ':');
json_write_binary(&c->out, value, value_size);
write_stream(&c->out, ',');
+
+ if (big_endian) {
+ json_write_string(&c->out, "BigEndian");
+ write_stream(&c->out, ':');
+ json_write_boolean(&c->out, 1);
+ write_stream(&c->out, ',');
+ }
}
json_write_string(&c->out, "Class");
diff --git a/services/symbols.h b/services/symbols.h
index 87948de6..bc53b4e4 100644
--- a/services/symbols.h
+++ b/services/symbols.h
@@ -154,7 +154,7 @@ extern int get_symbol_offset(const Symbol * sym, ContextAddress * offset);
/* Get value (constant objects and enums).
* The array returned shall not be modified by the client,
* and it may be overwritten by a subsequent calls to symbol functions */
-extern int get_symbol_value(const Symbol * sym, void ** value, size_t * size);
+extern int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big_endian);
/* Get address (variables) */
extern int get_symbol_address(const Symbol * sym, ContextAddress * address);
diff --git a/services/symbols_elf.c b/services/symbols_elf.c
index 19291b45..590ba59c 100644
--- a/services/symbols_elf.c
+++ b/services/symbols_elf.c
@@ -1735,7 +1735,7 @@ int get_symbol_offset(const Symbol * sym, ContextAddress * offset) {
return -1;
}
-int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
+int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big_endian) {
assert(sym->magic == SYMBOL_MAGIC);
if (sym->base || is_cardinal_type_pseudo_symbol(sym)) {
errno = ERR_INV_CONTEXT;
@@ -1763,6 +1763,7 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
*size = sizeof(bf);
*value = bf;
}
+ *big_endian = v.mBigEndian;
clear_trap(&trap);
return 0;
}
@@ -1775,16 +1776,12 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
exception(ERR_INV_CONTEXT);
}
else {
- static U1_T bf[sizeof(v.mValue)];
- U8_T n = 0;
- size_t i = 0;
- if (v.mAccessFunc(&v, 0, &n)) exception(errno);
- for (i = 0; i < sizeof(bf); i++) {
- bf[v.mBigEndian ? sizeof(bf) - i - 1 : i] = n & 0xffu;
- n = n >> 8;
- }
- *size = sizeof(bf);
+ static U1_T bf[32];
+ if (v.mSize > sizeof(bf)) exception(ERR_BUFFER_OVERFLOW);
+ if (v.mAccessFunc(&v, 0, bf) < 0) exception(errno);
+ *size = v.mSize;
*value = bf;
+ *big_endian = v.mBigEndian;
}
clear_trap(&trap);
return 0;
diff --git a/services/symbols_proxy.c b/services/symbols_proxy.c
index 8f479b11..b9d39841 100644
--- a/services/symbols_proxy.c
+++ b/services/symbols_proxy.c
@@ -79,6 +79,7 @@ typedef struct SymInfoCache {
int64_t upper_bound;
char * value;
size_t value_size;
+ int big_endian;
char ** children_ids;
int children_count;
ReplyHandlerInfo * pending_get_context;
@@ -351,6 +352,7 @@ static void read_context_data(InputStream * inp, const char * name, void * args)
else if (strcmp(name, "Offset") == 0) { s->offset = json_read_long(inp); s->has_offset = 1; }
else if (strcmp(name, "Address") == 0) { s->address = (ContextAddress)json_read_uint64(inp); s->has_address = 1; }
else if (strcmp(name, "Value") == 0) s->value = json_read_alloc_binary(inp, &s->value_size);
+ else if (strcmp(name, "BigEndian") == 0) s->big_endian = json_read_boolean(inp);
else json_skip_object(inp);
}
@@ -868,7 +870,7 @@ int get_symbol_offset(const Symbol * sym, ContextAddress * offset) {
return 0;
}
-int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
+int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big_endian) {
SymInfoCache * c = get_sym_info_cache(sym);
if (c == NULL) return -1;
if (c->sym_class != SYM_CLASS_VALUE) {
@@ -877,6 +879,7 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
}
*value = c->value;
*size = c->value_size;
+ *big_endian = c->big_endian;
return 0;
}
diff --git a/services/symbols_win32.c b/services/symbols_win32.c
index e25b335e..768551c8 100644
--- a/services/symbols_win32.c
+++ b/services/symbols_win32.c
@@ -673,7 +673,7 @@ int get_symbol_offset(const Symbol * sym, ContextAddress * offset) {
return 0;
}
-int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
+int get_symbol_value(const Symbol * sym, void ** value, size_t * size, int * big_endian) {
static VARIANT data;
VARTYPE vt;
void * data_addr = &data.bVal;
@@ -721,6 +721,7 @@ int get_symbol_value(const Symbol * sym, void ** value, size_t * size) {
*size = data_size;
*value = data_addr;
+ *big_endian = 0;
return 0;
}
diff --git a/services/tcf_elf.c b/services/tcf_elf.c
index 74652208..9bb3784e 100644
--- a/services/tcf_elf.c
+++ b/services/tcf_elf.c
@@ -392,6 +392,7 @@ static ELF_File * create_elf_cache(const char * file_name) {
}
file->type = hdr.e_type;
file->machine = hdr.e_machine;
+ file->os_abi = hdr.e_ident[EI_OSABI];
if (error == 0 && hdr.e_type != ET_EXEC && hdr.e_type != ET_DYN && hdr.e_type != ET_REL) {
error = set_errno(ERR_INV_FORMAT, "Invalid ELF type ID");
}
@@ -502,6 +503,7 @@ static ELF_File * create_elf_cache(const char * file_name) {
}
file->type = hdr.e_type;
file->machine = hdr.e_machine;
+ file->os_abi = hdr.e_ident[EI_OSABI];
if (error == 0 && hdr.e_type != ET_EXEC && hdr.e_type != ET_DYN && hdr.e_type != ET_REL) {
error = set_errno(ERR_INV_FORMAT, "Invalid ELF type ID");
}
diff --git a/services/tcf_elf.h b/services/tcf_elf.h
index 521b95de..04f3e24b 100644
--- a/services/tcf_elf.h
+++ b/services/tcf_elf.h
@@ -335,6 +335,16 @@ typedef struct {
#endif
+#ifndef EM_X86_64
+#define EM_X86_64 62
+#endif
+#ifndef EM_PPC
+#define EM_PPC 20
+#endif
+#ifndef EM_PPC64
+#define EM_PPC64 21
+#endif
+
typedef struct ElfX_Sym {
union {
Elf32_Sym Elf32;
@@ -367,11 +377,12 @@ struct ELF_File {
ErrorReport * error;
int fd;
- int big_endian; /* 0 - least significant first, 1 - most significat first */
- int byte_swap; /* > 0 if file endianness not same as the agent endianness */
- int elf64;
- int type;
- int machine;
+ uint8_t big_endian; /* 0 - least significant first, 1 - most significat first */
+ uint8_t byte_swap; /* > 0 if file endianness not same as the agent endianness */
+ uint8_t elf64;
+ uint16_t type;
+ uint16_t machine;
+ uint8_t os_abi;
unsigned section_cnt;
ELF_Section * sections;
diff --git a/system/GNU/Linux/context-linux.c b/system/GNU/Linux/context-linux.c
index 576fecd3..e7666a29 100644
--- a/system/GNU/Linux/context-linux.c
+++ b/system/GNU/Linux/context-linux.c
@@ -932,6 +932,7 @@ static int expression_identifier_callback(Context * ctx, int frame, char * name,
v->address = elf_get_debug_structure_address(ctx, NULL);
v->type_class = TYPE_CLASS_POINTER;
v->size = context_word_size(ctx);
+ v->big_endian = ctx->big_endian;
if (v->address != 0) {
switch (v->size) {
case 4: v->address += 8; break;

Back to the top