X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fregcache.c;h=2af8e241d98db5a8795682aa203f1585a4820ddb;hb=cbe14bcfada1e6f88811f82260f804167e95ac6f;hp=916a47994a48ed590c73e9ef1a574edf60edf160;hpb=6d3d12ebef6fa7dd6bc8c34fbc5e440ac8d0a8c6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c index 916a47994a..2af8e241d9 100644 --- a/gdb/gdbserver/regcache.c +++ b/gdb/gdbserver/regcache.c @@ -1,5 +1,5 @@ /* Register support routines for the remote server for GDB. - Copyright (C) 2001-2014 Free Software Foundation, Inc. + Copyright (C) 2001-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -28,7 +28,7 @@ get_thread_regcache (struct thread_info *thread, int fetch) { struct regcache *regcache; - regcache = (struct regcache *) inferior_regcache_data (thread); + regcache = inferior_regcache_data (thread); /* Threads' regcaches are created lazily, because biarch targets add the main thread/lwp before seeing it stop for the first time, and @@ -41,8 +41,7 @@ get_thread_regcache (struct thread_info *thread, int fetch) { struct process_info *proc = get_thread_process (thread); - if (proc->tdesc == NULL) - fatal ("no target description"); + gdb_assert (proc->tdesc != NULL); regcache = new_register_cache (proc->tdesc); set_inferior_regcache_data (thread, regcache); @@ -50,34 +49,45 @@ get_thread_regcache (struct thread_info *thread, int fetch) if (fetch && regcache->registers_valid == 0) { - struct thread_info *saved_inferior = current_inferior; + struct thread_info *saved_thread = current_thread; - current_inferior = thread; + current_thread = thread; + /* Invalidate all registers, to prevent stale left-overs. */ + memset (regcache->register_status, REG_UNAVAILABLE, + regcache->tdesc->num_registers); fetch_inferior_registers (regcache, -1); - current_inferior = saved_inferior; + current_thread = saved_thread; regcache->registers_valid = 1; } return regcache; } +/* See common/common-regcache.h. */ + +struct regcache * +get_thread_regcache_for_ptid (ptid_t ptid) +{ + return get_thread_regcache (find_thread_ptid (ptid), 1); +} + void regcache_invalidate_thread (struct thread_info *thread) { struct regcache *regcache; - regcache = (struct regcache *) inferior_regcache_data (thread); + regcache = inferior_regcache_data (thread); if (regcache == NULL) return; if (regcache->registers_valid) { - struct thread_info *saved_inferior = current_inferior; + struct thread_info *saved_thread = current_thread; - current_inferior = thread; + current_thread = thread; store_inferior_registers (regcache, -1); - current_inferior = saved_inferior; + current_thread = saved_thread; } regcache->registers_valid = 0; @@ -97,13 +107,23 @@ regcache_invalidate_one (struct inferior_list_entry *entry, return 0; } +/* See regcache.h. */ + +void +regcache_invalidate_pid (int pid) +{ + find_inferior (&all_threads, regcache_invalidate_one, &pid); +} + +/* See regcache.h. */ + void regcache_invalidate (void) { /* Only update the threads of the current process. */ - int pid = ptid_get_pid (current_inferior->entry.id); + int pid = ptid_get_pid (current_thread->entry.id); - find_inferior (&all_threads, regcache_invalidate_one, &pid); + regcache_invalidate_pid (pid); } #endif @@ -121,12 +141,15 @@ init_register_cache (struct regcache *regcache, fetches. This way they'll read as zero instead of garbage. */ regcache->tdesc = tdesc; - regcache->registers = xcalloc (1, tdesc->registers_size); + regcache->registers + = (unsigned char *) xcalloc (1, tdesc->registers_size); regcache->registers_owned = 1; - regcache->register_status = xcalloc (1, tdesc->num_registers); - gdb_assert (REG_UNAVAILABLE == 0); + regcache->register_status + = (unsigned char *) xmalloc (tdesc->num_registers); + memset ((void *) regcache->register_status, REG_UNAVAILABLE, + tdesc->num_registers); #else - fatal ("init_register_cache: can't allocate memory from the heap"); + gdb_assert_not_reached ("can't allocate memory from the heap"); #endif } else @@ -149,11 +172,10 @@ init_register_cache (struct regcache *regcache, struct regcache * new_register_cache (const struct target_desc *tdesc) { - struct regcache *regcache; + struct regcache *regcache = XCNEW (struct regcache); gdb_assert (tdesc->registers_size != 0); - regcache = xmalloc (sizeof (*regcache)); return init_register_cache (regcache, tdesc, NULL); } @@ -231,18 +253,6 @@ registers_from_string (struct regcache *regcache, char *buf) hex2bin (buf, registers, len / 2); } -struct reg * -find_register_by_name (const struct target_desc *tdesc, const char *name) -{ - int i; - - for (i = 0; i < tdesc->num_registers; i++) - if (strcmp (name, tdesc->reg_defs[i].name) == 0) - return &tdesc->reg_defs[i]; - fatal ("Unknown register %s requested", name); - return 0; -} - int find_regno (const struct target_desc *tdesc, const char *name) { @@ -251,8 +261,8 @@ find_regno (const struct target_desc *tdesc, const char *name) for (i = 0; i < tdesc->num_registers; i++) if (strcmp (name, tdesc->reg_defs[i].name) == 0) return i; - fatal ("Unknown register %s requested", name); - return -1; + internal_error (__FILE__, __LINE__, "Unknown register %s requested", + name); } struct reg * @@ -267,8 +277,7 @@ find_register_by_number (const struct target_desc *tdesc, int n) static void free_register_cache_thread (struct thread_info *thread) { - struct regcache *regcache - = (struct regcache *) inferior_regcache_data (thread); + struct regcache *regcache = inferior_regcache_data (thread); if (regcache != NULL) { @@ -306,6 +315,14 @@ register_size (const struct target_desc *tdesc, int n) return tdesc->reg_defs[n].size / 8; } +/* See common/common-regcache.h. */ + +int +regcache_register_size (const struct regcache *regcache, int n) +{ + return register_size (regcache->tdesc, n); +} + static unsigned char * register_data (struct regcache *regcache, int n, int fetch) { @@ -407,6 +424,28 @@ collect_register (struct regcache *regcache, int n, void *buf) register_size (regcache->tdesc, n)); } +enum register_status +regcache_raw_read_unsigned (struct regcache *regcache, int regnum, + ULONGEST *val) +{ + int size; + + gdb_assert (regcache != NULL); + gdb_assert (regnum >= 0 && regnum < regcache->tdesc->num_registers); + + size = register_size (regcache->tdesc, regnum); + + if (size > (int) sizeof (ULONGEST)) + error (_("That operation is not available on integers of more than" + "%d bytes."), + (int) sizeof (ULONGEST)); + + *val = 0; + collect_register (regcache, regnum, val); + + return REG_VALID; +} + #ifndef IN_PROCESS_AGENT void