Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2014-02-12 13:23:38 -0500
committerEugene Tarassov2014-02-12 13:23:38 -0500
commit488e908e2429a77c5697c07a1dbbfea921a7d3df (patch)
tree5a8701d10dd55ded32f7b5dbe06c3fd56ecc7491
parent7e248442f8db5b745e3ef2326dcb68b06087feb2 (diff)
downloadorg.eclipse.tcf.agent-488e908e2429a77c5697c07a1dbbfea921a7d3df.tar.gz
org.eclipse.tcf.agent-488e908e2429a77c5697c07a1dbbfea921a7d3df.tar.xz
org.eclipse.tcf.agent-488e908e2429a77c5697c07a1dbbfea921a7d3df.zip
TCF Agent: added code to handle GCC DWARF extension: DW_OP_GNU_parameter_ref
-rw-r--r--agent/tcf/services/dwarf.h3
-rw-r--r--agent/tcf/services/dwarfecomp.c112
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c36
3 files changed, 139 insertions, 12 deletions
diff --git a/agent/tcf/services/dwarf.h b/agent/tcf/services/dwarf.h
index 9106cb4d..e93d9764 100644
--- a/agent/tcf/services/dwarf.h
+++ b/agent/tcf/services/dwarf.h
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 1996, 2012 Wind River Systems, Inc. and others.
+ * Copyright (c) 1996, 2014 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.
@@ -240,6 +240,7 @@
#define AT_lo_user_v2 0x2000
#define AT_wrs_options 0x2001
#define AT_MIPS_linkage_name 0x2007
+#define AT_GNU_call_site_value 0x2111
#define AT_hi_user_v2 0x3fff
diff --git a/agent/tcf/services/dwarfecomp.c b/agent/tcf/services/dwarfecomp.c
index d02bcf14..6fa31d99 100644
--- a/agent/tcf/services/dwarfecomp.c
+++ b/agent/tcf/services/dwarfecomp.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2011, 2014 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.
@@ -55,6 +55,9 @@ static int expr_frame = 0;
static ContextAddress expr_code_addr = 0;
static ContextAddress expr_code_size = 0;
static int expr_big_endian = 0;
+static ObjectInfo ** call_site_buf = NULL;
+static unsigned call_site_cnt = 0;
+static unsigned call_site_max = 0;
static void add(unsigned n) {
if (buf_pos >= buf_max) {
@@ -533,6 +536,44 @@ static void op_call(void) {
add_expression_list(info, 0, 0);
}
+static void add_call_sites(ObjectInfo * obj, U8_T addr, U8_T size) {
+ while (obj != NULL) {
+ switch (obj->mTag) {
+ case TAG_subprogram:
+ case TAG_subroutine:
+ case TAG_inlined_subroutine:
+ case TAG_lexical_block:
+ add_call_sites(get_dwarf_children(obj), addr, size);
+ break;
+ case TAG_GNU_call_site:
+ if ((obj->mFlags & DOIF_low_pc) != 0 && (size == 0 ||
+ (obj->u.mCode.mLowPC >= addr && obj->u.mCode.mLowPC < addr + size))) {
+ if (call_site_cnt >= call_site_max) {
+ call_site_max *= 2;
+ call_site_buf = (ObjectInfo **)tmp_realloc(call_site_buf,
+ sizeof(ObjectInfo *) * call_site_max);
+ }
+ call_site_buf[call_site_cnt++] = obj;
+ }
+ break;
+ }
+ obj = obj->mSibling;
+ }
+}
+
+static void find_call_sites(CompUnit * unit, U8_T addr, U8_T size) {
+ ObjectInfo * obj = unit->mObject->mChildren;
+ call_site_cnt = 0;
+ call_site_max = 16;
+ call_site_buf = (ObjectInfo **)tmp_alloc(sizeof(ObjectInfo *) * call_site_max);
+ while (obj != NULL) {
+ if (obj->mTag == TAG_subprogram) {
+ add_call_sites(get_dwarf_children(obj), addr, size);
+ }
+ obj = obj->mSibling;
+ }
+}
+
static void op_entry_value(void) {
size_t size = 0;
size_t size_pos = 0;
@@ -557,6 +598,71 @@ static void op_entry_value(void) {
buf[size_pos++] = (U1_T)((size >> 14) & 0x7f);
}
+static void op_parameter_ref(void) {
+ U8_T ref_id = 0;
+ size_t size = 0;
+ size_t size_pos = 0;
+ U8_T dio_pos = 0;
+ DIO_UnitDescriptor * desc = &expr->object->mCompUnit->mDesc;
+ unsigned n;
+
+ DWARFExpressionInfo * info = NULL;
+ DWARFExpressionInfo ** info_last = &info;
+ PropertyValue pv;
+
+ expr_pos++;
+ add(OP_GNU_entry_value);
+ size_pos = buf_pos;
+ add(0);
+ add(0);
+ add(0);
+
+ dio_pos = expr->expr_addr + expr_pos - (U1_T *)expr->section->data;
+ dio_EnterSection(desc, expr->section, dio_pos);
+ ref_id = desc->mSection->addr + desc->mUnitOffs + dio_ReadU4();
+ expr_pos += (size_t)(dio_GetPos() - dio_pos);
+ dio_ExitSection();
+
+ find_call_sites(expr->object->mCompUnit, expr->code_addr, expr_code_size);
+ for (n = 0; n < call_site_cnt; n++) {
+ ObjectInfo * site = call_site_buf[n];
+ ObjectInfo * args = get_dwarf_children(site);
+ while (args != NULL) {
+ 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;
+ }
+ }
+ }
+ }
+ args = args->mSibling;
+ }
+ }
+
+ if (info == NULL) {
+ str_exception(ERR_OTHER, "Object is not available at this location in the code");
+ }
+ add_expression_list(info, 0, 0);
+
+ size = buf_pos - size_pos - 3;
+ buf[size_pos++] = (U1_T)((size & 0x7f) | 0x80);
+ buf[size_pos++] = (U1_T)(((size >> 7) & 0x7f) | 0x80);
+ buf[size_pos++] = (U1_T)((size >> 14) & 0x7f);
+}
+
static void adjust_jumps(void) {
JumpInfo * i = jumps;
while (i != NULL) {
@@ -747,6 +853,10 @@ static void add_expression(DWARFExpressionInfo * info) {
check_frame();
op_entry_value();
break;
+ case OP_GNU_parameter_ref:
+ check_frame();
+ op_parameter_ref();
+ break;
case OP_GNU_regval_type:
expr_pos++;
{
diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c
index 48be8290..fae3195a 100644
--- a/tests/test-dwarf/tcf/backend/backend.c
+++ b/tests/test-dwarf/tcf/backend/backend.c
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2010, 2013 Wind River Systems, Inc. and others.
+ * Copyright (c) 2010, 2014 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.
@@ -27,6 +27,7 @@
#include <tcf/framework/events.h>
#include <tcf/framework/myalloc.h>
#include <tcf/framework/exceptions.h>
+#include <tcf/framework/trace.h>
#include <tcf/services/tcf_elf.h>
#include <tcf/services/elf-symbols.h>
@@ -126,21 +127,18 @@ RegisterDefinition * get_reg_by_id(Context * ctx, unsigned id, RegisterIdScope *
int read_reg_bytes(StackFrame * frame, RegisterDefinition * reg_def, unsigned offs, unsigned size, uint8_t * buf) {
if (reg_def != NULL && frame != NULL) {
- if (frame->is_top_frame) {
+ if (frame->is_top_frame || frame->regs == NULL) {
return context_read_reg(frame->ctx, reg_def, offs, size, buf);
}
if (frame->regs != NULL) {
uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
-#if 0
uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
size_t i;
for (i = 0; i < size; i++) {
if (m_addr[offs + i] != 0xff) {
- errno = ERR_INV_CONTEXT;
- return -1;
+ return context_read_reg(frame->ctx, reg_def, offs, size, buf);
}
}
-#endif
if (offs + size > reg_def->size) {
errno = ERR_INV_DATA_SIZE;
return -1;
@@ -262,9 +260,8 @@ int context_get_memory_map(Context * ctx, MemoryMap * map) {
}
int crawl_stack_frame(StackFrame * frame, StackFrame * down) {
- if (frame->is_top_frame) {
- frame->fp = frame_addr;
- }
+ frame->fp = frame_addr;
+ down->has_reg_data = 1;
return 0;
}
@@ -1031,7 +1028,7 @@ static void loc_var_func(void * args, Symbol * sym) {
}
static void test_public_names(void) {
- DWARFCache * cache = get_dwarf_cache(elf_file);
+ DWARFCache * cache = get_dwarf_cache(get_dwarf_file(elf_file));
unsigned n = 0;
unsigned m = 0;
while (n < cache->mPubNames.mCnt) {
@@ -1070,6 +1067,24 @@ static void test_public_names(void) {
}
}
+static void check_addr_ranges(void) {
+ unsigned i;
+ DWARFCache * cache = get_dwarf_cache(get_dwarf_file(elf_file));
+ if (cache->mAddrRangesCnt > 1) {
+ for (i = 0; i < cache->mAddrRangesCnt - 1; i++) {
+ UnitAddressRange * x = cache->mAddrRanges + i;
+ UnitAddressRange * y = cache->mAddrRanges + i + 1;
+ if (x->mSection == y->mSection &&
+ x->mAddr < y->mAddr + y->mSize &&
+ y->mAddr < x->mAddr + x->mSize) {
+ printf("Overlapping address ranges: %08x %08x, %08x %08x\n",
+ (unsigned)x->mAddr, (unsigned)x->mSize,
+ (unsigned)y->mAddr, (unsigned)y->mSize);
+ }
+ }
+ }
+}
+
static void next_pc(void) {
Symbol * sym = NULL;
CodeArea area;
@@ -1341,6 +1356,7 @@ static void next_pc(void) {
}
printf("pub names time: %ld.%06ld\n", (long)time_diff.tv_sec, time_diff.tv_nsec / 1000);
fflush(stdout);
+ check_addr_ranges();
time_start = time_now;
}
else if (test_cnt >= 10000) {

Back to the top