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
symbol.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 <glib.h>
20 #include "glib_wrapper.h"
21 
22 #include "arch.h"
23 #include "target.h"
24 #include "dwdebug.h"
25 #include "dwdebug_priv.h"
26 
28  struct symbol *type) {
29  struct symbol *retval =
32 
33  retval->datatype_code = DATATYPE_PTR;
34  retval->issynthetic = 1;
35 
36  retval->datatype = type;
37  retval->datatype_ref = type->ref;
38 
39  retval->size.bytes = target->arch->ptrsize;
40  retval->size_is_bytes = 1;
41 
42  RHOLD(type,retval);
43  RHOLD(retval,retval);
44 
45  return retval;
46 }
47 
49  struct memregion *region) {
50  struct bsymbol *bsymbol = (struct bsymbol *)malloc(sizeof(struct bsymbol));
51  memset(bsymbol,0,sizeof(struct bsymbol *));
52 
53  bsymbol->lsymbol = lsymbol;
54  bsymbol->region = region;
55  bsymbol->refcnt = 0;
56 
57  RHOLD(lsymbol,bsymbol);
58 
59  return bsymbol;
60 }
61 
63  return lsymbol_get_name(bsymbol->lsymbol);
64 }
65 
67  return lsymbol_get_symbol(bsymbol->lsymbol);
68 }
69 
71  return bsymbol->lsymbol;
72 }
73 
75  if (bsymbol->lsymbol->symbol->isinlineinstance)
76  return 1;
77  return 0;
78 }
79 
81  struct lsymbol *lsymbol;
82 
83  lsymbol = lsymbol_create_noninline(bsymbol->lsymbol);
84  if (!lsymbol)
85  return NULL;
86 
87  return bsymbol_create(lsymbol,bsymbol->region);
88 }
89 
91  REFCNT retval;
92  RPUT(bsymbol,bsymbol,bsymbol,retval);
93  return retval;
94 }
95 
96 REFCNT bsymbol_free(struct bsymbol *bsymbol,int force) {
97  int retval = bsymbol->refcnt;
98  REFCNT trefcnt;
99 
100  if (retval) {
101  if (!force) {
102  vwarn("cannot free (%d refs) ",retval);
103  ERRORDUMPBSYMBOL_NL(bsymbol);
104  return retval;
105  }
106  else {
107  verror("forced free (%d refs) ",retval);
108  ERRORDUMPBSYMBOL(bsymbol);
109  }
110  }
111 
112  if (bsymbol->lsymbol)
113  RPUT(bsymbol->lsymbol,lsymbol,bsymbol,trefcnt);
114 
115  free(bsymbol);
116 
117  return retval;
118 }
119 
120 void bsymbol_dump(struct bsymbol *bsymbol,struct dump_info *ud) {
121  struct dump_info udn = {
122  .stream = ud->stream,
123  .detail = ud->detail,
124  .meta = ud->meta,
125  };
126  udn.prefix = malloc(strlen(ud->prefix) + 2 + 1);
127  sprintf(udn.prefix,"%s ",ud->prefix);
128 
129  fprintf(ud->stream,"bsymbol (");
130  if (bsymbol->region) {
131  memregion_dump(bsymbol->region,ud);
132  }
133  fprintf(ud->stream,")\n");
134 
135  lsymbol_dump(bsymbol->lsymbol,&udn);
136 
137  free(udn.prefix);
138 }
139 
140 void symbol_type_rvalue_print(FILE *stream,struct symbol *type,
141  void *buf,int bufsiz,
142  load_flags_t flags,
143  struct target *target) {
144  struct symbol *member;
145  int i;
146  uint32_t bytesize;
147  GSList *gsltmp;
148  loctype_t ltrc;
149  OFFSET offset;
150  struct location tloc;
151 
152  again:
153  bytesize = symbol_get_bytesize(type);
154  switch (type->datatype_code) {
155  case DATATYPE_VOID:
156  fprintf(stream,"<VOID>");
157  return;
158  case DATATYPE_BASE:;
159  encoding_t enc = SYMBOLX_ENCODING_V(type);
160  if (bytesize == 1) {
161  if (enc == ENCODING_SIGNED_CHAR)
162  fprintf(stream,"%c",rv_c(buf));
163  else if (enc == ENCODING_UNSIGNED_CHAR)
164  fprintf(stream,"%uc",rv_uc(buf));
165  else if (enc == ENCODING_SIGNED)
166  fprintf(stream,"%" PRIi8,rv_i8(buf));
167  else if (enc == ENCODING_SIGNED)
168  fprintf(stream,"%" PRIu8,rv_u8(buf));
169  else
170  fprintf(stream,"<BASE_%d>",bytesize);
171  }
172  else if (bytesize == 2) {
173  if (strstr(type->name,"char"))
174  fprintf(stream,"%lc",rv_wc(buf));
175  else if (enc == ENCODING_SIGNED)
176  fprintf(stream,"%" PRIi16,rv_i16(buf));
177  else if (enc == ENCODING_UNSIGNED)
178  fprintf(stream,"%" PRIu16,rv_u16(buf));
179  else
180  fprintf(stream,"<BASE_%d>",bytesize);
181  }
182  else if (bytesize == 4) {
183  if (enc == ENCODING_SIGNED)
184  fprintf(stream,"%" PRIi32,rv_i32(buf));
185  else if (enc == ENCODING_UNSIGNED)
186  fprintf(stream,"%" PRIu32,rv_u32(buf));
187  else
188  fprintf(stream,"<BASE_%d>",bytesize);
189  }
190  else if (bytesize == 8) {
191  if (enc == ENCODING_SIGNED)
192  fprintf(stream,"%" PRIi64,rv_i64(buf));
193  else if (enc == ENCODING_UNSIGNED)
194  fprintf(stream,"%" PRIu64,rv_u64(buf));
195  else
196  fprintf(stream,"<BASE_%d>",bytesize);
197  }
198  else {
199  fprintf(stream,"<BASE_%d>",bytesize);
200  }
201  return;
202  case DATATYPE_ARRAY:;
203  GSList *subranges = SYMBOLX_SUBRANGES(type);
204  int subrange;
205 
206  if (!subranges) {
207  fprintf(stream,"[ ]");
208  return;
209  }
210 
211  /* catch 0-byte arrays */
212  subrange = (int)(uintptr_t)subranges->data;
213  if (subrange == 0) {
214  fprintf(stream,"[ ]");
215  return;
216  }
217 
218  int llen = g_slist_length(subranges);
219  int typebytesize = symbol_get_bytesize(symbol_get_datatype(type));
220  int total = 1;
221  int *arcounts = (int *)malloc(sizeof(int) * llen);
222  uint64_t aoffset = 0;
223  int rowlength =
224  ((int)(uintptr_t)g_slist_nth_data(subranges,llen - 1)) + 1;
225  struct symbol *datatype = symbol_get_datatype(type);
226 
227  for (i = 0; i < llen; ++i) {
228  if (likely(i < (llen - 1))) {
229  arcounts[i] = 0;
230  fprintf(stream,"[ ");
231  }
232  int sri = (int)(uintptr_t)g_slist_nth_data(subranges,i);
233  total = total * (sri + 1);
234  }
235  while (total) {
236  /* do one row according to the current baseoffset */
237  fprintf(stream,"[ ");
238  for (i = 0; i < rowlength; ++i, aoffset += typebytesize) {
239  if (likely(i > 0))
240  fprintf(stream,", ");
241  symbol_type_rvalue_print(stream,datatype,
242  (void *)(buf+aoffset),typebytesize,
243  flags,target);
244  }
245  total -= rowlength;
246  fprintf(stream," ] ");
247 
248  /* Flow the index counters back and up as we do rows. We
249  * increment the next highest one each time we reach the
250  * max length for one of the indices.
251  */
252  int sri = (int)(uintptr_t)g_slist_nth_data(subranges,i);
253  for (i = llen - 1; i > -1; --i) {
254  if (arcounts[i]++ < (sri + 1))
255  break;
256  else {
257  fprintf(stream,"] ");
258  /* reset this index counter */
259  arcounts[i] = 0;
260  }
261  }
262  }
263  free(arcounts);
264  return;
265  case DATATYPE_UNION:
266  if (flags & LOAD_FLAG_AUTO_DEREF) {
267  vwarn("do not enable auto_deref for unions; clearing!\n");
268  flags &= ~LOAD_FLAG_AUTO_DEREF;
270  }
271  if (flags & LOAD_FLAG_AUTO_STRING) {
272  vwarn("do not enable auto_string for unions; clearing!\n");
273  flags &= ~LOAD_FLAG_AUTO_STRING;
274  }
275  case DATATYPE_STRUCT:
276  fprintf(stream,"{ ");
277  /* Only recursively follow pointers if the flags say so. */
278  if (!(flags & LOAD_FLAG_AUTO_DEREF_RECURSE))
279  flags &= ~LOAD_FLAG_AUTO_DEREF;
280  i = 0;
281  gsltmp = NULL;
282  v_g_slist_foreach(SYMBOLX_MEMBERS(type),gsltmp,member) {
283  if (likely(i))
284  fprintf(stream,", ");
285 
286  if (member->name)
287  fprintf(stream,".%s = ",member->name);
288  if (type->datatype_code == DATATYPE_UNION)
289  symbol_rvalue_print(stream,member,buf,bufsiz,flags,target);
290  else {
291  memset(&tloc,0,sizeof(tloc));
292  ltrc = symbol_resolve_location(member,NULL,&tloc);
293  if (ltrc != LOCTYPE_MEMBER_OFFSET)
294  fputs("?",stream);
295  else {
296  offset = LOCATION_OFFSET(&tloc);
297  symbol_rvalue_print(stream,member,
298  buf + offset,bufsiz - offset,
299  flags,target);
300  }
301  location_internal_free(&tloc);
302  }
303  ++i;
304  }
305  fprintf(stream," }");
306  return;
307  case DATATYPE_PTR:
308  if ((flags & LOAD_FLAG_AUTO_DEREF) ||
309  ((flags & LOAD_FLAG_AUTO_STRING)
310  && symbol_type_is_char(type->datatype))) {
311  type = symbol_type_skip_ptrs(type);
312 
313  if (symbol_type_is_char(type)) {
314  fprintf(stream,"%s",(char *)buf);
315  }
316  else
317  goto again;
318  }
319  else {
320  int ptrsize = (int)target->arch->ptrsize;
321 
322  fprintf(stream,"0x");
323  if (target->arch->endian == ENDIAN_LITTLE) {
324  for (i = ptrsize - 1; i > -1; --i) {
325  fprintf(stream,"%02hhx",*(((uint8_t *)buf)+i));
326  }
327  }
328  else {
329  for (i = 0; i < ptrsize; ++i) {
330  fprintf(stream,"%02hhx",*(((uint8_t *)buf)+i));
331  }
332  }
333  }
334  return;
335  case DATATYPE_FUNC:
336  fprintf(stream,"<FUNCTION>");
337  return;
338  case DATATYPE_TYPEDEF:
339  fprintf(stream,"<TYPEDEF>");
340  return;
341  case DATATYPE_CONST:
342  fprintf(stream,"<CONST>");
343  return;
344  case DATATYPE_VOL:
345  fprintf(stream,"<VOL>");
346  return;
347  default:
348  return;
349  }
350 }
351 
352 void symbol_rvalue_print(FILE *stream,struct symbol *symbol,
353  void *buf,int bufsiz,
354  load_flags_t flags,struct target *target) {
355  struct symbol *type;
356  uint64_t bitmask;
357  uint16_t lboffset;
358  int i;
359 
360  if (!SYMBOL_IS_VAR(symbol))
361  return;
362 
363  type = symbol_get_datatype(symbol);
364 
365  if (symbol->size_is_bits
366  && type->datatype_code != DATATYPE_BASE) {
367  vwarn("apparent bitfield %s is not backed by a base type!",symbol->name);
368  fprintf(stream,"<BADBITFIELDTYPE>");
369  return;
370  }
371  /* If it's a bitfield, select those bits and print them. */
372  else if (symbol->size_is_bits ) {
374  "doing bitfield for symbol %s: size=%d,offset=%d\n",
375  symbol->name,symbol->size.bits,
376  symbol->size.offset);
377  /* Create a bitmask */
378  bitmask = 1;
379  for (i = 1; i < symbol->size.bits; ++i) {
380  bitmask <<= 1;
381  bitmask |= 1;
382  }
383  if (target->arch->endian == ENDIAN_LITTLE)
384  lboffset = (symbol->size.ctbytes * 8) - (symbol->size.offset + symbol->size.bits);
385  else
386  lboffset = symbol->size.offset;
387  bitmask <<= lboffset;
388 
389  if (symbol->size.ctbytes == 1)
390  fprintf(stream,"%hhu",(uint8_t)(((*(uint8_t *)buf) & bitmask) \
391  >> lboffset));
392  else if (symbol->size.ctbytes == 2)
393  fprintf(stream,"%hu",(uint16_t)(((*(uint16_t *)buf) & bitmask) \
394  >> lboffset));
395  else if (symbol->size.ctbytes == 4)
396  fprintf(stream,"%u",(uint32_t)(((*(uint32_t *)buf) & bitmask) \
397  >> lboffset));
398  else if (symbol->size.ctbytes == 8)
399  fprintf(stream,"%"PRIu64,(uint64_t)(((*(uint64_t *)buf) & bitmask) \
400  >> lboffset));
401  else {
402  vwarn("unsupported bitfield byte size %d for symbol %s\n",
403  symbol->size.ctbytes,symbol->name);
404  fprintf(stream,"<BADBITFIELDBYTESIZE>");
405  }
406 
407  return;
408  }
409 
410  return symbol_type_rvalue_print(stream,type,buf,bufsiz,flags,target);
411 }
struct bsymbol * bsymbol_create(struct lsymbol *lsymbol, struct memregion *region)
Definition: symbol.c:48
uint16_t rv_u16(void *buf)
Definition: value.c:1340
encoding_t
Definition: dwdebug.h:266
#define SYMBOLX_SUBRANGES(sym)
struct lsymbol * lsymbol
Definition: target.h:1017
unsigned int ptrsize
Definition: arch.h:122
int bsymbol_is_inline(struct bsymbol *bsymbol)
Definition: symbol.c:74
union symbol::@7 size
struct symbol * symbol
Definition: dwdebug.h:1010
struct symbol * symbol_create(symbol_type_t symtype, symbol_source_t source, char *name, int name_copy, SMOFFSET offset, load_type_t loadtype, struct scope *scope)
Definition: debug.c:2550
static uint64_t unsigned int i
#define SYMBOLX_MEMBERS(sym)
uint8_t rv_u8(void *buf)
Definition: value.c:1339
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
SMOFFSET ref
Definition: dwdebug_priv.h:868
void location_internal_free(struct location *location)
Definition: location.c:347
unsigned int size_is_bytes
Definition: dwdebug_priv.h:839
wchar_t rv_wc(void *buf)
Definition: value.c:1338
#define likely(expr)
Definition: debugpred.h:102
uint32_t symbol_get_bytesize(struct symbol *symbol)
Definition: debug.c:3065
char * bsymbol_get_name(struct bsymbol *bsymbol)
Definition: symbol.c:62
int32_t OFFSET
Definition: common.h:65
SMOFFSET datatype_ref
Definition: dwdebug_priv.h:882
struct bsymbol * bsymbol_create_noninline(struct bsymbol *bsymbol)
Definition: symbol.c:80
signed char rv_c(void *buf)
Definition: value.c:1336
#define verror(format,...)
Definition: log.h:30
struct symbol * symbol_get_datatype(struct symbol *symbol)
Definition: debug.c:2989
symbol_type_t type
Definition: dwdebug_priv.h:833
uint32_t ctbytes
Definition: dwdebug_priv.h:906
loctype_t symbol_resolve_location(struct symbol *symbol, struct location_ctxt *lctxt, struct location *o_loc)
Definition: location.c:546
#define vwarn(format,...)
Definition: log.h:33
void lsymbol_dump(struct lsymbol *lsymbol, struct dump_info *ud)
Definition: debug.c:5622
int symbol_type_is_char(struct symbol *type)
Definition: debug.c:4224
void free(void *ptr)
Definition: debugserver.c:207
int8_t rv_i8(void *buf)
Definition: value.c:1343
#define LOCATION_OFFSET(loc)
Definition: dwdebug_priv.h:624
REFCNT refcnt
Definition: target.h:1023
char * prefix
Definition: output.h:25
char * lsymbol_get_name(struct lsymbol *lsymbol)
Definition: debug.c:4732
void memregion_dump(struct memregion *region, struct dump_info *ud)
Definition: memory.c:428
struct scope * symbol_containing_scope(struct symbol *symbol)
Definition: debug.c:2671
REFCNT bsymbol_release(struct bsymbol *bsymbol)
Definition: symbol.c:90
REFCNT bsymbol_free(struct bsymbol *bsymbol, int force)
Definition: symbol.c:96
datatype_code_t datatype_code
Definition: dwdebug_priv.h:827
uint32_t offset
Definition: dwdebug_priv.h:906
struct symbol * lsymbol_get_symbol(struct lsymbol *lsymbol)
Definition: debug.c:4738
#define SYMBOLX_ENCODING_V(sym)
char * name
Definition: dwdebug_priv.h:788
unsigned char rv_uc(void *buf)
Definition: value.c:1337
#define RHOLD(x, hx)
Definition: common.h:622
void symbol_type_rvalue_print(FILE *stream, struct symbol *type, void *buf, int bufsiz, load_flags_t flags, struct target *target)
Definition: symbol.c:140
unsigned int issynthetic
Definition: dwdebug_priv.h:839
uint32_t bits
Definition: dwdebug_priv.h:906
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
FILE * stream
Definition: output.h:26
struct arch * arch
Definition: target_api.h:2603
Definition: log.h:70
int16_t rv_i16(void *buf)
Definition: value.c:1344
uint32_t rv_u32(void *buf)
Definition: value.c:1341
int64_t rv_i64(void *buf)
Definition: value.c:1346
struct symbol * symbol_type_skip_ptrs(struct symbol *type)
Definition: debug.c:4209
Definition: log.h:125
struct lsymbol * bsymbol_get_lsymbol(struct bsymbol *bsymbol)
Definition: symbol.c:70
struct symbol * bsymbol_get_symbol(struct bsymbol *bsymbol)
Definition: symbol.c:66
uint64_t rv_u64(void *buf)
Definition: value.c:1342
#define ERRORDUMPBSYMBOL_NL(s)
Definition: target.h:68
int32_t rv_i32(void *buf)
Definition: value.c:1345
uint32_t REFCNT
Definition: common.h:124
uint32_t bytes
Definition: dwdebug_priv.h:901
int detail
Definition: output.h:28
struct symbol * target_create_synthetic_type_pointer(struct target *target, struct symbol *type)
Definition: symbol.c:27
load_flags_t
Definition: target_api.h:406
#define RPUT(x, objtype, hx, rc)
Definition: common.h:624
void symbol_rvalue_print(FILE *stream, struct symbol *symbol, void *buf, int bufsiz, load_flags_t flags, struct target *target)
Definition: symbol.c:352
void * malloc(size_t size)
Definition: debugserver.c:214
unsigned int isinlineinstance
Definition: dwdebug_priv.h:839
endian_t endian
Definition: arch.h:120
int meta
Definition: output.h:27
#define ERRORDUMPBSYMBOL(s)
Definition: target.h:57
struct lsymbol * lsymbol_create_noninline(struct lsymbol *lsymbol)
Definition: debug.c:4788
unsigned int size_is_bits
Definition: dwdebug_priv.h:839
loctype_t
Definition: dwdebug.h:234
struct symbol * datatype
Definition: dwdebug_priv.h:925
struct memregion * region
Definition: target.h:1020
#define SYMBOL_IS_VAR(sym)
void bsymbol_dump(struct bsymbol *bsymbol, struct dump_info *ud)
Definition: symbol.c:120