Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugene Tarassov2011-12-22 19:10:58 +0000
committerEugene Tarassov2011-12-22 19:10:58 +0000
commit3aab32f1a0f4aa6052a7331054a9cc7c3385f78c (patch)
tree1aaacf78092704e2aee2eb8fe5ce3b1397b8af95
parentae7d67026c5e454154d9379b149d32e3d5abfb42 (diff)
downloadorg.eclipse.tcf.agent-3aab32f1a0f4aa6052a7331054a9cc7c3385f78c.tar.gz
org.eclipse.tcf.agent-3aab32f1a0f4aa6052a7331054a9cc7c3385f78c.tar.xz
org.eclipse.tcf.agent-3aab32f1a0f4aa6052a7331054a9cc7c3385f78c.zip
TCF Agent: performance and stability improvements in DWARF reader.
-rw-r--r--agent/tcf/services/dwarfcache.c47
-rw-r--r--agent/tcf/services/dwarfcache.h7
-rw-r--r--agent/tcf/services/symbols_elf.c148
-rw-r--r--tests/test-dwarf/tcf/backend/backend.c167
-rw-r--r--tests/test-dwarf/tcf/backend/backend.h7
-rw-r--r--tests/test-dwarf/tcf/framework/cpudefs-ext.h100
6 files changed, 301 insertions, 175 deletions
diff --git a/agent/tcf/services/dwarfcache.c b/agent/tcf/services/dwarfcache.c
index b4a1814a..7cd00ec2 100644
--- a/agent/tcf/services/dwarfcache.c
+++ b/agent/tcf/services/dwarfcache.c
@@ -589,6 +589,9 @@ static void read_object_refs(void) {
if (ref.obj->mName == NULL) ref.obj->mName = ref.org->mName;
if (ref.obj->mType == NULL) ref.obj->mType = ref.org->mType;
ref.obj->mFlags |= ref.org->mFlags & ~DOIF_children_loaded;
+ assert(ref.obj->mDefinition == NULL);
+ ref.obj->mDefinition = ref.org->mDefinition;
+ ref.org->mDefinition = ref.obj;
}
}
sObjRefsPos = 0;
@@ -1026,11 +1029,16 @@ static void read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Ob
sCache = (DWARFCache *)sCompUnit->mFile->dwarf_dt_cache;
dio_EnterSection(&sCompUnit->mDesc, sDebugSection, Obj->mID - sDebugSection->addr);
for (;;) {
- gop_gAttr = Attr;
+ if (sUnitDesc.mVersion == 1 && Attr == AT_data_member_location) {
+ gop_gAttr = AT_location;
+ }
+ else {
+ gop_gAttr = Attr;
+ }
gop_gForm = 0;
gop_gSpecification = 0;
gop_gAbstractOrigin = 0;
- dio_ReadEntry(get_object_property_callback, Attr);
+ dio_ReadEntry(get_object_property_callback, gop_gAttr);
dio_ExitSection();
if (gop_gForm != 0) break;
if (gop_gSpecification != 0) dio_EnterSection(&sCompUnit->mDesc, sDebugSection, gop_gSpecification - sDebugSection->addr);
@@ -1118,6 +1126,41 @@ static void read_dwarf_object_property(Context * Ctx, int Frame, ObjectInfo * Ob
Value->mValue = sCompUnit->mDesc.mAddressSize * 2;
break;
}
+ if (Obj->mTag == TAG_structure_type || Obj->mTag == TAG_class_type || Obj->mTag == TAG_union_type) {
+ /* It is OK to return size 0 if the structure has no data members */
+ int OK = 1;
+ ObjectInfo * c = get_dwarf_children(Obj);
+ while (OK && c != NULL) {
+ ObjectInfo * d = c;
+ while (d->mTag == TAG_imported_declaration) {
+ PropertyValue v;
+ read_and_evaluate_dwarf_object_property(Ctx, Frame, 0, d, AT_import, &v);
+ d = find_object(
+ (DWARFCache *)Obj->mCompUnit->mFile->dwarf_dt_cache,
+ (ContextAddress)get_numeric_property_value(&v));
+ if (d == NULL) break;
+ }
+ if (d == NULL) {
+ OK = 0;
+ }
+ else {
+ switch (d->mTag) {
+ case TAG_typedef:
+ case TAG_subprogram:
+ case TAG_template_type_param:
+ break;
+ default:
+ OK = 0;
+ }
+ }
+ c = c->mSibling;
+ }
+ if (OK) {
+ Value->mForm = FORM_UDATA;
+ Value->mValue = 0;
+ break;
+ }
+ }
}
exception(ERR_SYM_NOT_FOUND);
}
diff --git a/agent/tcf/services/dwarfcache.h b/agent/tcf/services/dwarfcache.h
index 0e19baba..1714881d 100644
--- a/agent/tcf/services/dwarfcache.h
+++ b/agent/tcf/services/dwarfcache.h
@@ -33,7 +33,7 @@
#include <tcf/framework/errors.h>
#ifndef ENABLE_DWARF_LAZY_LOAD
-# define ENABLE_DWARF_LAZY_LOAD 0
+# define ENABLE_DWARF_LAZY_LOAD 1
#endif
typedef struct FileInfo FileInfo;
@@ -83,6 +83,7 @@ struct ObjectInfo {
ObjectInfo * mSibling;
ObjectInfo * mChildren;
ObjectInfo * mParent;
+ ObjectInfo * mDefinition;
U2_T mTag;
U2_T mFlags;
@@ -267,11 +268,11 @@ extern ELF_File * get_dwarf_file(ELF_File * file);
/* Return DWARF cache for given file, create and populate the cache if needed, throw an exception if error */
extern DWARFCache * get_dwarf_cache(ELF_File * file);
-/* Load chilfren of DWARF object - if not loaded already. Return obj->mChildren */
+/* Load children of DWARF object - if not loaded already. Return obj->mChildren */
#if ENABLE_DWARF_LAZY_LOAD
extern ObjectInfo * get_dwarf_children(ObjectInfo * obj);
#else
-# define get_dwarf_children(obj) obj->mChildren
+# define get_dwarf_children(obj) ((obj)->mChildren)
#endif
/* Return file name hash. The hash is used to search FileInfo. */
diff --git a/agent/tcf/services/symbols_elf.c b/agent/tcf/services/symbols_elf.c
index 4678710c..5435b87c 100644
--- a/agent/tcf/services/symbols_elf.c
+++ b/agent/tcf/services/symbols_elf.c
@@ -178,37 +178,75 @@ static int syminfo2address(Context * ctx, ELF_SymbolInfo * info, ContextAddress
return -1;
}
+/* Return 1 if evaluation of symbol properties requires a stack frame.
+ * Return 0 otherwise.
+ * In case of a doubt, should return 1. */
static int is_frame_based_object(Symbol * sym) {
int res = 0;
- ContextAddress addr = 0;
- ContextAddress size = 0;
- Context * org_ctx = sym_ctx;
- int org_frame = sym_frame;
- ContextAddress org_ip = sym_ip;
- if (sym->sym_class == SYM_CLASS_REFERENCE) {
- if (get_symbol_address(sym, &addr) < 0) {
- res = 1;
- }
- else {
- sym->has_address = 1;
- sym->address = addr;
+ if (sym->sym_class == SYM_CLASS_FUNCTION && sym->var == NULL) return 0;
+
+ if (sym->sym_class == SYM_CLASS_TYPE && sym->obj != NULL) {
+ ObjectInfo * obj = sym->obj;
+ while (1) {
+ switch (obj->mTag) {
+ case TAG_typedef:
+ case TAG_packed_type:
+ case TAG_const_type:
+ case TAG_volatile_type:
+ case TAG_restrict_type:
+ case TAG_shared_type:
+ if (obj->mType == NULL) break;
+ obj = obj->mType;
+ continue;
+ case TAG_base_type:
+ case TAG_class_type:
+ case TAG_union_type:
+ case TAG_structure_type:
+ case TAG_enumeration_type:
+ case TAG_pointer_type:
+ case TAG_reference_type:
+ return 0;
+ }
+ break;
}
}
- if (!res) {
- if (get_symbol_size(sym, &size) < 0) {
- res = 1;
+ if (sym->obj != NULL) {
+ ContextAddress addr = 0;
+ ContextAddress size = 0;
+ Context * org_ctx = sym_ctx;
+ int org_frame = sym_frame;
+ ContextAddress org_ip = sym_ip;
+
+ if (sym->sym_class == SYM_CLASS_REFERENCE) {
+ if (sym->obj->mTag == TAG_member || sym->obj->mTag == TAG_inheritance) {
+ if (get_symbol_offset(sym, &addr) < 0) res = 1;
+ }
+ else if (get_symbol_address(sym, &addr) < 0) {
+ res = 1;
+ }
+ else {
+ sym->has_address = 1;
+ sym->address = addr;
+ }
}
- else {
- sym->has_size = 1;
- sym->size = size;
+
+ if (!res) {
+ if (get_symbol_size(sym, &size) < 0) {
+ res = 1;
+ }
+ else {
+ sym->has_size = 1;
+ sym->size = size;
+ }
}
+
+ sym_ctx = org_ctx;
+ sym_frame = org_frame;
+ sym_ip = org_ip;
}
- sym_ctx = org_ctx;
- sym_frame = org_frame;
- sym_ip = org_ip;
return res;
}
@@ -269,9 +307,7 @@ static void object2symbol(ObjectInfo * obj, Symbol ** res) {
}
sym->frame = STACK_NO_FRAME;
sym->ctx = context_get_group(sym_ctx, CONTEXT_GROUP_PROCESS);
- if (sym->sym_class != SYM_CLASS_FUNCTION &&
- sym_frame != STACK_NO_FRAME &&
- is_frame_based_object(sym)) {
+ if (sym_frame != STACK_NO_FRAME && is_frame_based_object(sym)) {
sym->frame = sym_frame;
sym->ctx = sym_ctx;
}
@@ -387,24 +423,15 @@ static int check_in_range(ObjectInfo * obj, ContextAddress rt_offs, ContextAddre
return 0;
}
+static int map_to_sym_table(ObjectInfo * obj, Symbol ** sym);
+
/* If 'sym' represents a declaration, replace it with definition - if possible */
static ObjectInfo * find_definition(ObjectInfo * decl) {
- UnitAddressRange * range = NULL;
+ Symbol * sym = NULL;
if (decl == NULL) return NULL;
if (!(decl->mFlags & DOIF_declaration)) return decl;
- range = elf_find_unit(sym_ctx, sym_ip, sym_ip, NULL);
- if (range != NULL) {
- ObjectInfo * obj = get_dwarf_children(range->mUnit->mObject);
- while (obj != NULL) {
- if (obj->mFlags & DOIF_specification) {
- U8_T v = 0;
- if (get_num_prop(obj, AT_specification_v2, &v) && v == decl->mID) {
- return obj;
- }
- }
- obj = obj->mSibling;
- }
- }
+ if (decl->mDefinition != NULL) return decl->mDefinition;
+ if (map_to_sym_table(decl, &sym) && sym->obj != NULL) return sym->obj;
return decl;
}
@@ -546,7 +573,8 @@ static int find_by_name_in_sym_table(DWARFCache * cache, const char * name, Symb
case TAG_subroutine:
case TAG_subprogram:
case TAG_variable:
- if (obj->mName != NULL && strcmp(obj->mName, name) == 0) {
+ if ((obj->mFlags & DOIF_external) != 0 &&
+ obj->mName != NULL && strcmp(obj->mName, name) == 0) {
object2symbol(obj, res);
found = 1;
cnt++;
@@ -1731,23 +1759,6 @@ int get_symbol_size(const Symbol * sym, ContextAddress * size) {
sz = read_string_length(obj);
ok = 1;
}
- if (!ok && (obj->mTag == TAG_structure_type || obj->mTag == TAG_class_type)) {
- /* It is OK to return size 0 instead of error if the structure has no data members */
- ObjectInfo * c = get_dwarf_children(obj);
- sz = 0;
- ok = 1;
- while (ok && c != NULL) {
- switch (c->mTag) {
- case TAG_subprogram:
- case TAG_typedef:
- case TAG_template_type_param:
- break;
- default:
- ok = 0;
- }
- c = c->mSibling;
- }
- }
if (!ok && ref && ref->mTag != TAG_member && ref->mTag != TAG_inheritance) {
Trap trap;
if (set_trap(&trap)) {
@@ -2029,7 +2040,7 @@ int get_symbol_children(const Symbol * sym, Symbol *** children, int * count) {
ObjectInfo * i = get_dwarf_children(obj);
while (i != NULL) {
Symbol * x = NULL;
- object2symbol(i, &x);
+ object2symbol(find_definition(i), &x);
if (buf_len <= n) {
buf_len += 16;
buf = (Symbol **)loc_realloc(buf, sizeof(Symbol *) * buf_len);
@@ -2058,9 +2069,18 @@ int get_symbol_offset(const Symbol * sym, ContextAddress * offset) {
if (unpack(sym) < 0) return -1;
if (obj != NULL && (obj->mTag == TAG_member || obj->mTag == TAG_inheritance)) {
U8_T v;
- if (!get_num_prop(obj, AT_data_member_location, &v)) return -1;
- *offset = (ContextAddress)v;
- return 0;
+ if (get_num_prop(obj, AT_data_member_location, &v)) {
+ *offset = (ContextAddress)v;
+ return 0;
+ }
+ if (get_num_prop(obj, AT_bit_offset, &v)) {
+ set_errno(ERR_OTHER, "Cannot get member offset: the symbol is a bit field");
+ return -1;
+ }
+ if (obj->mFlags & DOIF_declaration) {
+ set_errno(ERR_OTHER, "Cannot get member offset: the symbol is a declaration");
+ return -1;
+ }
}
set_errno(ERR_OTHER, "Symbol does not have a member offset");
return -1;
@@ -2189,14 +2209,18 @@ int get_symbol_address(const Symbol * sym, ContextAddress * address) {
return 0;
}
if (unpack(sym) < 0) return -1;
- if (sym->var != NULL) {
+ if (obj != NULL && (obj->mFlags & DOIF_external) == 0 && sym->var != NULL) {
/* The symbol represents a member of a class instance */
Trap trap;
PropertyValue v;
ContextAddress base = 0;
ContextAddress offs = 0;
ObjectInfo * type = get_original_type(sym->var);
- if (!set_trap(&trap)) return -1;
+ if (!set_trap(&trap)) {
+ if (errno == ERR_SYM_NOT_FOUND) errno = set_errno(ERR_OTHER, "Location attribute not found");
+ set_errno(errno, "Cannot evaluate location of 'this' pointer");
+ return -1;
+ }
if ((type->mTag != TAG_pointer_type && type->mTag != TAG_mod_pointer) || type->mType == NULL) exception(ERR_INV_CONTEXT);
read_and_evaluate_dwarf_object_property(sym_ctx, sym_frame, 0, sym->var, AT_location, &v);
base = (ContextAddress)read_cardinal_object_value(&v);
diff --git a/tests/test-dwarf/tcf/backend/backend.c b/tests/test-dwarf/tcf/backend/backend.c
index d08802c0..9cf2a07b 100644
--- a/tests/test-dwarf/tcf/backend/backend.c
+++ b/tests/test-dwarf/tcf/backend/backend.c
@@ -42,6 +42,13 @@
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
+#define MAX_REGS 2000
+
+struct RegisterData {
+ uint8_t data[MAX_REGS * 8];
+ uint8_t mask[MAX_REGS * 8];
+};
+
static Context * elf_ctx = NULL;
static MemoryMap mem_map;
static RegisterDefinition reg_defs[MAX_REGS];
@@ -63,6 +70,104 @@ static char ** files = NULL;
static unsigned files_max = 0;
static unsigned files_cnt = 0;
+static RegisterDefinition * get_reg_by_dwarf_id(unsigned id) {
+ static RegisterDefinition ** map = NULL;
+ static unsigned map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ RegisterDefinition * regs_index = get_reg_definitions(NULL);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->dwarf_id >= (int)map_length) map_length = r->dwarf_id + 1;
+ }
+ map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->dwarf_id >= 0) map[r->dwarf_id] = r;
+ }
+ }
+ return id < map_length ? map[id] : NULL;
+}
+
+static RegisterDefinition * get_reg_by_eh_frame_id(unsigned id) {
+ static RegisterDefinition ** map = NULL;
+ static unsigned map_length = 0;
+
+ if (map == NULL) {
+ RegisterDefinition * r;
+ RegisterDefinition * regs_index = get_reg_definitions(NULL);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->eh_frame_id >= (int)map_length) map_length = r->eh_frame_id + 1;
+ }
+ map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
+ for (r = regs_index; r->name != NULL; r++) {
+ if (r->eh_frame_id >= 0) map[r->eh_frame_id] = r;
+ }
+ }
+ return id < map_length ? map[id] : NULL;
+}
+
+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;
+ }
+ 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) {
+ if (reg_def != NULL && frame != NULL) {
+ if (frame->is_top_frame) {
+ return context_read_reg(frame->ctx, reg_def, offs, size, buf);
+ }
+ if (frame->regs != NULL) {
+ size_t i;
+ uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
+ for (i = 0; i < size; i++) {
+ if (m_addr[offs + i] != 0xff) {
+ errno = ERR_INV_CONTEXT;
+ return -1;
+ }
+ }
+ if (offs + size > reg_def->size) {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ memcpy(buf, r_addr + offs, size);
+ return 0;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}
+
+int write_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) {
+ return context_write_reg(frame->ctx, reg_def, offs, size, buf);
+ }
+ if (frame->regs == NULL && context_has_state(frame->ctx)) {
+ frame->regs = (RegisterData *)loc_alloc_zero(sizeof(RegisterData));
+ }
+ if (frame->regs != NULL) {
+ uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
+ uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
+
+ if (offs + size > reg_def->size) {
+ errno = ERR_INV_DATA_SIZE;
+ return -1;
+ }
+ memcpy(r_addr + offs, buf, size);
+ memset(m_addr + offs, 0xff, size);
+ return 0;
+ }
+ }
+ errno = ERR_INV_CONTEXT;
+ return -1;
+}
+
RegisterDefinition * get_reg_definitions(Context * ctx) {
return reg_defs;
}
@@ -232,6 +337,7 @@ static void loc_var_func(void * args, Symbol * sym) {
}
if (get_symbol_size(sym, &size) < 0) {
int ok = 0;
+ int err = errno;
if (type != NULL) {
char * type_name;
unsigned type_flags;
@@ -246,7 +352,10 @@ static void loc_var_func(void * args, Symbol * sym) {
ok = 1;
}
}
- if (!ok) error("get_symbol_size");
+ if (!ok) {
+ errno = err;
+ error("get_symbol_size");
+ }
}
if (type != NULL) {
if (get_symbol_type_class(sym, &type_class) < 0) {
@@ -290,6 +399,48 @@ static void loc_var_func(void * args, Symbol * sym) {
}
}
}
+ else if (type_class == TYPE_CLASS_COMPOSITE) {
+ int i;
+ int count = 0;
+ Symbol ** children = NULL;
+ if (get_symbol_children(type, &children, &count) < 0) {
+ error("get_symbol_children");
+ }
+ for (i = 0; i < count; i++) {
+ int member_class = 0;
+ ContextAddress offs = 0;
+ if (get_symbol_class(children[i], &member_class) < 0) {
+ error("get_symbol_class");
+ }
+ if (member_class == SYM_CLASS_REFERENCE) {
+ if (get_symbol_address(children[i], &offs) < 0) {
+ if (get_symbol_offset(children[i], &offs) < 0) {
+ int ok = 0;
+ int err = errno;
+ unsigned type_flags;
+ if (get_symbol_flags(children[i], &type_flags) < 0) {
+ error("get_symbol_flags");
+ }
+ if (type_flags & SYM_FLAG_EXTERNAL) ok = 1;
+ /*
+ if (!ok) {
+ errno = err;
+ error("get_symbol_offset");
+ }
+ */
+ }
+ }
+ }
+ else if (member_class == SYM_CLASS_VALUE) {
+ void * value = NULL;
+ size_t value_size = 0;
+ int big_endian = 0;
+ if (get_symbol_value(children[i], &value, &value_size, &big_endian) < 0) {
+ error("get_symbol_value");
+ }
+ }
+ }
+ }
}
}
@@ -351,9 +502,21 @@ static void next_pc(void) {
else {
char * name = NULL;
char name_buf[0x1000];
+ ContextAddress addr = 0;
+ ContextAddress size = 0;
if (get_symbol_name(sym, &name) < 0) {
error("get_symbol_name");
}
+ if (get_symbol_address(sym, &addr) < 0) {
+ error("get_symbol_address");
+ }
+ if (get_symbol_size(sym, &size) < 0) {
+ error("get_symbol_size");
+ }
+ if (pc < addr || pc >= addr + size) {
+ errno = ERR_OTHER;
+ error("invalid symbol address");
+ }
if (name != NULL) {
strcpy(name_buf, name);
if (find_symbol_by_name(elf_ctx, STACK_TOP_FRAME, 0, name_buf, &sym) < 0) {
@@ -484,7 +647,7 @@ static void next_file(void) {
r->addr = (ContextAddress)p->address;
r->file_name = loc_strdup(elf_file_name);
r->file_offs = p->offset;
- r->size = (ContextAddress)p->file_size;
+ r->size = (ContextAddress)p->mem_size;
r->flags = MM_FLAG_R | MM_FLAG_W;
if (p->flags & PF_X) r->flags |= MM_FLAG_X;
r->dev = st.st_dev;
diff --git a/tests/test-dwarf/tcf/backend/backend.h b/tests/test-dwarf/tcf/backend/backend.h
index f9aaa0b2..0c32bbc9 100644
--- a/tests/test-dwarf/tcf/backend/backend.h
+++ b/tests/test-dwarf/tcf/backend/backend.h
@@ -21,11 +21,4 @@
#include <tcf/config.h>
#include <tcf/framework/channel.h>
-#define MAX_REGS 2000
-
-struct RegisterData {
- uint8_t data[MAX_REGS * 8];
- uint8_t mask[MAX_REGS * 8];
-};
-
#endif /* D_backend */
diff --git a/tests/test-dwarf/tcf/framework/cpudefs-ext.h b/tests/test-dwarf/tcf/framework/cpudefs-ext.h
index 18cb5704..cea1d092 100644
--- a/tests/test-dwarf/tcf/framework/cpudefs-ext.h
+++ b/tests/test-dwarf/tcf/framework/cpudefs-ext.h
@@ -13,102 +13,4 @@
* Wind River Systems - initial API and implementation
*******************************************************************************/
-#include <tcf/backend/backend.h>
-
-static RegisterDefinition * get_reg_by_dwarf_id(unsigned id) {
- static RegisterDefinition ** map = NULL;
- static unsigned map_length = 0;
-
- if (map == NULL) {
- RegisterDefinition * r;
- RegisterDefinition * regs_index = get_reg_definitions(NULL);
- for (r = regs_index; r->name != NULL; r++) {
- if (r->dwarf_id >= (int)map_length) map_length = r->dwarf_id + 1;
- }
- map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
- for (r = regs_index; r->name != NULL; r++) {
- if (r->dwarf_id >= 0) map[r->dwarf_id] = r;
- }
- }
- return id < map_length ? map[id] : NULL;
-}
-
-static RegisterDefinition * get_reg_by_eh_frame_id(unsigned id) {
- static RegisterDefinition ** map = NULL;
- static unsigned map_length = 0;
-
- if (map == NULL) {
- RegisterDefinition * r;
- RegisterDefinition * regs_index = get_reg_definitions(NULL);
- for (r = regs_index; r->name != NULL; r++) {
- if (r->eh_frame_id >= (int)map_length) map_length = r->eh_frame_id + 1;
- }
- map = (RegisterDefinition **)loc_alloc_zero(sizeof(RegisterDefinition *) * map_length);
- for (r = regs_index; r->name != NULL; r++) {
- if (r->eh_frame_id >= 0) map[r->eh_frame_id] = r;
- }
- }
- return id < map_length ? map[id] : NULL;
-}
-
-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;
- }
- 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) {
- if (reg_def != NULL && frame != NULL) {
- if (frame->is_top_frame) {
- return context_read_reg(frame->ctx, reg_def, offs, size, buf);
- }
- if (frame->regs != NULL) {
- size_t i;
- uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
- uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
- for (i = 0; i < size; i++) {
- if (m_addr[offs + i] != 0xff) {
- errno = ERR_INV_CONTEXT;
- return -1;
- }
- }
- if (offs + size > reg_def->size) {
- errno = ERR_INV_DATA_SIZE;
- return -1;
- }
- memcpy(buf, r_addr + offs, size);
- return 0;
- }
- }
- errno = ERR_INV_CONTEXT;
- return -1;
-}
-
-int write_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) {
- return context_write_reg(frame->ctx, reg_def, offs, size, buf);
- }
- if (frame->regs == NULL && context_has_state(frame->ctx)) {
- frame->regs = (RegisterData *)loc_alloc_zero(sizeof(RegisterData));
- }
- if (frame->regs != NULL) {
- uint8_t * r_addr = (uint8_t *)&frame->regs->data + reg_def->offset;
- uint8_t * m_addr = (uint8_t *)&frame->regs->mask + reg_def->offset;
-
- if (offs + size > reg_def->size) {
- errno = ERR_INV_DATA_SIZE;
- return -1;
- }
- memcpy(r_addr + offs, buf, size);
- memset(m_addr + offs, 0xff, size);
- return 0;
- }
- }
- errno = ERR_INV_CONTEXT;
- return -1;
-}
+/* All registers access in implemented in backend.c */

Back to the top