- /* now call the function */
-
- val = call_function_by_hand (funcval, 6, args);
-
- /* now get the results */
-
- target_read_memory (errno_return_addr, (char *) &err_value, sizeof (err_value));
-
- target_read_memory (value_return_addr, (char *) &stub_addr, sizeof (stub_addr));
- if (stub_addr <= 0)
- error (_("call to __d_shl_get failed, error code is %d"), err_value);
-
- return (stub_addr);
-}
-
-/* Cover routine for find_stub_with_shl_get to pass to catch_errors */
-static int
-cover_find_stub_with_shl_get (void *args_untyped)
-{
- args_for_find_stub *args = args_untyped;
- args->return_val = find_stub_with_shl_get (args->msym, args->solib_handle);
- return 0;
-}
-
-/* Initialize exception catchpoint support by looking for the
- necessary hooks/callbacks in end.o, etc., and set the hook value
- to point to the required debug function.
-
- Return 0 => failure
- 1 => success */
-
-static int
-initialize_hp_cxx_exception_support (void)
-{
- struct symtabs_and_lines sals;
- struct cleanup *old_chain;
- struct cleanup *canonical_strings_chain = NULL;
- int i;
- char *addr_start;
- char *addr_end = NULL;
- char **canonical = (char **) NULL;
- int thread = -1;
- struct symbol *sym = NULL;
- struct minimal_symbol *msym = NULL;
- struct objfile *objfile;
- asection *shlib_info;
-
- /* Detect and disallow recursion. On HP-UX with aCC, infinite
- recursion is a possibility because finding the hook for exception
- callbacks involves making a call in the inferior, which means
- re-inserting breakpoints which can re-invoke this code. */
-
- static int recurse = 0;
- if (recurse > 0)
- {
- hp_cxx_exception_support_initialized = 0;
- deprecated_exception_support_initialized = 0;
- return 0;
- }
-
- hp_cxx_exception_support = 0;
-
- /* First check if we have seen any HP compiled objects; if not,
- it is very unlikely that HP's idiosyncratic callback mechanism
- for exception handling debug support will be available!
- This will percolate back up to breakpoint.c, where our callers
- will decide to try the g++ exception-handling support instead. */
- if (!deprecated_hp_som_som_object_present)
- return 0;
-
- /* We have a SOM executable with SOM debug info; find the hooks. */
-
- /* First look for the notify hook provided by aCC runtime libs */
- /* If we find this symbol, we conclude that the executable must
- have HP aCC exception support built in. If this symbol is not
- found, even though we're a HP SOM-SOM file, we may have been
- built with some other compiler (not aCC). This results percolates
- back up to our callers in breakpoint.c which can decide to
- try the g++ style of exception support instead.
- If this symbol is found but the other symbols we require are
- not found, there is something weird going on, and g++ support
- should *not* be tried as an alternative.
-
- ASSUMPTION: Only HP aCC code will have __eh_notify_hook defined.
- ASSUMPTION: HP aCC and g++ modules cannot be linked together. */
-
- /* libCsup has this hook; it'll usually be non-debuggable */
- msym = lookup_minimal_symbol (HP_ACC_EH_notify_hook, NULL, NULL);
- if (msym)
- {
- eh_notify_hook_addr = SYMBOL_VALUE_ADDRESS (msym);
- hp_cxx_exception_support = 1;
- }
- else
- {
- warning (_("\
-Unable to find exception callback hook (%s).\n\
-Executable may not have been compiled debuggable with HP aCC.\n\
-GDB will be unable to intercept exception events."),
- HP_ACC_EH_notify_hook);
- eh_notify_hook_addr = 0;
- hp_cxx_exception_support = 0;
- return 0;
- }
-
- /* Next look for the notify callback routine in end.o */
- /* This is always available in the SOM symbol dictionary if end.o is
- linked in. */
- msym = lookup_minimal_symbol (HP_ACC_EH_notify_callback, NULL, NULL);
- if (msym)
- {
- eh_notify_callback_addr = SYMBOL_VALUE_ADDRESS (msym);
- hp_cxx_exception_support = 1;
- }
- else
- {
- warning (_("\
-Unable to find exception callback routine (%s).\n\
-Suggest linking executable with -g (links in /opt/langtools/lib/end.o).\n\
-GDB will be unable to intercept exception events."),
- HP_ACC_EH_notify_callback);
- eh_notify_callback_addr = 0;
- return 0;
- }
-
- if (!gdbarch_tdep (current_gdbarch)->is_elf)
- {
- /* Check whether the executable is dynamically linked or archive bound */
- /* With an archive-bound executable we can use the raw addresses we find
- for the callback function, etc. without modification. For an executable
- with shared libraries, we have to do more work to find the plabel, which
- can be the target of a call through $$dyncall from the aCC runtime
- support library (libCsup) which is linked shared by default by aCC. */
- /* This test below was copied from somsolib.c/somread.c. It may not be a very
- reliable one to test that an executable is linked shared.
- pai/1997-07-18 */
- shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
- if (shlib_info && (bfd_section_size (symfile_objfile->obfd, shlib_info) != 0))
- {
- /* The minsym we have has the local code address, but that's not
- the plabel that can be used by an inter-load-module call. */
- /* Find solib handle for main image (which has end.o), and use
- that and the min sym as arguments to __d_shl_get() (which
- does the equivalent of shl_findsym()) to find the plabel. */
-
- args_for_find_stub args;
- static char message[] = _("Error while finding exception callback hook:\n");
-
- args.solib_handle = gdbarch_tdep (current_gdbarch)->solib_get_solib_by_pc (eh_notify_callback_addr);
- args.msym = msym;
- args.return_val = 0;
-
- recurse++;
- catch_errors (cover_find_stub_with_shl_get, &args, message,
- RETURN_MASK_ALL);
- eh_notify_callback_addr = args.return_val;
- recurse--;
-
- deprecated_exception_catchpoints_are_fragile = 1;
-
- if (!eh_notify_callback_addr)
- {
- /* We can get here either if there is no plabel in the export list
- for the main image, or if something strange happened (?) */
- warning (_("\
-Couldn't find a plabel (indirect function label) for the exception callback.\n\
-GDB will not be able to intercept exception events."));
- return 0;
- }
- }
- else
- deprecated_exception_catchpoints_are_fragile = 0;
- }
-
- /* Now, look for the breakpointable routine in end.o */
- /* This should also be available in the SOM symbol dict. if end.o linked in */
- msym = lookup_minimal_symbol (HP_ACC_EH_break, NULL, NULL);
- if (msym)
- {
- eh_break_addr = SYMBOL_VALUE_ADDRESS (msym);
- hp_cxx_exception_support = 1;
- }
- else
- {
- warning (_("\
-Unable to find exception callback routine to set breakpoint (%s).\n\
-Suggest linking executable with -g (link in /opt/langtools/lib/end.o).\n\
-GDB will be unable to intercept exception events."),
- HP_ACC_EH_break);
- eh_break_addr = 0;
- return 0;
- }
-
- /* Next look for the catch enable flag provided in end.o */
- sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
- VAR_DOMAIN, 0, (struct symtab **) NULL);
- if (sym) /* sometimes present in debug info */
- {
- eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (sym);
- hp_cxx_exception_support = 1;
- }
- else
- /* otherwise look in SOM symbol dict. */
- {
- msym = lookup_minimal_symbol (HP_ACC_EH_catch_catch, NULL, NULL);
- if (msym)
- {
- eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (msym);
- hp_cxx_exception_support = 1;
- }
- else
- {
- warning (_("\
-Unable to enable interception of exception catches.\n\
-Executable may not have been compiled debuggable with HP aCC.\n\
-Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
- return 0;
- }
- }
-
- /* Next look for the catch enable flag provided end.o */
- sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
- VAR_DOMAIN, 0, (struct symtab **) NULL);
- if (sym) /* sometimes present in debug info */
- {
- eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (sym);
- hp_cxx_exception_support = 1;
- }
- else
- /* otherwise look in SOM symbol dict. */
- {
- msym = lookup_minimal_symbol (HP_ACC_EH_catch_throw, NULL, NULL);
- if (msym)
- {
- eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (msym);
- hp_cxx_exception_support = 1;
- }
- else
- {
- warning (_("\
-Unable to enable interception of exception throws.\n\
-Executable may not have been compiled debuggable with HP aCC.\n\
-Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
- return 0;
- }
- }
-
- /* Set the flags */
- hp_cxx_exception_support = 2; /* everything worked so far */
- hp_cxx_exception_support_initialized = 1;
- deprecated_exception_support_initialized = 1;
-
- return 1;
-}
-
-/* Target operation for enabling or disabling interception of
- exception events.
- KIND is either EX_EVENT_THROW or EX_EVENT_CATCH
- ENABLE is either 0 (disable) or 1 (enable).
- Return value is NULL if no support found;
- -1 if something went wrong,
- or a pointer to a symtab/line struct if the breakpointable
- address was found. */
-
-struct symtab_and_line *
-child_enable_exception_callback (enum exception_event_kind kind, int enable)
-{
- char buf[4];
-
- if (!deprecated_exception_support_initialized
- || !hp_cxx_exception_support_initialized)
- if (!initialize_hp_cxx_exception_support ())
- return NULL;
-
- switch (hp_cxx_exception_support)
- {
- case 0:
- /* Assuming no HP support at all */
- return NULL;
- case 1:
- /* HP support should be present, but something went wrong */
- return (struct symtab_and_line *) -1; /* yuck! */
- /* there may be other cases in the future */
- }
-
- /* Set the EH hook to point to the callback routine. */
- store_unsigned_integer (buf, 4, enable ? eh_notify_callback_addr : 0); /* FIXME 32x64 problem */
- /* pai: (temp) FIXME should there be a pack operation first? */
- if (target_write_memory (eh_notify_hook_addr, buf, 4)) /* FIXME 32x64 problem */
- {
- warning (_("\
-Could not write to target memory for exception event callback.\n\
-Interception of exception events may not work."));
- return (struct symtab_and_line *) -1;
- }
- if (enable)
- {
- /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
- if (PIDGET (inferior_ptid) > 0)
- {
- if (setup_d_pid_in_inferior ())
- return (struct symtab_and_line *) -1;
- }
- else
- {
- warning (_("Internal error: Invalid inferior pid? Cannot intercept exception events."));
- return (struct symtab_and_line *) -1;
- }
- }
-
- switch (kind)
- {
- case EX_EVENT_THROW:
- store_unsigned_integer (buf, 4, enable ? 1 : 0);
- if (target_write_memory (eh_catch_throw_addr, buf, 4)) /* FIXME 32x64? */
- {
- warning (_("Couldn't enable exception throw interception."));
- return (struct symtab_and_line *) -1;
- }
- break;
- case EX_EVENT_CATCH:
- store_unsigned_integer (buf, 4, enable ? 1 : 0);
- if (target_write_memory (eh_catch_catch_addr, buf, 4)) /* FIXME 32x64? */
- {
- warning (_("Couldn't enable exception catch interception."));
- return (struct symtab_and_line *) -1;
- }
- break;
- default:
- error (_("Request to enable unknown or unsupported exception event."));
- }
-
- /* Copy break address into new sal struct, malloc'ing if needed. */
- if (!break_callback_sal)
- break_callback_sal = XMALLOC (struct symtab_and_line);
- init_sal (break_callback_sal);
- break_callback_sal->symtab = NULL;
- break_callback_sal->pc = eh_break_addr;
- break_callback_sal->line = 0;
- break_callback_sal->end = eh_break_addr;
-
- return break_callback_sal;