diff options
author | Eugene Tarassov | 2011-12-22 19:10:58 +0000 |
---|---|---|
committer | Eugene Tarassov | 2011-12-22 19:10:58 +0000 |
commit | 3aab32f1a0f4aa6052a7331054a9cc7c3385f78c (patch) | |
tree | 1aaacf78092704e2aee2eb8fe5ce3b1397b8af95 | |
parent | ae7d67026c5e454154d9379b149d32e3d5abfb42 (diff) | |
download | org.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.c | 47 | ||||
-rw-r--r-- | agent/tcf/services/dwarfcache.h | 7 | ||||
-rw-r--r-- | agent/tcf/services/symbols_elf.c | 148 | ||||
-rw-r--r-- | tests/test-dwarf/tcf/backend/backend.c | 167 | ||||
-rw-r--r-- | tests/test-dwarf/tcf/backend/backend.h | 7 | ||||
-rw-r--r-- | tests/test-dwarf/tcf/framework/cpudefs-ext.h | 100 |
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 */ |