Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2016-02-20 21:02:36 -0500
committerEugene Tarassov2016-02-20 21:03:16 -0500
commitafff85a6cb7f15edc00139f9adbbd23c2e28549e (patch)
tree20d05c6278606c02a5baceb7a246d8911f4ecdd2
parentb9d3ea3b496a54a058ece35147bde0e152be7d9a (diff)
downloadorg.eclipse.tcf.agent-afff85a6cb7f15edc00139f9adbbd23c2e28549e.tar.gz
org.eclipse.tcf.agent-afff85a6cb7f15edc00139f9adbbd23c2e28549e.tar.xz
org.eclipse.tcf.agent-afff85a6cb7f15edc00139f9adbbd23c2e28549e.zip
TCF Agent: DWARF symbol reader improvements
1. better handling of array and structs of variable size 2. better handling of typed location expressions 3. fixed issues in handling debug info in a separate file
-rw-r--r--agent/tcf/framework/cpudefs.c3
-rw-r--r--agent/tcf/framework/cpudefs.h3
-rw-r--r--agent/tcf/services/dwarfcache.c2
-rw-r--r--agent/tcf/services/dwarfecomp.c180
-rw-r--r--agent/tcf/services/dwarfexpr.c5
-rw-r--r--agent/tcf/services/symbols_elf.c5
-rw-r--r--agent/tcf/services/tcf_elf.c25
-rw-r--r--agent/tcf/services/vm.c60
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c90
9 files changed, 276 insertions, 97 deletions
diff --git a/agent/tcf/framework/cpudefs.c b/agent/tcf/framework/cpudefs.c
index cc94a467..de9b5edd 100644
--- a/agent/tcf/framework/cpudefs.c
+++ b/agent/tcf/framework/cpudefs.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2014 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -404,6 +404,7 @@ LocationExpressionState * evaluate_location_expression(Context * ctx, StackFrame
break;
case SFT_CMD_LOCATION:
state->stk = stk;
+ state->type_stk = (uint8_t *)tmp_alloc_zero(stk_max);
state->stk_pos = stk_pos;
state->stk_max = stk_max;
state->reg_id_scope = cmd->args.loc.reg_id_scope;
diff --git a/agent/tcf/framework/cpudefs.h b/agent/tcf/framework/cpudefs.h
index 1c243220..8f398977 100644
--- a/agent/tcf/framework/cpudefs.h
+++ b/agent/tcf/framework/cpudefs.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -164,6 +164,7 @@ typedef struct LocationExpressionState {
unsigned stk_pos;
unsigned stk_max;
uint64_t * stk;
+ uint8_t * type_stk;
} LocationExpressionState;
typedef int LocationExpressionCallback(LocationExpressionState *);
diff --git a/agent/tcf/services/dwarfcache.c b/agent/tcf/services/dwarfcache.c
index 3c997943..816a2d31 100644
--- a/agent/tcf/services/dwarfcache.c
+++ b/agent/tcf/services/dwarfcache.c
@@ -861,6 +861,8 @@ static void read_object_info(U2_T Tag, U2_T Attr, U2_T Form) {
case AT_static_link:
case AT_use_location:
case AT_vtable_elem_location:
+ case AT_upper_bound:
+ case AT_lower_bound:
/* Note: FORM_DATA4, FORM_DATA8 and FORM_SEC_OFFSET are location lists.
* Location list needs PC, so we set DOIF_need_frame because of that */
if (Form == FORM_DATA4 || Form == FORM_DATA8 || Form == FORM_SEC_OFFSET) {
diff --git a/agent/tcf/services/dwarfecomp.c b/agent/tcf/services/dwarfecomp.c
index 779f7423..e28cc393 100644
--- a/agent/tcf/services/dwarfecomp.c
+++ b/agent/tcf/services/dwarfecomp.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2011, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -764,20 +764,27 @@ static void op_parameter_ref(void) {
if (args->mTag == TAG_GNU_call_site_parameter && args->mFlags & DOIF_abstract_origin) {
read_and_evaluate_dwarf_object_property(expr_ctx, STACK_NO_FRAME, args, AT_abstract_origin, &pv);
if (get_numeric_property_value(&pv) == ref_id) {
- read_dwarf_object_property(expr_ctx, STACK_NO_FRAME, args, AT_GNU_call_site_value, &pv);
- dwarf_get_expression_list(&pv, info_last);
- while (*info_last != NULL) {
- DWARFExpressionInfo * e = *info_last;
- if (e->code_size == 0 ||
- (e->code_addr <= site->u.mCode.mLowPC &&
- e->code_addr + e->code_size > site->u.mCode.mLowPC)) {
- e->code_addr = site->u.mCode.mLowPC;
- e->code_size = 1;
- info_last = &e->next;
- }
- else {
- *info_last = e->next;
+ Trap trap;
+ if (set_trap(&trap)) {
+ read_dwarf_object_property(expr_ctx, STACK_NO_FRAME, args, AT_GNU_call_site_value, &pv);
+ dwarf_get_expression_list(&pv, info_last);
+ while (*info_last != NULL) {
+ DWARFExpressionInfo * e = *info_last;
+ if (e->code_size == 0 ||
+ (e->code_addr <= site->u.mCode.mLowPC &&
+ e->code_addr + e->code_size > site->u.mCode.mLowPC)) {
+ e->code_addr = site->u.mCode.mLowPC;
+ e->code_size = 1;
+ info_last = &e->next;
+ }
+ else {
+ *info_last = e->next;
+ }
}
+ clear_trap(&trap);
+ }
+ else if (get_error_code(errno) != ERR_SYM_NOT_FOUND) {
+ str_exception(errno, "Cannot read value of call site parameter");
}
}
}
@@ -829,6 +836,17 @@ static void check_frame(void) {
str_exception(ERR_OTHER, "Object location is relative to a stack frame");
}
+static void get_type(U8_T type, U2_T * fund_type, U8_T * byte_size) {
+ ObjectInfo * obj = find_object(
+ expr->object->mCompUnit->mDesc.mSection,
+ expr->object->mCompUnit->mDesc.mSection->addr +
+ expr->object->mCompUnit->mDesc.mUnitOffs + type);
+ if (obj == NULL) str_exception(ERR_INV_DWARF, "Invalid type reference in DWARF expression");
+ if (obj->mTag != TAG_base_type) str_exception(ERR_INV_DWARF, "Invalid type object tag in DWARF expression");
+ if (!get_num_prop(obj, AT_byte_size, byte_size)) str_exception(ERR_INV_DWARF, "Invalid type size in DWARF expression");
+ *fund_type = obj->u.mFundType;
+}
+
static void add_expression(DWARFExpressionInfo * info) {
DWARFExpressionInfo * org_expr = expr;
size_t org_expr_pos = expr_pos;
@@ -999,14 +1017,12 @@ static void add_expression(DWARFExpressionInfo * info) {
{
U8_T type = read_u8leb128();
unsigned size = expr->expr_addr[expr_pos++];
+ U2_T fund_type = 0;
+ U8_T byte_size = 0;
int sign = 0;
- ObjectInfo * obj = find_object(
- expr->object->mCompUnit->mDesc.mSection,
- expr->object->mCompUnit->mDesc.mSection->addr +
- expr->object->mCompUnit->mDesc.mUnitOffs + type);
- if (obj == NULL) str_exception(ERR_INV_DWARF, "Invalid reference in OP_GNU_const_type");
- if (obj->mTag != TAG_base_type) str_exception(ERR_INV_DWARF, "Invalid object tag in OP_GNU_const_type");
- switch (obj->u.mFundType) {
+ int ok = 1;
+ get_type(type, &fund_type, &byte_size);
+ switch (fund_type) {
case ATE_address:
case ATE_unsigned:
case ATE_unsigned_char:
@@ -1019,15 +1035,25 @@ static void add_expression(DWARFExpressionInfo * info) {
sign = 1;
break;
default:
- str_exception(ERR_INV_DWARF, "Unsupported type in OP_GNU_const_type");
+ ok = 0;
break;
}
- switch (size) {
- case 1: add(sign ? OP_const1s : OP_const1u); break;
- case 2: add(sign ? OP_const2s : OP_const2u); break;
- case 4: add(sign ? OP_const4s : OP_const4u); break;
- case 8: add(sign ? OP_const8s : OP_const8u); break;
- default: str_exception(ERR_INV_DWARF, "Invalid size in OP_GNU_const_type");
+ if (ok) {
+ switch (size) {
+ case 1: add(sign ? OP_const1s : OP_const1u); break;
+ case 2: add(sign ? OP_const2s : OP_const2u); break;
+ case 4: add(sign ? OP_const4s : OP_const4u); break;
+ case 8: add(sign ? OP_const8s : OP_const8u); break;
+ default:
+ ok = 0;
+ break;
+ }
+ }
+ if (!ok) {
+ add(OP_GNU_const_type);
+ add_uleb128(fund_type);
+ add_uleb128(byte_size);
+ add_uleb128(size);
}
copy(size);
}
@@ -1035,50 +1061,90 @@ static void add_expression(DWARFExpressionInfo * info) {
case OP_GNU_regval_type:
expr_pos++;
{
- U8_T size = 0;
U4_T reg = read_u4leb128();
U8_T type = read_u8leb128();
- ObjectInfo * obj = find_object(
- expr->object->mCompUnit->mDesc.mSection,
- expr->object->mCompUnit->mDesc.mSection->addr +
- expr->object->mCompUnit->mDesc.mUnitOffs + type);
- if (obj == NULL) str_exception(ERR_INV_DWARF, "Invalid reference in OP_GNU_regval_type");
- if (!get_num_prop(obj, AT_byte_size, &size)) str_exception(ERR_INV_DWARF, "Invalid reference in OP_GNU_regval_type");
- add(OP_regx);
- add_uleb128(reg);
- add(OP_piece);
- add_uleb128(size);
+ U2_T fund_type = 0;
+ U8_T byte_size = 0;
+ int ok = 0;
+ get_type(type, &fund_type, &byte_size);
+ if (expr_pos == info->expr_size) {
+ switch (fund_type) {
+ case ATE_address:
+ case ATE_unsigned:
+ case ATE_unsigned_char:
+ case ATE_unsigned_fixed:
+ case ATE_UTF:
+ ok = 1;
+ add(OP_regx);
+ add_uleb128(reg);
+ add(OP_piece);
+ add_uleb128(byte_size);
+ break;
+ }
+ }
+ if (!ok) {
+ add(OP_GNU_regval_type);
+ add_uleb128(reg);
+ add_uleb128(fund_type);
+ add_uleb128(byte_size);
+ }
+ }
+ break;
+ case OP_GNU_deref_type:
+ expr_pos++;
+ {
+ unsigned size = expr->expr_addr[expr_pos++];
+ U8_T type = read_u8leb128();
+ U2_T fund_type = 0;
+ U8_T byte_size = 0;
+ int ok = 0;
+ get_type(type, &fund_type, &byte_size);
+ switch (fund_type) {
+ case ATE_address:
+ case ATE_unsigned:
+ case ATE_unsigned_char:
+ case ATE_unsigned_fixed:
+ case ATE_UTF:
+ ok = 1;
+ add(OP_deref_size);
+ add(size);
+ break;
+ }
+ if (!ok) {
+ add(OP_GNU_deref_type);
+ add_uleb128(size);
+ add_uleb128(fund_type);
+ add_uleb128(byte_size);
+ }
}
break;
case OP_GNU_convert:
expr_pos++;
{
U8_T type = read_u8leb128();
+ U2_T fund_type = 0;
+ U8_T byte_size = 0;
+ int ok = 0;
if (type == 0) {
/* 0 means to cast the value back to the "implicit" type */
}
else {
- U8_T size = 0;
- ObjectInfo * obj = find_object(
- expr->object->mCompUnit->mDesc.mSection,
- expr->object->mCompUnit->mDesc.mSection->addr +
- expr->object->mCompUnit->mDesc.mUnitOffs + type);
- if (obj != NULL && obj->mTag == TAG_base_type && get_num_prop(obj, AT_byte_size, &size)) {
- switch (obj->u.mFundType) {
- case ATE_unsigned:
- if (size < 8) {
- add(OP_constu);
- add_uleb128(((U8_T)1 << (size * 8)) - 1);
- add(OP_and);
- }
- break;
- default:
- str_exception(ERR_INV_DWARF, "Unsupported type in OP_GNU_convert");
- break;
+ get_type(type, &fund_type, &byte_size);
+ switch (fund_type) {
+ case ATE_unsigned:
+ if (byte_size < 8) {
+ add(OP_constu);
+ add_uleb128(((U8_T)1 << (byte_size * 8)) - 1);
+ add(OP_and);
+ ok = 1;
}
break;
}
- str_exception(ERR_INV_DWARF, "Invalid reference in OP_GNU_convert");
+ }
+ if (!ok) {
+ add(OP_GNU_convert);
+ add_uleb128(fund_type);
+ add_uleb128(byte_size);
}
}
break;
diff --git a/agent/tcf/services/dwarfexpr.c b/agent/tcf/services/dwarfexpr.c
index a7c21967..af2f05f0 100644
--- a/agent/tcf/services/dwarfexpr.c
+++ b/agent/tcf/services/dwarfexpr.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2008, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2008, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -111,7 +111,8 @@ void dwarf_evaluate_expression(PropertyValue * Value, uint64_t * args, unsigned
DWARFExpressionInfo * Info = NULL;
State = (LocationExpressionState *)tmp_alloc_zero(sizeof(LocationExpressionState));
- State->stk = (U8_T *)tmp_alloc(sizeof(U8_T) * (State->stk_max = 8));
+ State->stk = (uint64_t *)tmp_alloc(sizeof(uint64_t) * (State->stk_max = 8));
+ State->type_stk = (uint8_t *)tmp_alloc_zero(State->stk_max);
State->ctx = Value->mContext;
if (Value->mFrame != STACK_NO_FRAME &&
get_frame_info(Value->mContext, Value->mFrame, &State->stack_frame) < 0)
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index 3e17b174..d6168377 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -385,6 +385,7 @@ static int is_frame_based_object(Symbol * sym) {
if (sym->var != NULL) return 1;
if (sym->obj != NULL && (sym->obj->mFlags & DOIF_need_frame)) return 1;
+ if (sym->ref != NULL && (sym->ref->mFlags & DOIF_need_frame)) return 1;
switch (sym->sym_class) {
case SYM_CLASS_VALUE:
@@ -602,7 +603,9 @@ static void object2symbol(ObjectInfo * ref, ObjectInfo * obj, Symbol ** res) {
sym->sym_class = SYM_CLASS_VARIANT;
break;
}
+ sym->ref = ref;
sym->frame = STACK_NO_FRAME;
+ if (sym->sym_class == SYM_CLASS_REFERENCE && obj->mTag != TAG_member) sym->ref = obj;
sym->ctx = context_get_group(sym_ctx, CONTEXT_GROUP_SYMBOLS);
if (sym_frame != STACK_NO_FRAME && is_frame_based_object(sym)) {
sym->frame = sym_frame;
@@ -611,8 +614,6 @@ static void object2symbol(ObjectInfo * ref, ObjectInfo * obj, Symbol ** res) {
else if (sym_ctx != sym->ctx && is_thread_based_object(sym)) {
sym->ctx = sym_ctx;
}
- sym->ref = ref;
- if (sym->sym_class == SYM_CLASS_REFERENCE && obj->mTag != TAG_member) sym->ref = obj;
sym->priority = (int8_t)symbol_priority(obj);
sym->weak = (int8_t)symbol_is_weak(obj);
*res = sym;
diff --git a/agent/tcf/services/tcf_elf.c b/agent/tcf/services/tcf_elf.c
index 8d452a3d..dfa71a40 100644
--- a/agent/tcf/services/tcf_elf.c
+++ b/agent/tcf/services/tcf_elf.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -1091,8 +1091,7 @@ static U8_T get_pheader_file_size(ELF_File * file, ELF_PHeader * p, MemoryRegion
return p->file_size;
}
-static U8_T get_pheader_address(ELF_File * file, ELF_PHeader * p) {
- ELF_File * debug = get_dwarf_file(file);
+static U8_T get_debug_pheader_address(ELF_File * file, ELF_File * debug, ELF_PHeader * p) {
assert(p >= file->pheaders && p < file->pheaders + file->pheader_cnt);
/* p->address is not valid if the file is exec file with split debug info */
if (file != debug) {
@@ -1588,7 +1587,7 @@ UnitAddressRange * elf_find_unit(Context * ctx, ContextAddress addr_min, Context
ELF_PHeader * p = file->pheaders + j;
ELF_Section * sec = NULL;
if (!is_p_header_region(file, p, r)) continue;
- pheader_address = get_pheader_address(file, p);
+ pheader_address = get_debug_pheader_address(file, debug, p);
pheader_file_size = get_pheader_file_size(file, p, r);
offs_min = addr_min - r->addr + r->file_offs;
offs_max = addr_max - r->addr + r->file_offs;
@@ -1627,6 +1626,8 @@ UnitAddressRange * elf_find_unit(Context * ctx, ContextAddress addr_min, Context
}
ContextAddress elf_run_time_address_in_region(Context * ctx, MemoryRegion * r, ELF_File * file, ELF_Section * sec, ContextAddress addr) {
+ /* Note: when debug info is in a separate file, debug file link-time addresses are not same as exec file link-time addresses,
+ * because Linux has a habbit of re-linking execs after extracting debug info */
unsigned i;
errno = 0;
if (r->sect_name == NULL) {
@@ -1666,7 +1667,6 @@ ContextAddress elf_map_to_run_time_address(Context * ctx, ELF_File * file, ELF_S
if (elf_get_map(ctx, 0, ~(ContextAddress)0, &elf_map) < 0) return 0;
for (i = 0; i < elf_map.region_cnt; i++) {
MemoryRegion * r = elf_map.regions + i;
- ELF_File * exec = file;
int same_file = 0;
if (r->dev == 0) {
same_file = file_name_equ(file, r->file_name);
@@ -1678,19 +1678,20 @@ ContextAddress elf_map_to_run_time_address(Context * ctx, ELF_File * file, ELF_S
}
if (!same_file) {
/* Check if the memory map entry has a separate debug info file */
+ ELF_File * exec = NULL;
if (!file->debug_info_file) continue;
exec = elf_open_memory_region_file(r, NULL);
if (exec == NULL) continue;
if (get_dwarf_file(exec) != file) continue;
}
- rt = elf_run_time_address_in_region(ctx, r, exec, sec, addr);
+ rt = elf_run_time_address_in_region(ctx, r, file, sec, addr);
if (errno == 0) return rt;
}
if (file->type == ET_EXEC) {
errno = 0;
return addr;
}
- errno = ERR_INV_ADDRESS;
+ errno = set_errno(ERR_INV_ADDRESS, "Invalid memory map, cannot compute run-time address");
return 0;
}
@@ -1710,21 +1711,21 @@ ContextAddress elf_map_to_link_time_address(Context * ctx, ContextAddress addr,
if (r->sect_name == NULL) {
unsigned j;
if (f->pheader_cnt == 0 && f->type == ET_EXEC) {
- *file = d;
if (sec != NULL) *sec = find_section_by_address(d, addr, to_dwarf);
+ *file = d;
errno = 0;
return addr;
}
for (j = 0; j < f->pheader_cnt; j++) {
U8_T offs = addr - r->addr + r->file_offs;
- U8_T pheader_address = 0;
ELF_PHeader * p = f->pheaders + j;
+ U8_T pheader_address = 0;
if (!is_p_header_region(f, p, r)) continue;
if (offs < p->offset || offs >= p->offset + p->mem_size) continue;
- *file = d;
- pheader_address = to_dwarf ? get_pheader_address(f, p) : p->address;
+ pheader_address = get_debug_pheader_address(f, d, p);
addr = (ContextAddress)(offs - p->offset + pheader_address);
if (sec != NULL) *sec = find_section_by_address(d, addr, to_dwarf);
+ *file = d;
errno = 0;
return addr;
}
@@ -1734,9 +1735,9 @@ ContextAddress elf_map_to_link_time_address(Context * ctx, ContextAddress addr,
for (j = 1; j < d->section_cnt; j++) {
ELF_Section * s = d->sections + j;
if (strcmp(s->name, r->sect_name) == 0) {
- *file = d;
addr = (ContextAddress)(addr - r->addr + s->addr);
if (sec != NULL) *sec = s;
+ *file = d;
errno = 0;
return addr;
}
diff --git a/agent/tcf/services/vm.c b/agent/tcf/services/vm.c
index 6832bbf6..60343f8e 100644
--- a/agent/tcf/services/vm.c
+++ b/agent/tcf/services/vm.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2011, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -26,6 +26,7 @@
#include <tcf/framework/myalloc.h>
#include <tcf/framework/exceptions.h>
#include <tcf/services/stacktrace.h>
+#include <tcf/services/symbols.h>
#include <tcf/services/dwarf.h>
#include <tcf/services/vm.h>
@@ -194,6 +195,7 @@ static int is_end_of_loc_expr(void) {
static void evaluate_expression(void) {
uint64_t data = 0;
+ uint8_t type = 0;
if (code_len == 0) inv_dwarf("location expression size = 0");
@@ -204,57 +206,73 @@ static void evaluate_expression(void) {
if (state->stk_pos + 4 > state->stk_max) {
state->stk_max += 8;
state->stk = (uint64_t *)tmp_realloc(state->stk, sizeof(uint64_t) * state->stk_max);
+ state->type_stk = (uint8_t *)tmp_realloc(state->type_stk, sizeof(uint8_t) * state->stk_max);
}
switch (op) {
case OP_deref:
check_e_stack(1);
state->stk[state->stk_pos - 1] = read_memory(state->stk[state->stk_pos - 1], state->addr_size);
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_deref2:
check_e_stack(1);
state->stk[state->stk_pos - 1] = (int16_t)read_memory(state->stk[state->stk_pos - 1], 2);
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_deref_size:
check_e_stack(1);
state->stk[state->stk_pos - 1] = read_memory(state->stk[state->stk_pos - 1], read_u1());
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const:
state->stk[state->stk_pos++] = read_ia();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const1u:
state->stk[state->stk_pos++] = read_u1();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const1s:
state->stk[state->stk_pos++] = (int8_t)read_u1();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
break;
case OP_const2u:
state->stk[state->stk_pos++] = read_u2();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const2s:
state->stk[state->stk_pos++] = (int16_t)read_u2();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
break;
case OP_const4u:
state->stk[state->stk_pos++] = read_u4();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const4s:
state->stk[state->stk_pos++] = (int32_t)read_u4();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
break;
case OP_const8u:
state->stk[state->stk_pos++] = read_u8();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_const8s:
state->stk[state->stk_pos++] = (int64_t)read_u8();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
break;
case OP_constu:
state->stk[state->stk_pos++] = read_u8leb128();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_consts:
state->stk[state->stk_pos++] = read_i8leb128();
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_INTEGER;
break;
case OP_dup:
check_e_stack(1);
state->stk[state->stk_pos] = state->stk[state->stk_pos - 1];
+ state->type_stk[state->stk_pos] = state->type_stk[state->stk_pos - 1];
state->stk_pos++;
break;
case OP_drop:
@@ -264,6 +282,7 @@ static void evaluate_expression(void) {
case OP_over:
check_e_stack(2);
state->stk[state->stk_pos] = state->stk[state->stk_pos - 2];
+ state->type_stk[state->stk_pos] = state->type_stk[state->stk_pos - 2];
state->stk_pos++;
break;
case OP_pick:
@@ -271,30 +290,40 @@ static void evaluate_expression(void) {
unsigned n = read_u1();
check_e_stack(n + 1);
state->stk[state->stk_pos] = state->stk[state->stk_pos - n - 1];
+ state->type_stk[state->stk_pos] = state->type_stk[state->stk_pos - n - 1];
state->stk_pos++;
}
break;
case OP_swap:
check_e_stack(2);
data = state->stk[state->stk_pos - 1];
+ type = state->type_stk[state->stk_pos - 1];
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 2];
+ state->type_stk[state->stk_pos - 1] = state->type_stk[state->stk_pos - 2];
state->stk[state->stk_pos - 2] = data;
+ state->type_stk[state->stk_pos - 2] = type;
break;
case OP_rot:
check_e_stack(3);
data = state->stk[state->stk_pos - 1];
+ type = state->type_stk[state->stk_pos - 1];
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 2];
+ state->type_stk[state->stk_pos - 1] = state->type_stk[state->stk_pos - 2];
state->stk[state->stk_pos - 2] = state->stk[state->stk_pos - 3];
+ state->type_stk[state->stk_pos - 2] = state->type_stk[state->stk_pos - 3];
state->stk[state->stk_pos - 3] = data;
+ state->type_stk[state->stk_pos - 2] = type;
break;
case OP_xderef:
check_e_stack(2);
state->stk[state->stk_pos - 2] = read_memory(state->stk[state->stk_pos - 1], state->addr_size);
+ state->type_stk[state->stk_pos - 2] = TYPE_CLASS_CARDINAL;
state->stk_pos--;
break;
case OP_xderef_size:
check_e_stack(2);
state->stk[state->stk_pos - 2] = read_memory(state->stk[state->stk_pos - 1], read_u1());
+ state->type_stk[state->stk_pos - 2] = TYPE_CLASS_CARDINAL;
state->stk_pos--;
break;
case OP_abs:
@@ -404,31 +433,37 @@ static void evaluate_expression(void) {
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] == state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_ge:
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] >= state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_gt:
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] > state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_le:
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] <= state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_lt:
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] < state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_ne:
check_e_stack(2);
state->stk_pos--;
state->stk[state->stk_pos - 1] = state->stk[state->stk_pos - 1] != state->stk[state->stk_pos];
+ state->type_stk[state->stk_pos - 1] = TYPE_CLASS_CARDINAL;
break;
case OP_skip:
code_pos += (int16_t)read_u2();
@@ -466,7 +501,8 @@ static void evaluate_expression(void) {
case OP_lit29:
case OP_lit30:
case OP_lit31:
- state->stk[state->stk_pos++] = op - OP_lit0;
+ state->stk[state->stk_pos] = op - OP_lit0;
+ state->type_stk[state->stk_pos++] = TYPE_CLASS_CARDINAL;
break;
case OP_reg0:
case OP_reg1:
@@ -559,6 +595,7 @@ static void evaluate_expression(void) {
RegisterDefinition * def = get_reg_by_id(state->ctx, op - OP_breg0, &state->reg_id_scope);
if (def == NULL) exception(errno);
if (read_reg_value(state->stack_frame, def, state->stk + state->stk_pos) < 0) exception(errno);
+ state->type_stk[state->stk_pos] = TYPE_CLASS_CARDINAL;
state->stk[state->stk_pos++] += read_i8leb128();
}
break;
@@ -567,6 +604,7 @@ static void evaluate_expression(void) {
RegisterDefinition * def = get_reg_by_id(state->ctx, (unsigned)read_u4leb128(), &state->reg_id_scope);
if (def == NULL) exception(errno);
if (read_reg_value(state->stack_frame, def, state->stk + state->stk_pos) < 0) exception(errno);
+ state->type_stk[state->stk_pos] = TYPE_CLASS_CARDINAL;
state->stk[state->stk_pos++] += read_i8leb128();
}
break;
@@ -575,13 +613,14 @@ static void evaluate_expression(void) {
RegisterDefinition * def = get_reg_by_id(state->ctx, (unsigned)read_ua(), &state->reg_id_scope);
if (def == NULL) exception(errno);
if (read_reg_value(state->stack_frame, def, state->stk + state->stk_pos) < 0) exception(errno);
- state->stk_pos++;
+ state->type_stk[state->stk_pos++] = TYPE_CLASS_CARDINAL;
}
break;
case OP_call_frame_cfa:
{
StackFrame * frame = state->stack_frame;
if (frame == NULL) str_exception(ERR_INV_ADDRESS, "Stack frame address not available");
+ state->type_stk[state->stk_pos] = TYPE_CLASS_CARDINAL;
state->stk[state->stk_pos++] = frame->fp;
}
break;
@@ -589,6 +628,7 @@ static void evaluate_expression(void) {
break;
case OP_push_object_address:
if (state->args_cnt == 0) exception(ERR_INV_CONT_OBJ);
+ state->type_stk[state->stk_pos] = TYPE_CLASS_CARDINAL;
state->stk[state->stk_pos++] = state->args[0];
break;
case OP_piece:
@@ -623,6 +663,18 @@ static void evaluate_expression(void) {
}
if (!is_end_of_loc_expr()) inv_dwarf("OP_stack_value must be last instruction");
break;
+ case OP_GNU_const_type:
+ inv_dwarf("Unsupported type in OP_GNU_const_type");
+ break;
+ case OP_GNU_regval_type:
+ inv_dwarf("Unsupported type in OP_GNU_regval_type");
+ break;
+ case OP_GNU_deref_type:
+ inv_dwarf("Unsupported type in OP_GNU_deref_type");
+ break;
+ case OP_GNU_convert:
+ inv_dwarf("Unsupported type in OP_GNU_convert");
+ break;
case OP_TCF_switch:
check_e_stack(1);
{
@@ -729,9 +781,11 @@ static void evaluate_expression(void) {
for (i = 0; i < value_size; i++) {
value |= ((uint8_t *)value_addr)[i] << (i * 8);
}
+ s->type_stk[s->stk_pos] = TYPE_CLASS_CARDINAL;
s->stk[s->stk_pos++] = value;
}
else if (entry_state.stk_pos == 1) {
+ s->type_stk[s->stk_pos] = entry_state.type_stk[entry_state.stk_pos - 1];
s->stk[s->stk_pos++] = entry_state.stk[entry_state.stk_pos - 1];
}
else {
diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c
index 60bf2d7f..42dcb55c 100644
--- a/tests/test-dwarf/tcf/backend/backend.c
+++ b/tests/test-dwarf/tcf/backend/backend.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2015 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010, 2016 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
@@ -896,6 +896,7 @@ static void loc_var_func(void * args, Symbol * sym) {
if (errcmp(err, "Cannot get TLS module ID") == 0) return;
if (errcmp(err, "Cannot get address of ELF symbol: indirect symbol") == 0) return;
if (errcmp(err, "Unsupported type in OP_GNU_const_type") == 0) return;
+ if (errcmp(err, "Unsupported type in OP_GNU_regval_type") == 0) return;
if (errcmp(err, "Unsupported type in OP_GNU_convert") == 0) return;
if (errcmp(err, "Invalid size of implicit value") == 0) return;
if (errcmp(err, "Invalid implicit pointer") == 0) return;
@@ -984,6 +985,9 @@ static void loc_var_func(void * args, Symbol * sym) {
if (!ok && obj != NULL && obj->mCompUnit->mLanguage == LANG_ADA95) {
if (errcmp(err, "Cannot get object address: the object is located in a register") == 0) ok = 1;
}
+ if (!ok && obj != NULL && type_class == TYPE_CLASS_ARRAY) {
+ if (errcmp(err, "Cannot get array upper bound. No object location info found") == 0) ok = 1;
+ }
if (!ok && obj != NULL && obj->mTag == TAG_dwarf_procedure) {
ok = 1;
}
@@ -1315,6 +1319,9 @@ static void loc_var_func(void * args, Symbol * sym) {
if (!ok && obj != NULL && obj->mCompUnit->mLanguage == LANG_ADA95) {
if (errcmp(err, "Cannot get object address: the object is located in a register") == 0) ok = 1;
}
+ if (!ok && obj != NULL) {
+ if (errcmp(err, "Cannot get array upper bound. No object location info found") == 0) ok = 1;
+ }
if (!ok) {
errno = err;
error_sym("get_symbol_length", sym);
@@ -1547,7 +1554,6 @@ static void check_addr_ranges(void) {
static void next_pc(void) {
Symbol * sym = NULL;
ContextAddress lt_addr;
- ContextAddress rt_addr;
ELF_File * lt_file;
ELF_Section * lt_sec;
ObjectInfo * func_object = NULL;
@@ -1559,6 +1565,9 @@ static void next_pc(void) {
ContextAddress next_pc = pc + 1;
UnitAddressRange * unit_range = NULL;
ContextAddress rage_rt_addr = 0;
+ const char * isa = NULL;
+ ContextAddress isa_range_addr = 0;
+ ContextAddress isa_range_size = 0;
for (;;) {
if (mem_region_pos < 0) {
@@ -1595,6 +1604,20 @@ static void next_pc(void) {
set_regs_PC(elf_ctx, pc);
send_context_changed_event(elf_ctx);
+ if (get_context_isa(elf_ctx, pc, &isa, &isa_range_addr, &isa_range_size) < 0) {
+ error("get_context_isa");
+ }
+ if (isa != NULL) {
+ if (pc < isa_range_addr) {
+ set_errno(ERR_OTHER, "pc < isa_range_addr");
+ error("get_context_isa");
+ }
+ if (isa_range_addr + isa_range_size > 0 && pc >= isa_range_addr + isa_range_size) {
+ set_errno(ERR_OTHER, "pc >= isa_range_addr + isa_range_size");
+ error("get_context_isa");
+ }
+ }
+
func_name = NULL;
func_object = NULL;
if (find_symbol_by_addr(elf_ctx, STACK_NO_FRAME, pc, &sym) < 0) {
@@ -1824,18 +1847,22 @@ static void next_pc(void) {
if (errno) error("elf_map_to_link_time_address");
assert(lt_file != NULL);
assert(lt_file == get_dwarf_file(elf_file));
- assert(lt_sec == NULL || lt_sec->file == lt_file);
- rt_addr = elf_map_to_run_time_address(elf_ctx, lt_file, lt_sec, lt_addr);
- if (pc != rt_addr) {
- set_errno(ERR_OTHER, "Invalid address - broken relocation logic?");
- error("elf_map_to_run_time_address");
- }
- if (set_trap(&trap)) {
- get_dwarf_stack_frame_info(elf_ctx, lt_file, lt_sec, lt_addr);
- clear_trap(&trap);
- }
- else {
- error("get_dwarf_stack_frame_info 1");
+ if (lt_sec != NULL) {
+ ContextAddress rt_addr;
+ assert(lt_sec->file == lt_file);
+ rt_addr = elf_map_to_run_time_address(elf_ctx, lt_file, lt_sec, lt_addr);
+ if (errno) error("elf_map_to_run_time_address");
+ if (pc != rt_addr) {
+ set_errno(ERR_OTHER, "Invalid address - broken relocation logic?");
+ error("elf_map_to_run_time_address");
+ }
+ if (set_trap(&trap)) {
+ get_dwarf_stack_frame_info(elf_ctx, lt_file, lt_sec, lt_addr);
+ clear_trap(&trap);
+ }
+ else {
+ error("get_dwarf_stack_frame_info 1");
+ }
}
if (enumerate_symbols(elf_ctx, STACK_TOP_FRAME, loc_var_func, NULL) < 0) {
@@ -2095,8 +2122,17 @@ static void test(void * args) {
post_event_with_delay(test, NULL, 1);
}
+static int file_name_comparator(const void * x, const void * y) {
+ return strcmp(*(const char **)x, *(const char **)y);
+}
+
static void add_dir(const char * dir_name) {
DIR * dir = opendir(dir_name);
+ char ** buf = NULL;
+ unsigned buf_len = 0;
+ unsigned buf_max = 0;
+ unsigned i;
+
if (dir == NULL) {
printf("Cannot open '%s' directory\n", dir_name);
fflush(stdout);
@@ -2104,15 +2140,30 @@ static void add_dir(const char * dir_name) {
}
for (;;) {
struct dirent * e = readdir(dir);
- char path[FILE_PATH_SIZE];
- struct stat st;
if (e == NULL) break;
if (strcmp(e->d_name, ".") == 0) continue;
if (strcmp(e->d_name, "..") == 0) continue;
if (strcmp(e->d_name + strlen(e->d_name) - 6, ".debug") == 0) continue;
if (strcmp(e->d_name + strlen(e->d_name) - 7, ".x86_64") == 0) continue;
if (strcmp(e->d_name + strlen(e->d_name) - 4, ".txt") == 0) continue;
- snprintf(path, sizeof(path), "%s/%s", dir_name, e->d_name);
+ if (buf_len >= buf_max) {
+ buf_max = buf_max == 0 ? 256 : buf_max * 2;
+ buf = (char **)loc_realloc(buf, buf_max * sizeof(char *));
+ }
+ buf[buf_len++] = loc_strdup(e->d_name);
+ }
+ closedir(dir);
+ qsort(buf, buf_len, sizeof(char *), file_name_comparator);
+ for (i = 0; i < buf_len; i++) {
+ char * name = buf[i];
+ char path[FILE_PATH_SIZE];
+ struct stat st;
+ if (strcmp(dir_name, ".") == 0) {
+ strlcpy(path, name, sizeof(path));
+ }
+ else {
+ snprintf(path, sizeof(path), "%s/%s", dir_name, name);
+ }
if (stat(path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
add_dir(path);
@@ -2125,15 +2176,16 @@ static void add_dir(const char * dir_name) {
else {
close(fd);
if (files_cnt >= files_max) {
- files_max += 8;
+ files_max = files_max == 0 ? 256 : files_max * 2;
files = (char **)loc_realloc(files, files_max * sizeof(char *));
}
files[files_cnt++] = loc_strdup(path);
}
}
}
+ loc_free(name);
}
- closedir(dir);
+ loc_free(buf);
}
void init_contexts_sys_dep(void) {

Back to the top