Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreutarass2011-03-15 21:40:40 +0000
committereutarass2011-03-15 21:40:40 +0000
commit9d4dd5905d208e8414345f246d184b3151264975 (patch)
tree97e82fa02d41cd9fef435e97372424844703be2c
parent1d9f536db21d46d0dc19a7e34567de2bc4763881 (diff)
downloadorg.eclipse.tcf.agent-9d4dd5905d208e8414345f246d184b3151264975.tar.gz
org.eclipse.tcf.agent-9d4dd5905d208e8414345f246d184b3151264975.tar.xz
org.eclipse.tcf.agent-9d4dd5905d208e8414345f246d184b3151264975.zip
TCF Agent:
1. Added handling of AT_ranges attribute for functions and lexical blocks. 2. Changed symbol IDs to start with '@' - it allows to easily distinguish symbol IDs and improves symbol cache performance
-rw-r--r--services/dwarfcache.c3
-rw-r--r--services/dwarfcache.h1
-rw-r--r--services/symbols_elf.c99
-rw-r--r--services/symbols_proxy.c11
-rw-r--r--services/symbols_win32.c12
5 files changed, 88 insertions, 38 deletions
diff --git a/services/dwarfcache.c b/services/dwarfcache.c
index c9e9e757..dfa0b3e3 100644
--- a/services/dwarfcache.c
+++ b/services/dwarfcache.c
@@ -606,6 +606,9 @@ static void load_debug_sections(void) {
else if (strcmp(sec->name, ".debug_loc") == 0) {
sCache->mDebugLoc = sec;
}
+ else if (strcmp(sec->name, ".debug_ranges") == 0) {
+ sCache->mDebugRanges = sec;
+ }
else if (strcmp(sec->name, ".debug_frame") == 0) {
sCache->mDebugFrame = sec;
}
diff --git a/services/dwarfcache.h b/services/dwarfcache.h
index ec0b5857..8b54a5d9 100644
--- a/services/dwarfcache.h
+++ b/services/dwarfcache.h
@@ -192,6 +192,7 @@ struct DWARFCache {
ObjectInfo * mCompUnits;
ELF_Section * mDebugLine;
ELF_Section * mDebugLoc;
+ ELF_Section * mDebugRanges;
ELF_Section * mDebugFrame;
ELF_Section * mEHFrame;
SymbolSection ** mSymSections;
diff --git a/services/symbols_elf.c b/services/symbols_elf.c
index 3dd8b0b6..797909c9 100644
--- a/services/symbols_elf.c
+++ b/services/symbols_elf.c
@@ -200,6 +200,59 @@ static int get_num_prop(ObjectInfo * obj, int at, U8_T * res) {
return 1;
}
+/* Check 'addr' belongs to an object address range(s) */
+static int check_in_range(ObjectInfo * obj, ContextAddress addr) {
+ Trap trap;
+
+ if (set_trap(&trap)) {
+ U8_T pc0, pc1;
+ PropertyValue v0, v1;
+ read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_low_pc, &v0);
+ read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_high_pc, &v1);
+ pc0 = get_numeric_property_value(&v0);
+ pc1 = get_numeric_property_value(&v1);
+ clear_trap(&trap);
+ return pc0 <= addr && pc1 > addr;
+ }
+ if (set_trap(&trap)) {
+ CompUnit * unit = obj->mCompUnit;
+ DWARFCache * cache = get_dwarf_cache(unit->mFile);
+ ELF_Section * debug_ranges = cache->mDebugRanges;
+ if (debug_ranges != NULL) {
+ ContextAddress base = unit->mLowPC;
+ PropertyValue v;
+ U8_T offs = 0;
+ int res = 0;
+
+ read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, obj, AT_ranges, &v);
+ offs = get_numeric_property_value(&v);
+ dio_EnterSection(&unit->mDesc, debug_ranges, offs);
+ for (;;) {
+ ELF_Section * sec = NULL;
+ U8_T x = dio_ReadAddress(&sec);
+ U8_T y = dio_ReadAddress(&sec);
+ if (x == 0 && y == 0) break;
+ if (x == ((U8_T)1 << unit->mDesc.mAddressSize * 8) - 1) {
+ base = (ContextAddress)y;
+ }
+ else {
+ x = base + x;
+ y = base + y;
+ if (x <= addr && addr < y) {
+ res = 1;
+ break;
+ }
+ }
+ }
+ dio_ExitSection();
+ clear_trap(&trap);
+ return res;
+ }
+ clear_trap(&trap);
+ }
+ return 0;
+}
+
static int find_in_object_tree(ObjectInfo * list, ContextAddress ip, const char * name, Symbol ** sym) {
Symbol * sym_imp = NULL;
Symbol * sym_enu = NULL;
@@ -218,12 +271,8 @@ static int find_in_object_tree(ObjectInfo * list, ContextAddress ip, const char
case TAG_subprogram:
case TAG_entry_point:
case TAG_lexical_block:
- if (ip != 0) {
- U8_T LowPC, HighPC;
- if (get_num_prop(obj, AT_low_pc, &LowPC) && LowPC <= ip &&
- get_num_prop(obj, AT_high_pc, &HighPC) && HighPC > ip) {
- if (find_in_object_tree(obj->mChildren, ip, name, sym)) return 1;
- }
+ if (ip != 0 && check_in_range(obj, ip)) {
+ if (find_in_object_tree(obj->mChildren, ip, name, sym)) return 1;
}
break;
case TAG_namespace:
@@ -624,17 +673,12 @@ static int find_by_addr_in_unit(ObjectInfo * obj, int level, ContextAddress addr
case TAG_subprogram:
case TAG_entry_point:
case TAG_lexical_block:
- {
- U8_T LowPC, HighPC;
- if (get_num_prop(obj, AT_low_pc, &LowPC) && get_num_prop(obj, AT_high_pc, &HighPC)) {
- if (LowPC <= addr && HighPC > addr) {
- object2symbol(obj, res);
- return 1;
- }
- if (LowPC <= sym_ip && HighPC > sym_ip) {
- return find_by_addr_in_unit(obj->mChildren, level + 1, addr, res);
- }
- }
+ if (check_in_range(obj, addr)) {
+ object2symbol(obj, res);
+ return 1;
+ }
+ if (check_in_range(obj, sym_ip)) {
+ return find_by_addr_in_unit(obj->mChildren, level + 1, addr, res);
}
break;
case TAG_formal_parameter:
@@ -719,13 +763,8 @@ static void enumerate_local_vars(ObjectInfo * obj, int level,
case TAG_subprogram:
case TAG_entry_point:
case TAG_lexical_block:
- {
- U8_T LowPC, HighPC;
- if (get_num_prop(obj, AT_low_pc, &LowPC) && get_num_prop(obj, AT_high_pc, &HighPC)) {
- if (LowPC <= sym_ip && HighPC > sym_ip) {
- enumerate_local_vars(obj->mChildren, level + 1, call_back, args);
- }
- }
+ if (check_in_range(obj, sym_ip)) {
+ enumerate_local_vars(obj->mChildren, level + 1, call_back, args);
}
break;
case TAG_formal_parameter:
@@ -765,7 +804,7 @@ const char * symbol2id(const Symbol * sym) {
assert(sym->frame == STACK_NO_FRAME);
assert(sym->sym_class == SYM_CLASS_TYPE);
strcpy(base, symbol2id(sym->base));
- snprintf(id, sizeof(id), "PTR%"PRIX64".%s", (uint64_t)sym->size, base);
+ snprintf(id, sizeof(id), "@P%"PRIX64".%s", (uint64_t)sym->size, base);
}
else {
ELF_File * file = NULL;
@@ -777,7 +816,7 @@ const char * symbol2id(const Symbol * sym) {
if (sym->obj != NULL) obj_index = sym->obj->mID;
if (sym->tbl != NULL) tbl_index = sym->tbl->mIndex + 1;
if (frame == STACK_TOP_FRAME) frame = get_top_frame(sym->ctx);
- snprintf(id, sizeof(id), "SYM%X.%lX.%lX.%"PRIX64".%"PRIX64".%X.%d.%X.%X.%"PRIX64".%s",
+ snprintf(id, sizeof(id), "@S%X.%lX.%lX.%"PRIX64".%"PRIX64".%X.%d.%X.%X.%"PRIX64".%s",
sym->sym_class,
file ? (unsigned long)file->dev : 0ul,
file ? (unsigned long)file->ino : 0ul,
@@ -832,8 +871,8 @@ int id2symbol(const char * id, Symbol ** res) {
Trap trap;
*res = sym;
- if (id != NULL && id[0] == 'P' && id[1] == 'T' && id[2] == 'R') {
- p = id + 3;
+ if (id != NULL && id[0] == '@' && id[1] == 'P') {
+ p = id + 2;
sym->size = (ContextAddress)read_hex(&p);
if (*p == '.') p++;
if (id2symbol(p, &sym->base)) return -1;
@@ -842,8 +881,8 @@ int id2symbol(const char * id, Symbol ** res) {
sym->sym_class = SYM_CLASS_TYPE;
return 0;
}
- else if (id != NULL && id[0] == 'S' && id[1] == 'Y' && id[2] == 'M') {
- p = id + 3;
+ else if (id != NULL && id[0] == '@' && id[1] == 'S') {
+ p = id + 2;
sym->sym_class = (int)read_hex(&p);
if (*p == '.') p++;
dev = (dev_t)read_hex(&p);
diff --git a/services/symbols_proxy.c b/services/symbols_proxy.c
index 14e6800b..49e7f929 100644
--- a/services/symbols_proxy.c
+++ b/services/symbols_proxy.c
@@ -641,8 +641,15 @@ const char * symbol2id(const Symbol * sym) {
int id2symbol(const char * id, Symbol ** sym) {
LINK * l;
SymInfoCache * s = NULL;
- unsigned h = hash_sym_id(id);
- SymbolsCache * syms = get_symbols_cache();
+ unsigned h = 0;
+ SymbolsCache * syms = NULL;
+ if (id == NULL || id[0] != '@') {
+ /* Cacheable symbol IDs should start with '@' */
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ h = hash_sym_id(id);
+ syms = get_symbols_cache();
for (l = syms->link_sym[h].next; l != syms->link_sym + h; l = l->next) {
SymInfoCache * x = syms2sym(l);
if (strcmp(x->id, id) == 0) {
diff --git a/services/symbols_win32.c b/services/symbols_win32.c
index 2e0cf2b1..71b8cb27 100644
--- a/services/symbols_win32.c
+++ b/services/symbols_win32.c
@@ -228,11 +228,11 @@ const char * symbol2id(const Symbol * sym) {
assert(sym->ctx == sym->base->ctx);
assert(sym->sym_class == SYM_CLASS_TYPE);
strcpy(base, symbol2id(sym->base));
- snprintf(buf, sizeof(buf), "PTR%"PRIX64".%s", (uint64_t)sym->length, base);
+ snprintf(buf, sizeof(buf), "@P%"PRIX64".%s", (uint64_t)sym->length, base);
}
else {
int i = sym->info ? sym->info - basic_type_info + 1 : 0;
- snprintf(buf, sizeof(buf), "SYM%"PRIX64".%lX.%X.%X.%s",
+ snprintf(buf, sizeof(buf), "@S%"PRIX64".%lX.%X.%X.%s",
(uint64_t)sym->module, sym->index, sym->frame, i, sym->ctx->id);
}
return buf;
@@ -262,16 +262,16 @@ int id2symbol(const char * id, Symbol ** res) {
size_t length = 0;
const char * p;
- if (id != NULL && id[0] == 'P' && id[1] == 'T' && id[2] == 'R') {
- p = id + 3;
+ if (id != NULL && id[0] == '@' && id[1] == 'P') {
+ p = id + 2;
length = (size_t)read_hex(&p);
if (*p == '.') p++;
if (id2symbol(p, (Symbol **)&base)) return -1;
ctx = base->ctx;
}
- else if (id != NULL && id[0] == 'S' && id[1] == 'Y' && id[2] == 'M') {
+ else if (id != NULL && id[0] == '@' && id[1] == 'S') {
unsigned idx = 0;
- p = id + 3;
+ p = id + 2;
module = (ULONG64)read_hex(&p);
if (*p == '.') p++;
index = (ULONG)read_hex(&p);

Back to the top