Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
location.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "target.h"
20 #include "dwdebug_priv.h"
21 
28  int frame) {
29  struct target_location_ctxt *tlctxt =
30  (struct target_location_ctxt *)lctxt->priv;
31  struct target_location_ctxt_frame *tlctxtf =
32  target_location_ctxt_get_frame(tlctxt,frame);
33 
34  if (!tlctxtf) {
35  errno = EBADSLT;
36  return -1;
37  }
38 
39  if (tlctxtf->bsymbol)
40  tlctxt->region = tlctxtf->bsymbol->region;
41  else if (tlctxtf->alt_bsymbol)
42  tlctxt->region = tlctxtf->alt_bsymbol->region;
43  lctxt->current_frame = frame;
44  return 0;
45 }
46 
48  struct target_location_ctxt *tlctxt =
49  (struct target_location_ctxt *)lctxt->priv;
50  struct target_location_ctxt_frame *tlctxtf =
52 
53  if (tlctxtf->bsymbol)
54  return bsymbol_get_symbol(tlctxtf->bsymbol);
55  else if (tlctxtf->alt_bsymbol)
56  return bsymbol_get_symbol(tlctxtf->alt_bsymbol);
57  else
58  return NULL;
59 }
60 
62  struct target_location_ctxt *tlctxt =
63  (struct target_location_ctxt *)lctxt->priv;
64  struct target *target = tlctxt->thread->target;
65  struct target_location_ctxt_frame *tlctxtf =
67  struct symbol *symbol;
68  struct symbol *root;
69  struct debugfile *debugfile;
70  ADDR ipval;
71 
72  /* Find our debugfile. */
73  if (tlctxtf->bsymbol) {
74  symbol = bsymbol_get_symbol(tlctxtf->bsymbol);
75  if (symbol) {
76  root = symbol_find_root(symbol);
77  SYMBOL_RX_ROOT(root,srd);
78  debugfile = srd->debugfile;
79  if (debugfile)
80  return debugfile;
81  }
82  }
83  else if (tlctxtf->alt_bsymbol) {
84  symbol = bsymbol_get_symbol(tlctxtf->alt_bsymbol);
85  if (symbol) {
86  root = symbol_find_root(symbol);
87  SYMBOL_RX_ROOT(root,srd);
88  debugfile = srd->debugfile;
89  if (debugfile)
90  return debugfile;
91  }
92  }
93  else {
94  ipval = (ADDR)(uintptr_t) \
95  g_hash_table_lookup(tlctxtf->registers,
96  (gpointer)(uintptr_t)target->ipregno);
97  if (ipval != 0) {
98  debugfile = target_lookup_debugfile(target,ipval);
99  if (debugfile)
100  return debugfile;
101  }
102  }
103 
105  "could not find debugfile for frame %d!\n",tlctxtf->frame);
106  errno = EINVAL;
107  return NULL;
108 }
109 
111  struct target_location_ctxt *tlctxt;
112 
113  tlctxt = (struct target_location_ctxt *)lctxt->priv;
114  return tlctxt->thread->target->arch->wordsize;
115 }
116 
118  common_reg_t creg,REG *o_reg) {
119  struct target_location_ctxt *tlctxt;
120  REG reg;
121 
122  tlctxt = (struct target_location_ctxt *)lctxt->priv;
123  errno = 0;
124 
125  if (target_cregno(tlctxt->thread->target,creg,&reg))
126  return -1;
127 
128  if (o_reg)
129  *o_reg = reg;
130  return 0;
131 }
132 
134  REG regno,REGVAL *regval) {
135  struct target_location_ctxt *tlctxt;
136  REGVAL retval;
137  struct target_location_ctxt_frame *tlctxtf;
138  gpointer v;
139 
140  tlctxt = (struct target_location_ctxt *)lctxt->priv;
141  if (lctxt->current_frame == 0) {
142  errno = 0;
143  retval = target_read_reg(tlctxt->thread->target,tlctxt->thread->tid,
144  regno);
145  if (errno) {
146  verror("could not read reg %"PRIiREG" in tid %"PRIiTID": %s!\n",
147  regno,tlctxt->thread->tid,strerror(errno));
148  return -1;
149  }
150 
151  *regval = retval;
152  return 0;
153  }
154  else {
155  if (!tlctxt->frames) {
156  verror("no unwinding context for thread %"PRIiTID";"
157  " cannot read %"PRIiREG" in frame %d\n",
158  tlctxt->thread->tid,regno,lctxt->current_frame);
159  errno = EINVAL;
160  return -1;
161  }
162  tlctxtf = target_location_ctxt_current_frame(tlctxt);
163  if (!tlctxtf) {
164  verror("frame %d not available yet for thread %"PRIiTID";"
165  " cannot read %"PRIiREG"\n",
166  lctxt->current_frame,tlctxt->thread->tid,regno);
167  errno = EINVAL;
168  return -1;
169  }
170 
171  /* Check the cache. */
172  if (g_hash_table_lookup_extended(tlctxtf->registers,
173  (gpointer)(uintptr_t)regno,NULL,&v) == TRUE) {
174  if (regval)
175  *regval = (REGVAL)(uintptr_t)v;
176  return 0;
177  }
178 
179  errno = EADDRNOTAVAIL;
180  return -1;
181  }
182 }
183 
185  REG regno,REGVAL regval) {
186  struct target_location_ctxt *tlctxt;
187 
188  tlctxt = (struct target_location_ctxt *)lctxt->priv;
189  if (lctxt->current_frame == 0) {
190  errno = 0;
191  if (target_write_reg(tlctxt->thread->target,tlctxt->thread->tid,
192  regno,regval)) {
193  verror("could not write 0x%"PRIxREGVAL" to reg %"PRIiREG
194  " in tid %"PRIiTID": %s!\n",
195  regval,regno,tlctxt->thread->tid,strerror(errno));
196  return -1;
197  }
198  return 0;
199  }
200 
201  errno = EINVAL;
202  return -1;
203 }
204 
206  REG regno,REGVAL regval) {
207  struct target_location_ctxt *tlctxt;
208  struct target_location_ctxt_frame *tlctxtf;
209 
210  tlctxt = (struct target_location_ctxt *)lctxt->priv;
211 
212  if (lctxt->current_frame == 0) {
213  errno = EINVAL;
214  return -1;
215  }
216 
217  if (!tlctxt->frames) {
218  verror("no unwinding context for thread %"PRIiTID";"
219  " cannot cache %"PRIiREG" 0x%"PRIxREGVAL" in frame %d\n",
220  tlctxt->thread->tid,regno,regval,lctxt->current_frame);
221  errno = EINVAL;
222  return -1;
223  }
224  tlctxtf = target_location_ctxt_current_frame(tlctxt);
225  if (!tlctxtf) {
226  verror("frame %d not available yet for thread %"PRIiTID";"
227  " cannot cache %"PRIiREG" 0x%"PRIxREGVAL"\n",
228  lctxt->current_frame,tlctxt->thread->tid,regno,regval);
229  errno = EINVAL;
230  return -1;
231  }
232 
233  g_hash_table_insert(tlctxtf->registers,
234  (gpointer)(uintptr_t)regno,(gpointer)(uintptr_t)regval);
235 
236  errno = 0;
237  return 0;
238 }
239 
241  struct target_location_ctxt *tlctxt;
242 
243  tlctxt = (struct target_location_ctxt *)lctxt->priv;
244 
245  return __target_location_ops_readreg(lctxt,
246  tlctxt->thread->target->ipregno,regval);
247 }
248 
250  ADDR real_addr,ADDR *pval) {
251  struct target_location_ctxt *tlctxt;
252  unsigned char *rc;
253 
254  tlctxt = (struct target_location_ctxt *)lctxt->priv;
255 
256  rc = target_read_addr(tlctxt->thread->target,real_addr,
257  tlctxt->thread->target->arch->ptrsize,(unsigned char *)pval);
258  if (rc != (unsigned char *)pval) {
259  verror("could not read 0x%"PRIxADDR": %s!\n",
260  real_addr,strerror(errno));
261  return -1;
262  }
263 
264  return 0;
265 }
266 
268  ADDR real_addr,ADDR pval) {
269  struct target_location_ctxt *tlctxt;
270  unsigned long rc;
271 
272  tlctxt = (struct target_location_ctxt *)lctxt->priv;
273 
274  rc = target_write_addr(tlctxt->thread->target,real_addr,
275  tlctxt->thread->target->arch->ptrsize,
276  (unsigned char *)&pval);
277  if (rc != tlctxt->thread->target->arch->ptrsize) {
278  verror("could not write 0x%"PRIxADDR" to 0x%"PRIxADDR": %s!\n",
279  pval,real_addr,strerror(errno));
280  return -1;
281  }
282 
283  return 0;
284 }
285 
287  ADDR obj_addr,ADDR *real_addr) {
288  struct target_location_ctxt *tlctxt;
289 
290  tlctxt = (struct target_location_ctxt *)lctxt->priv;
291 
292  /* Relocate the obj_addr according to tlctxt->region */
293  *real_addr = memregion_relocate(tlctxt->region,obj_addr,NULL);
294 
295  return 0;
296 }
297 
299  ADDR real_addr,ADDR *obj_addr) {
300  struct target_location_ctxt *tlctxt;
301 
302  tlctxt = (struct target_location_ctxt *)lctxt->priv;
303 
304  /* Relocate the obj_addr according to tlctxt->region */
305  *obj_addr = memregion_unrelocate(tlctxt->region,real_addr,NULL);
306 
307  return 0;
308 }
309 
312  .getdebugfile = __target_location_ops_getdebugfile,
313  .getsymbol = __target_location_ops_getsymbol,
315  .writereg = __target_location_ops_writereg,
316  .cachereg = __target_location_ops_cachereg,
317  .readipreg = __target_location_ops_readipreg,
318 
319  .readword = __target_location_ops_readword,
320  .writeword = __target_location_ops_writeword,
321  .relocate = __target_location_ops_relocate,
322  .unrelocate = __target_location_ops_unrelocate,
323 
324  .getregno = __target_location_ops_getregno,
325  .getaddrsize = __target_location_ops_getaddrsize,
326 };
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
int __target_location_ops_readword(struct location_ctxt *lctxt, ADDR real_addr, ADDR *pval)
Definition: location.c:249
int __target_location_ops_relocate(struct location_ctxt *lctxt, ADDR obj_addr, ADDR *real_addr)
Definition: location.c:286
unsigned int ptrsize
Definition: arch.h:122
struct array_list * frames
Definition: target_api.h:2396
ADDR memregion_unrelocate(struct memregion *region, ADDR real_addr, struct memrange **range_saveptr)
Definition: memory.c:402
common_reg_t
Definition: arch.h:73
#define SYMBOL_RX_ROOT(sym, rvar)
int __target_location_ops_setcurrentframe(struct location_ctxt *lctxt, int frame)
Definition: location.c:27
struct memregion * region
Definition: target_api.h:2391
#define PRIiREG
Definition: common.h:94
int __target_location_ops_writereg(struct location_ctxt *lctxt, REG regno, REGVAL regval)
Definition: location.c:184
struct symbol * symbol_find_root(struct symbol *symbol)
Definition: debug.c:3119
int __target_location_ops_writeword(struct location_ctxt *lctxt, ADDR real_addr, ADDR pval)
Definition: location.c:267
int target_cregno(struct target *target, common_reg_t creg, REG *reg)
Definition: target_api.c:1126
int __target_location_ops_getaddrsize(struct location_ctxt *lctxt)
Definition: location.c:110
struct debugfile * target_lookup_debugfile(struct target *target, ADDR addr)
Definition: target.c:2020
#define verror(format,...)
Definition: log.h:30
unsigned char * target_read_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1053
REGVAL target_read_reg(struct target *target, tid_t tid, REG reg)
Definition: target_api.c:1132
struct target_location_ctxt_frame * target_location_ctxt_get_frame(struct target_location_ctxt *tlctxt, int frame)
Definition: target.c:5742
int __target_location_ops_unrelocate(struct location_ctxt *lctxt, ADDR real_addr, ADDR *obj_addr)
Definition: location.c:298
Definition: log.h:69
int __target_location_ops_readreg(struct location_ctxt *lctxt, REG regno, REGVAL *regval)
Definition: location.c:133
int(* setcurrentframe)(struct location_ctxt *lctxt, int frame)
Definition: dwdebug_priv.h:673
struct arch * arch
Definition: target_api.h:2603
struct target_location_ctxt_frame * target_location_ctxt_current_frame(struct target_location_ctxt *tlctxt)
Definition: target.c:5748
unsigned int wordsize
Definition: arch.h:121
struct symbol * __target_location_ops_getsymbol(struct location_ctxt *lctxt)
Definition: location.c:47
struct target * target
Definition: target_api.h:2078
uint32_t REGVAL
Definition: common.h:66
#define PRIiTID
Definition: common.h:37
int __target_location_ops_cachereg(struct location_ctxt *lctxt, REG regno, REGVAL regval)
Definition: location.c:205
struct location_ops target_location_ops
Definition: location.c:310
int __target_location_ops_getregno(struct location_ctxt *lctxt, common_reg_t creg, REG *o_reg)
Definition: location.c:117
int8_t REG
Definition: common.h:93
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
uint32_t ADDR
Definition: common.h:64
int __target_location_ops_readipreg(struct location_ctxt *lctxt, REGVAL *regval)
Definition: location.c:240
ADDR memregion_relocate(struct memregion *region, ADDR obj_addr, struct memrange **range_saveptr)
Definition: memory.c:375
#define PRIxADDR
Definition: common.h:67
struct symbol_root * root
Definition: dwdebug_priv.h:973
struct target_thread * thread
Definition: target_api.h:2383
unsigned long target_write_addr(struct target *target, ADDR addr, unsigned long length, unsigned char *buf)
Definition: target_api.c:1060
REG ipregno
Definition: target_api.h:2508
int target_write_reg(struct target *target, tid_t tid, REG reg, REGVAL value)
Definition: target_api.c:1141
struct location_ctxt * lctxt
Definition: target_api.h:2377
Definition: log.h:127
struct debugfile * __target_location_ops_getdebugfile(struct location_ctxt *lctxt)
Definition: location.c:61
#define PRIxREGVAL
Definition: common.h:72