* breakpoint.c (breakpoint_re_set): #ifdef GET_LONGJMP_TARGET
[deliverable/binutils-gdb.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.048075 seconds and 4 git commands to generate.