6 #include "breakpoint.h"
13 #ifdef DYNAMIC_COMMAND_SUPPORT
17 #ifdef ANSI_PROTOTYPES
24 /* Maximum number of bytes of extra data to print, or UINT_MAX for no limit.
25 Note that "set extra-data-max 0" stores UINT_MAX in extra_data_max, which
26 displays in a show command as "unlimited." */
28 static unsigned int extra_data_max;
29 #define EXTRA_DATA_MAX_DEFAULT 1024
31 /* Return the number of elements in ARRAY. */
33 #define ARRAY_NELEMENTS(array) (sizeof (array) / sizeof (array[0]))
35 /* Basic information about a text label */
39 char *name; /* label name */
40 CORE_ADDR addr; /* label value or 0 if label not found */
43 /* Labels within the Magic Cap dispatcher that we need to know about
44 in order to implement "magic stepping" (that is, stepping over
45 Magic Cap method dispatches). The label addresses are refreshed
46 whenever a new symbol table is loaded. */
48 struct text_label dispatch_labels[] =
50 {"__DispatchMethod", 0}, /* normal dispatch entry point */
51 {"__DispatchInherited", 0}, /* inherited dispatch entry point */
52 {"__DispatchDelegated", 0}, /* delegated dispatch entry point */
53 {"__DispatchIntrinsic", 0}, /* intrinsic dispatch entry point */
54 {"__DoDispatchMethodBpSite", 0}, /* do dispatch site */
57 /* Accessors for the array above. */
59 #define DISPATCH_METHOD_ADDR dispatch_labels[0].addr
60 #define DISPATCH_INHERITED_ADDR dispatch_labels[1].addr
61 #define DISPATCH_DELEGATED_ADDR dispatch_labels[2].addr
62 #define DISPATCH_INTRINSIC_ADDR dispatch_labels[3].addr
63 #define DO_DISPATCH_METHOD_ADDR dispatch_labels[4].addr
65 /* Cached value objects describing functions in the target program that
66 we call frequently. These are refreshed whenever a new symbol table
69 static value_ptr remote_get_class_name_val;
70 static value_ptr remote_get_base_ptr_val;
72 /* Nonzero means that "magic step" (stepping through the Magic Cap method
73 dispatcher to the dispatch target) is enabled. */
75 static int magic_step_enabled;
77 /* function prototypes */
80 print_object PARAMS ((char *args, int dump));
83 get_class_name PARAMS ((unsigned long objectID, char **name, int *is_scripted));
86 get_base_ptr PARAMS ((unsigned long objectID));
89 should_dump_extra_data PARAMS ((char *class_name));
92 dump_extra_data PARAMS ((CORE_ADDR addr, unsigned long length));
95 call_function_by_name PARAMS ((char *function_name, int nargs, ...));
98 call_function_by_value PARAMS ((value_ptr function_value, int nargs, ...));
101 vcall_function_by_value PARAMS ((value_ptr function_value, int nargs,
104 local_shell_escape PARAMS ((char *arg));
107 lookup_text_label PARAMS ((char *name, value_ptr *val_ptrptr));
110 is_dispatcher_entry PARAMS ((CORE_ADDR pc));
113 is_dispatcher_exit PARAMS ((CORE_ADDR pc));
116 /* This is the GDB handler for the "dobj" command, which prints a
117 verbose description of an object. ARGS is a string containing an
118 expression for the object ID, and FROM_TTY is nonzero if the
119 command was issued interactively. */
123 dobj_command (args, from_tty)
127 if (remote_get_class_name_val == NULL)
128 error ("This version of Magic Cap lacks the runtime support for \"dobj\".");
130 print_object (args, 1);
133 /* This is the GDB handler for the "pobj" command, which prints a
134 brief description of an object. ARGS is a string containing an
135 expression for the object ID, and FROM_TTY is nonzero if the
136 command was issued interactively. */
140 pobj_command (args, from_tty)
144 if (remote_get_class_name_val == NULL)
145 error ("This version of Magic Cap lacks the runtime support for \"pobj\".");
147 print_object (args, 0);
150 /* This is the GDB handler for the "cdump" command, which prints a
151 description of a cluster. ARGS is a string containing a cluster
152 selector, and FROM_TTY is nonzero if the command was issued
155 cdump <contextSlot> [/l[ocked]] [/s[tartAddr] <expr>]
156 [/c[lass] <className> | <classNumber>] */
160 cdump_command (args, from_tty)
165 unsigned long cluster;
166 CORE_ADDR min_object;
167 long display_only_locked;
169 long display_only_class_number;
170 char *display_only_class_name;
173 error_no_arg ("expression for context slot to dump");
175 token = strtok (args, " \t");
177 error ("The first argument to cdump must be an expression for the context slot to dump.");
179 cluster = parse_and_eval_address (token);
181 /* Initialize option values. Note that we assume that
182 sizeof (long) == sizeof (void *) here, in that we pass
183 min_object as a long, even though it is a pointer. */
186 display_only_locked = 0;
188 display_only_class_name = NULL;
189 display_only_class_number = 0;
191 while ((token = strtok (NULL, " \t")) != NULL)
199 if (token[2] && strcmp (token + 1, "locked"))
202 display_only_locked = 1;
206 if (token[2] && strcmp (token + 1, "startAddr"))
209 if ((token = strtok (NULL, " \t")) == NULL)
210 error ("Missing start address expression for `/s' option.");
212 min_object = parse_and_eval_address (token);
216 if (token[2] && strcmp (token + 1, "class"))
219 if ((token = strtok (NULL, " \t")) == NULL)
220 error ("Missing class name or number for `/c' option.");
223 if (isdigit (token[0]))
224 display_only_class_number = parse_and_eval_address (token);
226 display_only_class_name = token;
235 if (display_only_class_name != NULL)
236 error ("Sorry, `/c <className>' isn't supported yet.");
238 (void)call_function_by_name ("cdump", 6, cluster, min_object,
240 filter_classes, display_only_class_number,
241 display_only_class_name);
245 error ("Invalid option: `%s'.", token);
248 /* This is the GDB handler for the "esc" command, which lists the
249 exception handlers for a given actor. ARGS is a string containing
250 an expression for the objectID of the actor in question, and FROM_TTY
251 is nonzero if the command was issued interactively. */
255 esc_command (args, from_tty)
259 unsigned long object;
262 error_no_arg ("expression for actor's object ID");
264 object = parse_and_eval_address (args);
265 (void)call_function_by_name ("esc", 1, object);
268 /* This is the GDB handler for the "cnum" command, which converts
269 a class number to a class name. ARGS is a string containing an
270 expression for the class number, and FROM_TTY is nonzero if the
271 command was issued interactively. */
275 cnum_command (args, from_tty)
282 error_no_arg ("expression for class number");
284 cnum = parse_and_eval_address (args);
285 (void)call_function_by_name ("cnum", 1, cnum);
288 /* This is the GDB handler for the "getint" command, which converts an
289 intrinsic operation number to the corresponding intrinsic operation name,
290 or vice-versa. ARGS is a string containing the intrinsic number or name,
291 and FROM_TTY is nonzero if the command was issued interactively. */
295 getint_command (args, from_tty)
299 char shell_command[256];
302 error_no_arg ("intrinsic operation number or name");
304 if (isdigit (args[0]))
305 sprintf (shell_command, "getint %ld", parse_and_eval_address (args));
307 sprintf (shell_command, "getint %s", args);
309 local_shell_escape (shell_command);
312 /* This is the GDB handler for the "getop" command, which converts an
313 operation number to the corresponding operation name, or vice-versa.
314 ARGS is a string containing the operation number or name, and FROM_TTY
315 is nonzero if the command was issued interactively. */
319 getop_command (args, from_tty)
323 char shell_command[256];
327 error_no_arg ("operation number or name");
329 if (isdigit (args[0]))
330 sprintf (shell_command, "getop %ld", parse_and_eval_address (args));
332 sprintf (shell_command, "getop %s", args);
334 local_shell_escape (shell_command);
337 /* This is the GDB handler for the "getindexical" command, which converts
338 an indexical number to the corresponding indexical name, or vice-versa.
339 ARGS is a string containing the indexical number or name, and FROM_TTY
340 is nonzero if the command was issued interactively. */
344 getindexical_command (args, from_tty)
348 char shell_command[256];
351 error_no_arg ("indexical number or name");
353 if (isdigit (args[0]))
354 sprintf (shell_command, "getindexical 0x%lx",
355 parse_and_eval_address (args));
357 sprintf (shell_command, "getindexical %s", args);
359 local_shell_escape (shell_command);
362 /* This is the GDB handler for the "exc" command, which converts an
363 exception number to the corresponding exception name, or vice-versa.
364 ARGS is a string containing the exception number or name, and FROM_TTY
365 is nonzero if the command was issued interactively.
367 FIXME why is this one "exc" instead of "getexc?" (inconsistent naming). */
371 exc_command (args, from_tty)
375 char shell_command[256];
378 error_no_arg ("exception number or name");
380 if (isdigit (args[0]))
381 sprintf (shell_command, "getexc %ld", parse_and_eval_address (args));
383 sprintf (shell_command, "getexc %s", args);
385 local_shell_escape (shell_command);
388 #ifdef DYNAMIC_COMMAND_SUPPORT
389 /* Open a dynamic library and invoke an entry point within it.
390 ARGS is a string containing the names of the dynamic library
391 and the symbolic entry point, separated by whitespace. */
395 dlopen_command (args, from_tty)
405 error ("No arguments specified.");
410 while (*p != ' ' && *p != '\0')
415 error ("Not enough arguments.");
420 hdl = dlopen (args, RTLD_NOW);
423 fprintf (stderr, "%s: %s\n", args, dlerror ());
427 sym = dlsym (hdl, p);
430 fprintf (stderr, "%s: %s\n", p, dlerror ());
436 #endif /* DYNAMIC_COMMAND_SUPPORT */
438 /* Given an object ID OBJECT, return a pointer to a type structure
439 representing the GDB type that describes the layout of the object's
440 fields in memory (i.e., the "_AllFields" structure corresponding
441 to the object's class). */
444 type_of_object (object)
447 char *class_name = NULL;
448 char classAllFieldsName[128];
449 struct type *type = NULL;
452 get_class_name (object, &class_name, &is_scripted);
453 sprintf (classAllFieldsName, "%s_AllFields", class_name);
456 type = lookup_typename (classAllFieldsName, (struct block *)NULL, 0);
457 return lookup_pointer_type (type);
460 /* Given OBJECT, an object ID, return the address of the object's
464 baseptr_of_object (object)
465 unsigned long object;
467 return get_base_ptr (object) + kSizeOfObjectHeader;
470 /* Given an expression for an object ID, ARGS, print information about
471 the object--including its class, the values of its fixed fields, and
472 the values in its extra data block. */
476 print_object (args, dump)
481 unsigned long object, object_length;
482 char *class_name = NULL;
483 char class_all_fields_name[128];
486 struct cleanup *old_chain;
489 error_no_arg ("expression for object ID");
491 object = parse_and_eval_address (args);
493 /* check for nilObject */
497 printf_filtered ("\"%s\" evaluates to nilObject.\n", args);
501 /* allow shortcut for system object ids */
503 if (IsObjectID (object))
504 object |= 1 << kIDBitUsable;
505 else if (object < 0x5000)
506 object |= (1 << kIDBitObject) | (1 << kIDBitUsable); /* 0x84000000 */
508 /* Get the name of the object's class, as well as the GDB type that
509 describes the layout of the object's fixed fields. */
511 get_class_name (object, &class_name, &is_scripted);
512 old_chain = make_cleanup (free_current_contents, &class_name);
514 sprintf (class_all_fields_name, "%s_AllFields", class_name);
515 type = lookup_typename (class_all_fields_name, (struct block *)NULL, 1);
517 /* Get pointer to object's fields.
518 FIXME: ADDR is actually an (ObjectHeader *); should use normal expression
519 evaluator to extract the length member, rather than hardwiring the
520 format of the structure in this code. */
522 addr = get_base_ptr (object);
523 object_length = read_memory_unsigned_integer (addr, 4);
524 object_length -= kSizeOfObjectHeader;
525 addr += kSizeOfObjectHeader;
527 if (type == NULL || (TYPE_CODE (type) != TYPE_CODE_UNDEF
528 && !(TYPE_FLAGS (type) & TYPE_FLAG_STUB)))
532 unsigned long fixed_length;
534 printf_filtered ("Object 0x%08lx%s at address 0x%08lx of class %s\n",
535 object, (is_scripted) ? " (scripted)" : "",
538 /* If the object has fixed fields, dump them. */
542 value_ptr valptr = value_at_lazy (type, addr);
543 int histindex = record_latest_value (valptr);
546 printf_filtered ("$%d = ", histindex);
548 value_print (valptr, gdb_stdout, 0, Val_prettyprint);
549 puts_filtered ("\n");
550 fixed_length = TYPE_LENGTH (type);
555 /* If the object's length is less than that of its fixed fields,
558 if (object_length < fixed_length)
560 error ("Warning: object is too small (should be at least %d bytes, is %d bytes).",
561 fixed_length, object_length);
564 /* Dump the object's extra data, if any. should_dump_extra_data ()
565 filters out classes (e.g. Cluster) that have too much extra data
566 to be dumped usefully in this format. */
568 if (should_dump_extra_data (class_name))
570 dump_extra_data (addr + fixed_length,
571 object_length - fixed_length);
576 struct type *pointer_type;
580 pointer_type = lookup_pointer_type ((type == NULL) ?
581 builtin_type_void : type);
582 valptr = value_from_longest (pointer_type, addr);
584 histindex = record_latest_value (valptr);
586 printf_filtered ("$%d = ", histindex);
588 value_print (valptr, gdb_stdout, 0, Val_prettyprint);
589 puts_filtered ("\n");
592 do_cleanups (old_chain);
595 /* Get the name of the class of the object referenced by OBJECTID.
596 *NAME is set to a pointer to the string containing the class
597 name; it is the caller's responsibility to free the memory for
598 the string. *IS_SCRIPTED is set to nonzero if the object is
599 scripted, zero otherwise. */
602 get_class_name (objectID, name, is_scripted)
603 unsigned long objectID;
610 val = call_function_by_value (remote_get_class_name_val, 1, objectID);
612 /* As RemoteGetClassName() is currently (9/21/95) written, an empty string,
613 rather than a nil pointer, is returned upon failure. I'm leaving the
614 value_logical_not test in anyway, though, just for added robustness. */
616 if (!value_logical_not (val))
618 (void)target_read_string (value_as_pointer (val), name, 256, &errno_val);
620 error ("Can't read class name for object 0x%08lx.", objectID);
624 char *scripted_suffix;
626 if ((scripted_suffix = strstr (*name, " (scripted)")) != NULL)
628 *scripted_suffix = '\0';
640 error ("Bad object ID: 0x%08lx.", objectID);
643 /* Given an object ID, return a pointer to the object's data. */
646 get_base_ptr (objectID)
647 unsigned long objectID;
649 register value_ptr val;
651 val = call_function_by_value (remote_get_base_ptr_val, 1, objectID);
653 if (value_logical_not (val))
654 error ("Could not get base pointer to object.");
656 return value_as_pointer (val);
659 /* Return nonzero if we should dump the extra data for an object
662 FIXME this only works for explicitly named classes, and doesn't
663 handle subclasses. */
666 should_dump_extra_data (class_name)
671 static char *dont_dump_extra_classes[] =
676 for (i = 0, name = dont_dump_extra_classes;
677 i < ARRAY_NELEMENTS(dont_dump_extra_classes);
680 if (!strcmp (class_name, *name))
687 /* Given ADDR, the address of an object's extra data block, and LENGTH,
688 the length of that block in bytes, dump the object's extra data to
692 dump_extra_data (addr, length)
694 unsigned long length;
696 unsigned long buf[5];
705 while (length > 3 && bytes_printed < extra_data_max)
707 QUIT; /* allow user to interrupt dump */
709 /* read a chunk of extra data */
711 chunk = (length > 16) ? 16 : length;
712 memset (buf, 0, sizeof (buf));
713 read_memory (addr, (char *) &buf, chunk);
715 /* format data as hex longwords */
717 chunk_longs = chunk >> 2;
718 for (i = 0; i < chunk_longs; i++)
719 printf_filtered ("%08lx ",
720 extract_unsigned_integer (buf + i, sizeof (long)));
724 for (i = chunk_longs; i < 4; i++)
727 puts_filtered ("| ");
729 /* format data as ascii bytes */
731 for (i = 0, p = (char*)buf; i < chunk; i++, p++)
736 printf_filtered ("%s |\n", buf);
740 bytes_printed += chunk;
744 printf_filtered ("(%d bytes of extra data remaining but not displayed.)\n",
748 /* Given the name of a function in the target program and a list of
749 long arguments, call the function and return a pointer to a value
750 object describing the function's return value. NAME is a string
751 containing the name of the function to be called; NARGS is the
752 number of arguments to the function; and the remaining parameters
753 are the arguments to passed to the function, all assumed to be of
757 #ifdef ANSI_PROTOTYPES
758 call_function_by_name (char *function_name, int nargs, ...)
760 call_function_by_name (va_alist)
765 value_ptr return_value;
766 value_ptr function_value;
767 #ifndef ANSI_PROTOTYPES
772 function_name = va_arg (args, char *);
773 nargs = va_arg (args, int);
775 va_start (args, nargs);
778 /* Find the address of function NAME in the inferior. */
780 if (!lookup_text_label (function_name, &function_value))
781 error ("Execution of this command requires the debugged program to have a function \"%s.\"",
784 /* Call the function. */
786 return_value = vcall_function_by_value (function_value, nargs, args);
792 /* Given a value object describing a function in the target program and
793 a list of long arguments, call the function and return a pointer to a
794 value object describing the function's return value. FUNCTION_VALUE
795 is a pointer to a value struct describing the function; NARGS is the
796 number of arguments to the function; and the remaining parameters are
797 the arguments to passed to the function, all assumed to be of type long. */
800 #ifdef ANSI_PROTOTYPES
801 call_function_by_value (value_ptr function_value, int nargs, ...)
803 call_function_by_value (va_alist)
808 value_ptr return_value;
809 #ifndef ANSI_PROTOTYPES
810 value_ptr function_value;
814 function_value = va_arg (args, value_ptr);
815 nargs = va_arg (args, int);
817 va_start (args, nargs);
820 /* Call the function and return its return value. */
822 return_value = vcall_function_by_value (function_value, nargs, args);
828 /* Helper routine for call_function_by_name and call_function_by_value
829 above. This function does the work of collecting the function
830 arguments into an array of value objects, and then invoking
831 call_function_by_hand to do the real work. FUNCTION_VALUE is a
832 pointer to a value object describing the function to be called,
833 NARGS is the number of arguments to the function, and ARGS is a
834 list (va_list) of the arguments to the function, all assumed to
837 Returns a pointer to a value object describing the return value
841 vcall_function_by_value (function_value, nargs, args)
842 value_ptr function_value;
846 value_ptr *arg_values;
847 value_ptr return_value;
848 struct cleanup *old_chain;
851 /* Construct a vector of value objects describing the arguments
852 to the function to be called. */
854 arg_values = (value_ptr *) xmalloc (nargs * sizeof (value_ptr));
855 old_chain = make_cleanup (free_current_contents, &arg_values);
857 for (i = 0; i < nargs; i++)
858 arg_values[i] = value_from_longest (builtin_type_long,
859 (LONGEST) va_arg (args, unsigned long));
861 /* Call the function and return its return value. */
863 return_value = call_function_by_hand (function_value, nargs, arg_values);
864 do_cleanups (old_chain);
868 /* Invoke a shell, supplying ARG as the command to be executed. */
871 local_shell_escape (arg)
875 /* FIXME: what about errors (I don't know how GO32 system() handles
878 #else /* Can fork. */
880 char *p, *user_shell;
882 if ((user_shell = (char *) getenv ("SHELL")) == NULL)
883 user_shell = "/bin/sh";
885 /* Get the name of the shell for arg0 */
886 if ((p = strrchr (user_shell, '/')) == NULL)
889 p++; /* Get past '/' */
891 if ((pid = fork()) == 0)
894 execl (user_shell, p, 0);
896 execl (user_shell, p, "-c", arg, 0);
898 fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
899 safe_strerror (errno));
900 gdb_flush (gdb_stderr);
905 while ((rc = wait (&status)) != pid && rc != -1)
908 error ("Fork failed");
909 #endif /* Can fork. */
912 /* Lookup NAME as a text label in the target program. If NAME is the
913 name of a function, and VAL_PTRPTR is not NULL, a pointer to a value
914 object describing the function is stored at VAL_PTRPTR.
916 Returns the text address to which the label refers, or 0 if the
917 label is not found in the target program. */
920 lookup_text_label (name, val_ptrptr)
922 value_ptr *val_ptrptr;
929 /* Try looking up NAME as a first-class symbol. */
931 sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
934 switch (SYMBOL_CLASS (sym))
937 addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
938 if (val_ptrptr != NULL)
939 *val_ptrptr = value_of_variable (sym, NULL);
945 addr = SYMBOL_VALUE_ADDRESS (sym);
951 struct minimal_symbol *msymbol;
954 /* Try to find a minimal symbol for NAME. */
956 msymbol = lookup_minimal_symbol (name, "", (struct objfile *) NULL);
959 addr = SYMBOL_VALUE_ADDRESS (msymbol);
960 if (val_ptrptr != NULL)
962 type = lookup_pointer_type (builtin_type_char);
963 type = lookup_function_type (type);
964 type = lookup_pointer_type (type);
965 *val_ptrptr = value_from_longest (type, addr);
972 /* The following two routines adapt GDB's framework for stepping over
973 shared library trampoline code to the problem of stepping over the
974 Magic Cap method dispatcher. While the method dispatcher is not a
975 shared library trampoline, we can use the interfaces for controlling
976 stepping over trampolines to do what we want. */
978 /* Return nonzero if STOP_PC is within the Magic Cap method dispatcher.
979 NAME is unused. This function serves as the implementation of both
980 IN_SOLIB_CALL_TRAMPOLINE() and IN_SOLIB_RETURN_TRAMPOLINE() when GDB
981 is configured to target Magic Cap. We don't need to distinguish
982 between the two types of trampolines (because they're not really
983 trampolines); we just need to tell GDB to set a breakpoint at the
984 site of the next "hop" on our way through the dispatcher, and to
988 magic_in_dispatcher (stop_pc, name)
992 return magic_step_enabled
993 && (is_dispatcher_entry (stop_pc) || is_dispatcher_exit (stop_pc));
996 /* Determine if STOP_PC is an address within the Magic Cap method
997 dispatcher, and if so, return the address at which GDB should set
998 a step resume breakpoint in order to skip over the dispatcher code.
999 In fact, we have to skip over the dispatcher in two separate "hops:"
1000 the first hop gets us from a dispatcher entry point to the dispatcher
1001 exit site; the second hop gets us from this exit site to the first
1002 instruction of the method.
1004 This function serves as the implementation of SKIP_TRAMPOLINE_CODE()
1005 when GDB is configured to target Magic Cap. */
1008 magic_skip_dispatcher (stop_pc)
1011 /* If magic stepping is disabled, return 0, indicating that GDB should
1012 process this step event normally. This will have the effect of
1013 allowing the user to step through the dispatcher code itself. */
1015 if (!magic_step_enabled)
1018 /* If the program is stopped at an entry point to the dispatcher,
1019 tell GDB to set a breakpoint at a well-known label in the
1020 dispatcher where we will be able to determine the address of
1021 the method to which we are dispatching. Note that the dispatcher
1022 has hair to ensure that the code at this label is executed when we
1023 are completing a top-level dispatch; recursive dispatches generated
1024 from within the dispatcher do not exit through this code. */
1026 if (is_dispatcher_entry (stop_pc))
1027 return DO_DISPATCH_METHOD_ADDR;
1029 /* If we have hit the breakpoint set previously at a dispatcher exit site,
1030 determine the method address and tell GDB to set a breakpoint there. */
1032 else if (is_dispatcher_exit (stop_pc))
1033 return read_register (14); /* assumes that we branch through t6 */
1038 /* Return nonzero if PC is an entry point to the Magic Cap method
1042 is_dispatcher_entry (pc)
1045 return pc == DISPATCH_METHOD_ADDR
1046 || pc == DISPATCH_INTRINSIC_ADDR
1047 || pc == DISPATCH_INHERITED_ADDR
1048 || pc == DISPATCH_DELEGATED_ADDR;
1051 /* Return nonzero if PC is an exit site from the Magic Cap method
1055 is_dispatcher_exit (pc)
1058 return pc == DO_DISPATCH_METHOD_ADDR;
1061 /* Store away addresses in the inferior we need to control single-stepping
1062 through Magic Cap method dispatches, as well as other addresses of
1063 interest in Magic Cap. */
1068 struct text_label *label;
1071 /* Cache method dispatch label addresses. */
1073 for (i = 0, label = dispatch_labels;
1074 i < ARRAY_NELEMENTS (dispatch_labels);
1077 if (!(label->addr = lookup_text_label (label->name, NULL)))
1079 /* If we can't find all of the dispatcher addresses, don't attempt
1080 to do magic stepping. */
1082 magic_step_enabled = 0;
1087 /* Cache value objects for RemoteGetClassName () and RemoteGetBasePtr (),
1088 which are used to implement the "dobj" and "pobj" commands. Note that
1089 we must call release_value () on these values to prevent GDB from freeing
1090 them automatically. */
1092 if (remote_get_class_name_val != NULL)
1094 value_free (remote_get_class_name_val);
1095 remote_get_class_name_val = NULL;
1098 if (remote_get_base_ptr_val != NULL)
1100 value_free (remote_get_base_ptr_val);
1101 remote_get_base_ptr_val = NULL;
1104 if (lookup_text_label ("RemoteGetClassName", &remote_get_class_name_val))
1106 release_value (remote_get_class_name_val);
1108 if (lookup_text_label ("RemoteGetBasePtr", &remote_get_base_ptr_val))
1109 release_value (remote_get_base_ptr_val);
1113 /* Hook routine called when an inferior (i.e., debugged) process is
1117 magic_create_inferior_hook ()
1119 struct symbol *sym = lookup_symbol ("gHandleError", NULL, VAR_NAMESPACE,
1123 CORE_ADDR addr = SYMBOL_VALUE (sym);
1124 unsigned long errorDebugger = 2;
1126 target_write_memory (addr, (char *) &errorDebugger, 4);
1130 /* Initialization routine for magic.c. This is where we define debugger
1131 commands specific to Magic Cap. */
1134 _initialize_magic ()
1136 add_com ("dobj", class_support, dobj_command,
1137 "Display object contents.\n\
1138 Usage: dobj <objectID>\n\
1139 Where: <objectID> is an expression for the object ID to dump.");
1141 add_com ("pobj", class_support, pobj_command,
1142 "Print object base pointer.\n\
1143 Usage: pobj <objectID>\n\
1144 Where: <objectID> is an expression for the object ID to examine.");
1146 add_com ("cdump", class_support, cdump_command,
1147 concat ("Display the contents of a cluster.\n\
1148 Usage: cdump <contextSlot> [/l[ocked]] [/s[tartAddr] <addr>]\n\
1149 [/c[lass] <classNumber>]\n\
1150 Where: <contextSlot> is an expression describing the cluster to dump;\n\
1151 if <contextSlot> is a number between 0x8 and 0xf, it is \n\
1152 interpreted as the high-order nibble of an object ID\n\
1153 belonging to the cluster to dump, with the second highest-\n\
1154 order nibble assumed to be 0. (For example, \"cdump 8\" and \n\
1155 \"cdump 0xa\" dump the System Persistent and Persistent RAM\n\
1156 clusters, respectively.)\n",
1158 if <contextSlot> is a number between 0xf0 and 0x100, it is\n\
1159 interpreted as the high-order byte of an object ID belonging to\n\
1160 the cluster to dump. (For example, \"cdump 0x88\" and \n\
1161 \"cdump 0xa8\" dump the Locked Persistent and Transient RAM\n\
1162 clusters, respectively.)\n",
1164 /locked or /l indicates that only locked objects are to be displayed.\n\
1166 /startAddr or /s indicates that only objects whose base pointers are\n\
1167 greater than or equal to the address specified by the following\n\
1168 expression (<startAddr>) are to be displayed.\n\
1170 /class or /c indicates that only objects of the class specified by\n\
1171 the following expression <classNumber> are to be displayed.",
1174 add_com ("esc", class_support, esc_command,
1175 "List all the exception handlers for a given actor.\n\
1176 Usage: esc <objectID>\n\
1177 Where: <objectID> is an expression for the object ID of the actor\n\
1178 whose exception handlers are to be listed.");
1180 add_com ("cnum", class_support, cnum_command,
1181 "Convert class number to name.\n\
1182 Usage: cnum <classNumber>\n\
1183 Where: <classNumber> is an expression for the class number to convert.");
1185 add_com ("getint", class_support, getint_command,
1186 "Convert intrinsic name to number or vice versa.\n\
1187 Usage: getint <intrinsicName> | <intrinsicNumber>\n\
1188 Where: <intrinsicName> | <intrinsicNumber> is an intrinsic operation name\n\
1189 to be converted to an operation number, or an intrinsic operation\n\
1190 number to be converted to an operation name.");
1192 add_com ("getop", class_support, getop_command,
1193 "Convert operation name to number or vice versa.\n\
1194 Usage: getop <operationName> | <operationNumber>\n\
1195 Where: <operationName> | <operationNumber> is an operation name to be\n\
1196 converted to an operation number, or an operation number to\n\
1197 be converted to an operation name.");
1199 add_com ("getindexical", class_support, getindexical_command,
1200 "Convert indexical name to number or vice versa.\n\
1201 Usage: getindexical <indexicalName> | <indexicalNumber>\n\
1202 Where: <indexicalName> | <indexicalNumber> is an indexical name to be\n\
1203 converted to an an indexical number, or an indexical number\n\
1204 to be converted to an indexical name.");
1206 add_com ("exc", class_support, exc_command,
1207 "Convert exception name to number or vice versa.\n\
1208 Usage: exc <exceptionName> | <exceptionNumber>\n\
1209 Where: <exceptionName> | <exceptionNumber> is an exception name to be\n\
1210 converted to an an exception number, or an exception number\n\
1211 to be converted to an exception name.");
1214 (add_set_cmd ("extra-data-max", class_support, var_uinteger,
1215 (char *) &extra_data_max,
1216 "Set limit on number of bytes of extra data to print.\n\
1217 This command sets an upper limit on the number of bytes of extra\n\
1218 data displayed by the \"dobj\" command when dumping a Magic Cap\n\
1219 object. \"set extra-data-max 0\" causes there to be no limit.",
1223 extra_data_max = EXTRA_DATA_MAX_DEFAULT;
1226 (add_set_cmd ("magic-step", class_support, var_boolean,
1227 (char *) &magic_step_enabled,
1228 "Set stepping over Magic Cap method dispatches.\n\
1229 When set to \"on\" (the default), issuing a \"step\" command at a Magic Cap\n\
1230 operation call site will cause the program to stop at the first line of\n\
1231 the corresponding method. Set this to \"off\" only if you need to debug\n\
1232 the dispatcher itself.",
1236 magic_step_enabled = 1;
1238 #ifdef DYNAMIC_COMMAND_SUPPORT
1239 add_com ("dlopen", class_support, dlopen_command,
1240 "Load the dynamic library specified and execute the specified symbol");