]> Git Repo - binutils.git/blob - gdb/magic.c
* breakpoint.c (breakpoint_re_set): #ifdef GET_LONGJMP_TARGET
[binutils.git] / gdb / magic.c
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
11 typedef unsigned long ulong;
12
13 #ifdef DYNAMIC_COMMAND_SUPPORT
14 static void
15 dlopen_command PARAMS ((char *, int));
16 #endif
17
18 #ifdef DYNAMIC_COMMAND_SUPPORT
19 /* ARGSUSED */
20 static void
21 dlopen_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
58 static void
59 local_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
99 static void
100 GetClassName(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
147 static CORE_ADDR
148 GetBasePtr(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
194 static void
195 dump_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
217 struct 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
228 CORE_ADDR baseptr_of_object(ulong object)
229 {
230         return GetBasePtr(object) + 12;
231 }
232
233 /* ARGSUSED */
234 static void
235 print_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 */
279 static void
280 dobj_command (arg, from_tty)
281      char *arg;
282      int from_tty;
283 {
284         print_object(arg, 1);
285 }
286
287 /* ARGSUSED */
288 static void
289 pobj_command (arg, from_tty)
290      char *arg;
291      int from_tty;
292 {
293         print_object(arg, 0);
294 }
295
296 /* ARGSUSED */
297 static void
298 getint_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 */
309 static void
310 getindexical_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 */
321 static void
322 exc_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
333 static CORE_ADDR dispatch_method_addr = -1, dispatch_inherited_addr = -1, dispatch_delegated_addr = -1, dispatch_intrinsic_addr = -1;
334 CORE_ADDR do_dispatch_method_addr = -1, do_dispatch_intrinsic_addr = -1;
335
336 static CORE_ADDR
337 lookup_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
349 void
350 init_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
360 int
361 is_dispatch(CORE_ADDR pc)
362 {
363   return (pc == dispatch_method_addr) || (pc == dispatch_inherited_addr) || (pc == dispatch_delegated_addr);
364 }
365
366 int
367 is_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    */
376 CORE_ADDR 
377 deal_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
393 void
394 magic_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.0508 seconds and 4 git commands to generate.