diff options
author | eutarass | 2011-03-15 21:40:40 +0000 |
---|---|---|
committer | eutarass | 2011-03-15 21:40:40 +0000 |
commit | 9d4dd5905d208e8414345f246d184b3151264975 (patch) | |
tree | 97e82fa02d41cd9fef435e97372424844703be2c | |
parent | 1d9f536db21d46d0dc19a7e34567de2bc4763881 (diff) | |
download | org.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.c | 3 | ||||
-rw-r--r-- | services/dwarfcache.h | 1 | ||||
-rw-r--r-- | services/symbols_elf.c | 99 | ||||
-rw-r--r-- | services/symbols_proxy.c | 11 | ||||
-rw-r--r-- | services/symbols_win32.c | 12 |
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); |