* monitor.c: Include gnu-regex.h rather than system regex.h.
[deliverable/binutils-gdb.git] / gdb / magic.c
CommitLineData
cd10c7e3
SG
1#include "defs.h"
2#include "gdbcmd.h"
3#include "symtab.h"
4#include "value.h"
5#include <ctype.h>
6#include <string.h>
7#ifdef DYNAMIC_COMMAND_SUPPORT
8#include <dlfcn.h>
9#endif
10
11typedef unsigned long ulong;
12
13#ifdef DYNAMIC_COMMAND_SUPPORT
14static void
15dlopen_command PARAMS ((char *, int));
16#endif
17
18#ifdef DYNAMIC_COMMAND_SUPPORT
19/* ARGSUSED */
20static void
21dlopen_command (arg, from_tty)
22 char *arg;
23 int from_tty;
24{
25 char *p;
26 void *hdl;
27 void (*sym)();
28
29 if (arg == 0) {
30 error ("No arguments specified.");
31 return;
32 }
33 p = arg;
34 while(*p != ' ' && *p != '\0')
35 p++;
36 if (*p != ' ') {
37 error ("Not enough arguments.");
38 return;
39 }
40 *p++ = '\0';
41
42 hdl = dlopen(arg, RTLD_NOW);
43 if (hdl == NULL) {
44 fprintf(stderr, "%s: %s\n", arg, dlerror());
45 return;
46 }
47 sym = dlsym(hdl, p);
48
49 if (sym == NULL) {
50 fprintf(stderr, "%s: %s\n", p, dlerror());
51 return;
52 }
53
54 sym();
55}
56#endif
57
58static void
59local_shell_escape (char *arg)
60{
61#ifdef CANT_FORK
62 /* FIXME: what about errors (I don't know how GO32 system() handles
63 them)? */
64 system (arg);
65#else /* Can fork. */
66 int rc, status, pid;
67 char *p, *user_shell;
68
69 if ((user_shell = (char *) getenv ("SHELL")) == NULL)
70 user_shell = "/bin/sh";
71
72 /* Get the name of the shell for arg0 */
73 if ((p = strrchr (user_shell, '/')) == NULL)
74 p = user_shell;
75 else
76 p++; /* Get past '/' */
77
78 if ((pid = fork()) == 0)
79 {
80 if (!arg)
81 execl (user_shell, p, 0);
82 else
83 execl (user_shell, p, "-c", arg, 0);
84
85 fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
86 safe_strerror (errno));
87 gdb_flush (gdb_stderr);
88 _exit (0177);
89 }
90
91 if (pid != -1)
92 while ((rc = wait (&status)) != pid && rc != -1)
93 ;
94 else
95 error ("Fork failed");
96#endif /* Can fork. */
97}
98
99static void
100GetClassName(long objectID, char* name)
101{
102 register value_ptr val;
103 register struct symbol *sym;
104 struct minimal_symbol *msymbol;
105 struct type *type;
106 value_ptr blocklen;
107 LONGEST maddr;
108
109 /* Find the address of RemoteGetClassName in the inferior. */
110
111 sym = lookup_symbol ("RemoteGetClassName", 0, VAR_NAMESPACE, 0, NULL);
112 if (sym != NULL)
113 {
114 if (SYMBOL_CLASS (sym) != LOC_BLOCK)
115 {
116 error ("\"RemoteGetClassName\" exists in this program but is not a function.");
117 }
118 val = value_of_variable (sym, NULL);
119 }
120 else
121 {
122 msymbol = lookup_minimal_symbol ("RemoteGetClassName", "", (struct objfile *) NULL);
123 if (msymbol != NULL)
124 {
125 type = lookup_pointer_type (builtin_type_char);
126 type = lookup_function_type (type);
127 type = lookup_pointer_type (type);
128 maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
129 val = value_from_longest (type, maddr);
130 }
131 else
132 {
133 error ("evaluation of this expression requires the program to have a function \"RemoteGetClassName\".");
134 }
135 }
136
137 blocklen = value_from_longest (builtin_type_int, (LONGEST) objectID);
138 val = call_function_by_hand (val, 1, &blocklen);
139 if (value_logical_not (val))
140 {
141 error ("Could not get class name.");
142 }
143 read_memory(value_as_pointer(val), name, 32);
144
145}
146
147static CORE_ADDR
148GetBasePtr(long objectID)
149{
150 register value_ptr val;
151 register struct symbol *sym;
152 struct minimal_symbol *msymbol;
153 struct type *type;
154 value_ptr blocklen;
155 LONGEST maddr;
156
157 /* Find the address of RemoteGetBasePtr in the inferior. */
158
159 sym = lookup_symbol ("RemoteGetBasePtr", 0, VAR_NAMESPACE, 0, NULL);
160 if (sym != NULL)
161 {
162 if (SYMBOL_CLASS (sym) != LOC_BLOCK)
163 {
164 error ("\"RemoteGetBasePtr\" exists in this program but is not a function.");
165 }
166 val = value_of_variable (sym, NULL);
167 }
168 else
169 {
170 msymbol = lookup_minimal_symbol ("RemoteGetBasePtr", "", (struct objfile *) NULL);
171 if (msymbol != NULL)
172 {
173 type = lookup_pointer_type (builtin_type_char);
174 type = lookup_function_type (type);
175 type = lookup_pointer_type (type);
176 maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
177 val = value_from_longest (type, maddr);
178 }
179 else
180 {
181 error ("evaluation of this expression requires the program to have a function \"RemoteGetBasePtr\".");
182 }
183 }
184
185 blocklen = value_from_longest (builtin_type_int, (LONGEST) objectID);
186 val = call_function_by_hand (val, 1, &blocklen);
187 if (value_logical_not (val))
188 {
189 error ("Could not get base pointer to object.");
190 }
191 return value_as_pointer(val);
192}
193
194static void
195dump_extra_data(CORE_ADDR addr, ulong length)
196{
197 ulong buf[5], chunk, i;
198 char *p;
199
200 while (length > 3) {
201 chunk = (length > 16) ? 16 : length;
202
203 memset(buf, 0, 5*sizeof(long));
204 read_memory(addr, &buf, chunk);
205 fprintf(gdb_stdout, "%08lx %08lx %08lx %08lx | ", buf[0],
206 buf[1], buf[2], buf[3]);
207 for (i = 0, p = (char*)buf; i < chunk; i++, p++) {
208 if (!isprint(*p))
209 *p = '.';
210 }
211 fprintf(gdb_stdout, "%s |\n", buf);
212 addr += chunk;
213 length -= chunk;
214 }
215}
216
217struct type *type_of_object(CORE_ADDR object)
218{
219 char className[32], classAllFieldsName[128];
220 struct type *type = NULL;
221 GetClassName(object, className);
222 sprintf(classAllFieldsName, "%s_AllFields", className);
223
224 type = lookup_typename(classAllFieldsName, (struct block *)NULL, 0);
225 return lookup_pointer_type(type);
226}
227
228CORE_ADDR baseptr_of_object(ulong object)
229{
230 return GetBasePtr(object) + 12;
231}
232
233/* ARGSUSED */
234static void
235print_object (arg, dump)
236 char *arg;
237 int dump;
238{
239 CORE_ADDR addr;
240 ulong object, objectLength, typeLength = 0;
241 char className[32], classAllFieldsName[128];
242 struct type* type = NULL;
243
244 object = parse_and_eval_address(arg);
245
246 GetClassName(object, className);
247 sprintf(classAllFieldsName, "%s_AllFields", className);
248
249 type = lookup_typename(classAllFieldsName, (struct block *)NULL, 0);
250 typeLength = TYPE_LENGTH(type);
251 addr = GetBasePtr(object);
252 read_memory(addr, &objectLength, 4);
253 objectLength -= 12;
254 addr += 12;
255 if (TYPE_CODE(type) != TYPE_CODE_UNDEF && !(TYPE_FLAGS(type)&TYPE_FLAG_STUB)) {
256 if (dump) {
257 value_ptr valptr = value_at_lazy(type, addr);
258 int histindex = record_latest_value(valptr);
259 printf_filtered("Object 0x%08lx at address 0x%08lx of class %s\n",
260 object, addr, className);
261 if (histindex >= 0) printf_filtered ("$%d = ", histindex);
262 value_print(valptr, gdb_stdout, 0, Val_prettyprint);
263 objectLength -= typeLength;
264 addr += typeLength;
265 printf_filtered("\n");
266 dump_extra_data(addr, objectLength);
267 printf_filtered("\n");
268 } else {
269 value_ptr valptr = value_from_longest(lookup_pointer_type(type), addr);
270 int histindex = record_latest_value(valptr);
271 if (histindex >= 0) printf_filtered ("$%d = ", histindex);
272 value_print(valptr, gdb_stdout, 0, Val_prettyprint);
273 printf_filtered("\n");
274 }
275 }
276}
277
278/* ARGSUSED */
279static void
280dobj_command (arg, from_tty)
281 char *arg;
282 int from_tty;
283{
284 print_object(arg, 1);
285}
286
287/* ARGSUSED */
288static void
289pobj_command (arg, from_tty)
290 char *arg;
291 int from_tty;
292{
293 print_object(arg, 0);
294}
295
296/* ARGSUSED */
297static void
298getint_command (arg, from_tty)
299 char *arg;
300 int from_tty;
301{
302 char shellCommand[128];
303
304 sprintf(shellCommand, "getint %s", arg);
305 local_shell_escape(shellCommand);
306}
307
308/* ARGSUSED */
309static void
310getindexical_command (arg, from_tty)
311 char *arg;
312 int from_tty;
313{
314 char shellCommand[128];
315
316 sprintf(shellCommand, "getindexical %s", arg);
317 local_shell_escape(shellCommand);
318}
319
320/* ARGSUSED */
321static void
322exc_command (arg, from_tty)
323 char *arg;
324 int from_tty;
325{
326 char shellCommand[128];
327 ulong exception;
328
329 sprintf(shellCommand, "getexc %s", arg);
330 local_shell_escape(shellCommand);
331}
332
333static CORE_ADDR dispatch_method_addr = -1, dispatch_inherited_addr = -1, dispatch_delegated_addr = -1, dispatch_intrinsic_addr = -1;
334CORE_ADDR do_dispatch_method_addr = -1, do_dispatch_intrinsic_addr = -1;
335
336static CORE_ADDR
337lookup_address(const char *name)
338{
339 struct symbol *sym = lookup_symbol(name, NULL, VAR_NAMESPACE, NULL, NULL);
340 if (sym)
341 return BLOCK_START(SYMBOL_BLOCK_VALUE(sym));
342 else
343 {
344/* printf("Couldn't find %s!\n", name); */
345 return -1;
346 }
347}
348
349void
350init_magic()
351{
352 dispatch_method_addr = lookup_address("__DispatchMethod");
353 dispatch_inherited_addr = lookup_address("__DispatchInherited");
354 dispatch_delegated_addr = lookup_address("__DispatchDelegated");
355 dispatch_intrinsic_addr = lookup_address("__DispatchIntrinsic");
356 do_dispatch_method_addr = lookup_address("__DoTheDispatch");
357 do_dispatch_intrinsic_addr = lookup_address("__DoDispatchIntrinsic");
358}
359
360int
361is_dispatch(CORE_ADDR pc)
362{
363 return (pc == dispatch_method_addr) || (pc == dispatch_inherited_addr) || (pc == dispatch_delegated_addr);
364}
365
366int
367is_dispatch_intrinsic(CORE_ADDR pc)
368{
369 return pc == dispatch_intrinsic_addr;
370}
371
372/* If we are stopped at one of the entry points to the dispatcher, we want to continue until just
373 before we jump to the implementation. If we are at that point, we want to continue until we
374 actually get to the implementation. Likewise for the intrinsic dispatcher
375 */
376CORE_ADDR
377deal_with_dispatch(CORE_ADDR stop_pc)
378{
379 if (is_dispatch(stop_pc))
380 return do_dispatch_method_addr;
381 else if (is_dispatch_intrinsic(stop_pc))
382 return do_dispatch_intrinsic_addr;
383 else if (stop_pc == do_dispatch_method_addr)
384 /* This assumes that we branch through t6 */
385 return read_register(14);
386 else if (stop_pc == do_dispatch_intrinsic_addr)
387 /* This assumes that we branch through t0 */
388 return read_register(8);
389 else
390 return 0;
391}
392
393void
394magic_create_inferior_hook()
395{
396 struct symbol *sym = lookup_symbol("gHandleError", NULL, VAR_NAMESPACE, NULL, NULL);
397 if (sym)
398 {
399 CORE_ADDR addr = SYMBOL_VALUE(sym);
400 unsigned long errorDebugger = 2;
401 target_write_memory(addr, &errorDebugger, 4);
402 }
403
404 init_magic ();
405}
406
407
408_initialize_magic ()
409{
410 add_com ("dobj", class_support, dobj_command, "Display Object Contents");
411 add_com ("pobj", class_support, pobj_command, "Print object base pointer");
412 add_com ("getint", class_support, getint_command, "Convert intrinsic name to number or vice versa.");
413 add_com ("getindexical", class_support, getindexical_command, "Convert indexical name to number or vice versa.");
414 add_com ("exc", class_support, exc_command, "Convert exception name to number or vice versa.");
415
416#ifdef DYNAMIC_COMMAND_SUPPORT
417 add_com ("dlopen", class_support, dlopen_command,
418 "Load the dynamic library specified and execute the specified symbol");
419#endif
420}
This page took 0.040922 seconds and 4 git commands to generate.