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
debuginfo_rpc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2013 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 "generic_rpc.h"
20 #include "debuginfo_rpc.h"
21 #include "alist.h"
22 #include <pthread.h>
23 #include <glib.h>
24 #include <errno.h>
25 
26 /*
27  * Overall note about how we handle multi-ref data: gsoap would handle
28  * this if it we didn't have this middle layer of translation between
29  * our native data structs/unions and the "nice" ones for the XML
30  * server; so we have to do an additional layer to help gsoap handle
31  * multi-ref data. Each time we encode one of our data structs that has
32  * a unique memory location, we store it in a per-invocation hashtable
33  * mapping it to its gsoap C data struct. Then each time we encode one
34  * of our data structs, we check the hashtable quick and simply return
35  * the already-encoded version.
36  */
37 
38 /*
39  * We don't check error codes for locking this mutex; don't need to
40  * since the only way it could fail (unless the mutex structure gets
41  * corrupted) is if the calling thread already owns it.
42  */
43 pthread_mutex_t debuginfo_rpc_mutex = PTHREAD_MUTEX_INITIALIZER;
44 
45 struct vmi1__DebugFileOptsT defDebugFileOpts = {
46  .symbolRefDepth = 1,
47  .scopeRefDepth = 1,
48  .doMultiRef = 0,
49 };
50 
51 static int init_done = 0;
52 
53 void debuginfo_rpc_init(void) {
54  pthread_mutex_lock(&debuginfo_rpc_mutex);
55 
56  if (init_done) {
57  pthread_mutex_unlock(&debuginfo_rpc_mutex);
58  return;
59  }
60 
61  dwdebug_init();
63 
64  init_done = 1;
65 
66  pthread_mutex_unlock(&debuginfo_rpc_mutex);
67 }
68 
69 void debuginfo_rpc_fini(void) {
70  if (!init_done)
71  return;
72 
73  pthread_mutex_lock(&debuginfo_rpc_mutex);
74 
75  if (!init_done)
76  return;
77 
79  dwdebug_fini();
80 
81  init_done = 0;
82 
83  pthread_mutex_unlock(&debuginfo_rpc_mutex);
84 }
85 
86 int vmi1__ListDebugFiles(struct soap *soap,
87  struct vmi1__DebugFileOptsT *opts,
88  struct vmi1__DebugFiles *r) {
89  struct debugfile *df;
90  int i;
91  GHashTable *reftab;
92  struct array_list *refstack;
93  struct array_list *loaded_list;
94 
96 
97  if (!opts)
98  opts = &defDebugFileOpts;
99 
100  if (opts->doMultiRef)
101  soap_set_omode(soap,SOAP_XML_GRAPH);
102 
103  pthread_mutex_lock(&debuginfo_rpc_mutex);
104 
105  loaded_list = debugfile_get_loaded_debugfiles();
106  r->__size_debugFile = loaded_list ? array_list_len(loaded_list) : 0;
107  if (r->__size_debugFile == 0) {
108  r->debugFile = NULL;
109  pthread_mutex_unlock(&debuginfo_rpc_mutex);
110  return SOAP_OK;
111  }
112 
113  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
114  refstack = array_list_create(DEF_REFSTACK_SIZE);
115  r->debugFile = soap_malloc(soap,r->__size_debugFile * sizeof(*r->debugFile));
116 
117  array_list_foreach(loaded_list,i,df)
118  r->debugFile[i] = d_debugfile_to_x_DebugFileT(soap,df,opts,reftab,refstack,0);
119 
120  array_list_free(refstack);
121  g_hash_table_destroy(reftab);
122 
123  array_list_free(loaded_list);
124 
125  pthread_mutex_unlock(&debuginfo_rpc_mutex);
126  return SOAP_OK;
127 }
128 
129 int vmi1__LoadDebugFile(struct soap *soap,
130  char *filename,struct vmi1__DebugFileOptsT *opts,
131  struct vmi1__DebugFile *r) {
133 
134  return soap_receiver_fault(soap,"Not implemented!","Not implemented!");
135 }
136 
137 int vmi1__LoadDebugFileForBinary(struct soap *soap,
138  char *filename,
139  struct vmi1__DebugFileOptsT *opts,
140  struct vmi1__DebugFile *r) {
142 
143  return soap_receiver_fault(soap,"Not implemented!","Not implemented!");
144 }
145 
146 int vmi1__LookupSymbolSimple(struct soap *soap,
147  char *filename,char *name,
148  struct vmi1__DebugFileOptsT *opts,
149  struct vmi1__SymbolResponse *r) {
150  struct debugfile *debugfile;
151  struct lsymbol *lsymbol;
152  GHashTable *reftab;
153  struct array_list *refstack;
154 
155  if (!opts)
156  opts = &defDebugFileOpts;
157 
158  if (opts->doMultiRef)
159  soap_set_omode(soap,SOAP_XML_GRAPH);
160 
161  if (filename == NULL || name == NULL
162  || strcmp(filename,"") == 0 || strcmp(name,"") == 0) {
163  return soap_receiver_fault(soap,"Bad debugfile or name!",
164  "Bad debugfile or name!");
165  }
166 
167  if (!(debugfile = debugfile_from_file(filename,NULL,NULL)))
168  return soap_receiver_fault(soap,"Could not load debugfile!",
169  "Could not load debugfile!");
170 
171  lsymbol = debugfile_lookup_sym(debugfile,name,NULL,NULL,SYMBOL_TYPE_NONE);
172 
173  if (!lsymbol)
174  return soap_receiver_fault(soap,"Could not find symbol!",
175  "Could not find symbol!");
176 
177  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
178  refstack = array_list_create(DEF_REFSTACK_SIZE);
179  r->symbol = d_symbol_to_x_SymbolT(soap,lsymbol->symbol,
180  opts,reftab,refstack,0);
181  array_list_free(refstack);
182  g_hash_table_destroy(reftab);
183 
184  lsymbol_release(lsymbol);
185 
186  return SOAP_OK;
187 }
188 
189 
190 int vmi1__LookupSymbol(struct soap *soap,
191  char *filename,char *name,
192  struct vmi1__DebugFileOptsT *opts,
193  struct vmi1__NestedSymbolResponse *r) {
194  struct debugfile *debugfile;
195  struct lsymbol *lsymbol;
196  GHashTable *reftab;
197  struct array_list *refstack;
198  char errbuf[64];
199 
200  if (!opts)
201  opts = &defDebugFileOpts;
202 
203  if (opts->doMultiRef)
204  soap_set_omode(soap,SOAP_XML_GRAPH);
205 
206  if (filename == NULL || name == NULL
207  || strcmp(filename,"") == 0 || strcmp(name,"") == 0) {
208  return soap_receiver_fault(soap,"Bad debugfile or name!",
209  "Bad debugfile or name!");
210  }
211  if (!(debugfile = debugfile_from_file(filename,NULL,NULL)))
212  return soap_receiver_fault(soap,"Could not load debugfile!",
213  "Could not load debugfile!");
214 
215  lsymbol = debugfile_lookup_sym(debugfile,name,NULL,NULL,SYMBOL_TYPE_NONE);
216 
217  if (!lsymbol)
218  return soap_receiver_fault(soap,"Could not find symbol!",
219  "Could not find symbol!");
220 
221  reftab = g_hash_table_new_full(g_direct_hash,g_direct_equal,NULL,NULL);
222  refstack = array_list_create(DEF_REFSTACK_SIZE);
223  r->nestedSymbol = \
225  opts,reftab,refstack,0);
226  if (r->nestedSymbol)
227  vwarn("%d %d %p\n",g_hash_table_size(reftab),
228  r->nestedSymbol->__size_SymbolsT,
229  r->nestedSymbol->__union_SymbolsT);
230  else
231  vwarn("%d\n",g_hash_table_size(reftab));
232 
233  array_list_free(refstack);
234  g_hash_table_destroy(reftab);
235 
236  lsymbol_release(lsymbol);
237 
238  return SOAP_OK;
239 }
240 
241 int vmi1__LookupAddrSimple(struct soap *soap,
242  char *filename,vmi1__ADDR addr,
243  struct vmi1__DebugFileOptsT *opts,
244  struct vmi1__SymbolResponse *r) {
245  return soap_receiver_fault(soap,"Not implemented!","Not implemented!");
246 }
247 
248 int vmi1__LookupAddr(struct soap *soap,
249  char *filename,vmi1__ADDR addr,
250  struct vmi1__DebugFileOptsT *opts,
251  struct vmi1__NestedSymbolResponse *r) {
252  return soap_receiver_fault(soap,"Not implemented!","Not implemented!");
253 }
254 
255 int vmi1__LookupAllSymbols(struct soap *soap,
256  char *filename,char *name,
257  struct vmi1__DebugFileOptsT *opts,
258  struct vmi1__NestedSymbolResponse *r) {
259  return soap_receiver_fault(soap,"Not implemented!","Not implemented!");
260 }
struct debugfile * debugfile_from_file(char *filename, char *root_prefix, struct array_list *debugfile_load_opts_list)
Definition: debug.c:1584
REFCNT lsymbol_release(struct lsymbol *lsymbol)
Definition: debug.c:4805
int vmi1__LookupAllSymbols(struct soap *soap, char *filename, char *name, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
struct symbol * symbol
Definition: dwdebug.h:1010
static uint64_t unsigned int i
struct vmi1__DebugFileOptsT defDebugFileOpts
Definition: debuginfo_rpc.c:45
void generic_rpc_init(void)
Definition: generic_rpc.c:69
int vmi1__LoadDebugFile(struct soap *soap, char *filename, struct vmi1__DebugFileOptsT *opts, struct vmi1__DebugFile *r)
pthread_mutex_t debuginfo_rpc_mutex
Definition: debuginfo_rpc.c:43
void dwdebug_init(void)
Definition: debug.c:83
#define vwarn(format,...)
Definition: log.h:33
#define array_list_foreach(alist, lpc, placeholder)
Definition: alist.h:371
int vmi1__LookupSymbol(struct soap *soap, char *filename, char *name, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
void dwdebug_fini(void)
Definition: debug.c:143
struct dt_argp_state opts
Definition: dumptarget.c:111
struct vmi1__SymbolT * d_symbol_to_x_SymbolT(struct soap *soap, struct symbol *s, struct vmi1__DebugFileOptsT *opts, GHashTable *reftab, struct array_list *refstack, int depth)
struct vmi1__DebugFileT * d_debugfile_to_x_DebugFileT(struct soap *soap, struct debugfile *df, struct vmi1__DebugFileOptsT *opts, GHashTable *reftab, struct array_list *refstack, int depth)
void debuginfo_rpc_fini(void)
Definition: debuginfo_rpc.c:69
struct vmi1__SymbolsT * nestedSymbol
int vmi1__LookupAddr(struct soap *soap, char *filename, vmi1__ADDR addr, struct vmi1__DebugFileOptsT *opts, struct vmi1__NestedSymbolResponse *r)
void debuginfo_rpc_init(void)
Definition: debuginfo_rpc.c:53
struct vmi1__DebugFileT ** debugFile
struct lsymbol * debugfile_lookup_sym(struct debugfile *debugfile, char *name, const char *delim, struct rfilter *srcfile_filter, symbol_type_flag_t flags)
Definition: debug.c:1021
struct vmi1__SymbolT * symbol
void generic_rpc_fini(void)
Definition: generic_rpc.c:104
struct vmi1__SymbolsT * d_symbol_array_list_to_x_SymbolsT(struct soap *soap, struct array_list *list, struct vmi1__DebugFileOptsT *opts, GHashTable *reftab, struct array_list *refstack, int depth)
struct array_list * debugfile_get_loaded_debugfiles(void)
Definition: debug.c:1810
int vmi1__LookupSymbolSimple(struct soap *soap, char *filename, char *name, struct vmi1__DebugFileOptsT *opts, struct vmi1__SymbolResponse *r)
#define DEF_REFSTACK_SIZE
Definition: debuginfo_rpc.h:28
struct array_list * chain
Definition: dwdebug.h:1016
int vmi1__ListDebugFiles(struct soap *soap, struct vmi1__DebugFileOptsT *opts, struct vmi1__DebugFiles *r)
Definition: debuginfo_rpc.c:86
int vmi1__LoadDebugFileForBinary(struct soap *soap, char *filename, struct vmi1__DebugFileOptsT *opts, struct vmi1__DebugFile *r)
int vmi1__LookupAddrSimple(struct soap *soap, char *filename, vmi1__ADDR addr, struct vmi1__DebugFileOptsT *opts, struct vmi1__SymbolResponse *r)