diff options
author | Andrew Cagney <cagney@redhat.com> | 2004-04-06 15:30:19 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2004-04-06 15:30:19 +0000 |
commit | 4c02c60cb2422af953eda5abb7aeb61771bc49a3 (patch) | |
tree | 2a6f9b8a88f01c4803a365f8649afb81919624a5 /gdb/hppa-tdep.c | |
parent | 3a515653dc9ceac100caad236d95aefd6ac2a2b4 (diff) | |
download | gdb-4c02c60cb2422af953eda5abb7aeb61771bc49a3.zip gdb-4c02c60cb2422af953eda5abb7aeb61771bc49a3.tar.gz gdb-4c02c60cb2422af953eda5abb7aeb61771bc49a3.tar.bz2 |
2004-04-06 Randolph Chung <tausq@debian.org>
Committed by Andrew Cagney (mechanical change).
* hppa-tdep.c: (args_for_find_stub, hp_som_som_object_present,
exception_catchpoints_are_fragile, find_stub_with_shl_get,
cover_find_stub_with_shl_get, initialize_hp_cxx_exception_support,
child_enable_exception_callback, current_ex_event,
null_symtab_and_line, child_get_current_exception_event,
HP_ACC_EH_notify_hook, HP_ACC_EH_set_hook_value,
HP_ACC_EH_notify_callback, HP_ACC_EH_break, HP_ACC_EH_catch_throw,
HP_ACC_EH_catch_catch, __eh_notification, hp_cxx_exception_support,
hp_cxx_exception_support_initialized, eh_notify_hook_addr,
eh_notify_callback_addr, eh_break_addr, eh_catch_catch_addr,
eh_catch_throw_addr, break_callback_sal, setup_d_pid_in_inferior):
Move hpux-specific definitions ...
* hppa-hpux-tdep.c: ... to here.
Diffstat (limited to 'gdb/hppa-tdep.c')
-rw-r--r-- | gdb/hppa-tdep.c | 568 |
1 files changed, 0 insertions, 568 deletions
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index ca6331d..798395b 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -48,12 +48,10 @@ #include <sys/types.h> #endif -#include <dl.h> #include <sys/param.h> #include <signal.h> #include <sys/ptrace.h> -#include <machine/save_state.h> #ifdef COFF_ENCAPSULATE #include "a.out.encap.h" @@ -152,24 +150,8 @@ CORE_ADDR hppa_smash_text_address (CORE_ADDR addr); CORE_ADDR hppa_target_read_pc (ptid_t ptid); void hppa_target_write_pc (CORE_ADDR v, ptid_t ptid); -typedef struct - { - struct minimal_symbol *msym; - CORE_ADDR solib_handle; - CORE_ADDR return_val; - } -args_for_find_stub; - -static int cover_find_stub_with_shl_get (void *); - static int is_pa_2 = 0; /* False */ -/* This is declared in symtab.c; set to 1 in hp-symtab-read.c */ -extern int hp_som_som_object_present; - -/* In breakpoint.c */ -extern int exception_catchpoints_are_fragile; - /* Handle 32/64-bit struct return conventions. */ static enum return_value_convention @@ -1058,102 +1040,6 @@ hppa64_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) } -/* elz: Used to lookup a symbol in the shared libraries. - This function calls shl_findsym, indirectly through a - call to __d_shl_get. __d_shl_get is in end.c, which is always - linked in by the hp compilers/linkers. - The call to shl_findsym cannot be made directly because it needs - to be active in target address space. - inputs: - minimal symbol pointer for the function we want to look up - - address in target space of the descriptor for the library - where we want to look the symbol up. - This address is retrieved using the - som_solib_get_solib_by_pc function (somsolib.c). - output: - real address in the library of the function. - note: the handle can be null, in which case shl_findsym will look for - the symbol in all the loaded shared libraries. - files to look at if you need reference on this stuff: - dld.c, dld_shl_findsym.c - end.c - man entry for shl_findsym */ - -CORE_ADDR -find_stub_with_shl_get (struct minimal_symbol *function, CORE_ADDR handle) -{ - struct symbol *get_sym, *symbol2; - struct minimal_symbol *buff_minsym, *msymbol; - struct type *ftype; - struct value **args; - struct value *funcval; - struct value *val; - - int x, namelen, err_value, tmp = -1; - CORE_ADDR endo_buff_addr, value_return_addr, errno_return_addr; - CORE_ADDR stub_addr; - - - args = alloca (sizeof (struct value *) * 8); /* 6 for the arguments and one null one??? */ - funcval = find_function_in_inferior ("__d_shl_get"); - get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_DOMAIN, NULL, NULL); - buff_minsym = lookup_minimal_symbol ("__buffer", NULL, NULL); - msymbol = lookup_minimal_symbol ("__shldp", NULL, NULL); - symbol2 = lookup_symbol ("__shldp", NULL, VAR_DOMAIN, NULL, NULL); - endo_buff_addr = SYMBOL_VALUE_ADDRESS (buff_minsym); - namelen = strlen (DEPRECATED_SYMBOL_NAME (function)); - value_return_addr = endo_buff_addr + namelen; - ftype = check_typedef (SYMBOL_TYPE (get_sym)); - - /* do alignment */ - if ((x = value_return_addr % 64) != 0) - value_return_addr = value_return_addr + 64 - x; - - errno_return_addr = value_return_addr + 64; - - - /* set up stuff needed by __d_shl_get in buffer in end.o */ - - target_write_memory (endo_buff_addr, DEPRECATED_SYMBOL_NAME (function), namelen); - - target_write_memory (value_return_addr, (char *) &tmp, 4); - - target_write_memory (errno_return_addr, (char *) &tmp, 4); - - target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol), - (char *) &handle, 4); - - /* now prepare the arguments for the call */ - - args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12); - args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol)); - args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr); - args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE); - args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr); - args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr); - - /* 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; -} - /* Get the PC from %r31 if currently in a syscall. Also mask out privilege bits. */ @@ -2494,460 +2380,6 @@ hppa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) return frame_unwind_register_signed (next_frame, PCOQ_HEAD_REGNUM) & ~3; } -/* Exception handling support for the HP-UX ANSI C++ compiler. - The compiler (aCC) provides a callback for exception events; - GDB can set a breakpoint on this callback and find out what - exception event has occurred. */ - -/* The name of the hook to be set to point to the callback function */ -static char HP_ACC_EH_notify_hook[] = "__eh_notify_hook"; -/* The name of the function to be used to set the hook value */ -static char HP_ACC_EH_set_hook_value[] = "__eh_set_hook_value"; -/* The name of the callback function in end.o */ -static char HP_ACC_EH_notify_callback[] = "__d_eh_notify_callback"; -/* Name of function in end.o on which a break is set (called by above) */ -static char HP_ACC_EH_break[] = "__d_eh_break"; -/* Name of flag (in end.o) that enables catching throws */ -static char HP_ACC_EH_catch_throw[] = "__d_eh_catch_throw"; -/* Name of flag (in end.o) that enables catching catching */ -static char HP_ACC_EH_catch_catch[] = "__d_eh_catch_catch"; -/* The enum used by aCC */ -typedef enum - { - __EH_NOTIFY_THROW, - __EH_NOTIFY_CATCH - } -__eh_notification; - -/* Is exception-handling support available with this executable? */ -static int hp_cxx_exception_support = 0; -/* Has the initialize function been run? */ -int hp_cxx_exception_support_initialized = 0; -/* Similar to above, but imported from breakpoint.c -- non-target-specific */ -extern int exception_support_initialized; -/* Address of __eh_notify_hook */ -static CORE_ADDR eh_notify_hook_addr = 0; -/* Address of __d_eh_notify_callback */ -static CORE_ADDR eh_notify_callback_addr = 0; -/* Address of __d_eh_break */ -static CORE_ADDR eh_break_addr = 0; -/* Address of __d_eh_catch_catch */ -static CORE_ADDR eh_catch_catch_addr = 0; -/* Address of __d_eh_catch_throw */ -static CORE_ADDR eh_catch_throw_addr = 0; -/* Sal for __d_eh_break */ -static struct symtab_and_line *break_callback_sal = 0; - -/* Code in end.c expects __d_pid to be set in the inferior, - otherwise __d_eh_notify_callback doesn't bother to call - __d_eh_break! So we poke the pid into this symbol - ourselves. - 0 => success - 1 => failure */ -int -setup_d_pid_in_inferior (void) -{ - CORE_ADDR anaddr; - struct minimal_symbol *msymbol; - char buf[4]; /* FIXME 32x64? */ - - /* Slam the pid of the process into __d_pid; failing is only a warning! */ - msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile); - if (msymbol == NULL) - { - warning ("Unable to find __d_pid symbol in object file."); - warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o)."); - return 1; - } - - anaddr = SYMBOL_VALUE_ADDRESS (msymbol); - store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); /* FIXME 32x64? */ - if (target_write_memory (anaddr, buf, 4)) /* FIXME 32x64? */ - { - warning ("Unable to write __d_pid"); - warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o)."); - return 1; - } - 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; - 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 (!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).", HP_ACC_EH_notify_hook); - warning ("Executable may not have been compiled debuggable with HP aCC."); - warning ("GDB will be unable to intercept exception events."); - 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).", HP_ACC_EH_notify_callback); - warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o)."); - warning ("GDB will be unable to intercept exception events."); - eh_notify_callback_addr = 0; - return 0; - } - -#ifndef GDB_TARGET_IS_HPPA_20W - /* 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 = som_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--; - - 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."); - warning ("GDB will not be able to intercept exception events."); - return 0; - } - } - else - exception_catchpoints_are_fragile = 0; -#endif - - /* 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).", HP_ACC_EH_break); - warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."); - warning ("GDB will be unable to intercept exception events."); - 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."); - warning ("Executable may not have been compiled debuggable with HP aCC."); - warning ("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."); - warning ("Executable may not have been compiled debuggable with HP aCC."); - warning ("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; - 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 (!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."); - warning ("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 = (struct symtab_and_line *) xmalloc (sizeof (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; -} - -/* Record some information about the current exception event */ -static struct exception_event_record current_ex_event; -/* Convenience struct */ -static struct symtab_and_line null_symtab_and_line = -{NULL, 0, 0, 0}; - -/* Report current exception event. Returns a pointer to a record - that describes the kind of the event, where it was thrown from, - and where it will be caught. More information may be reported - in the future */ -struct exception_event_record * -child_get_current_exception_event (void) -{ - CORE_ADDR event_kind; - CORE_ADDR throw_addr; - CORE_ADDR catch_addr; - struct frame_info *fi, *curr_frame; - int level = 1; - - curr_frame = get_current_frame (); - if (!curr_frame) - return (struct exception_event_record *) NULL; - - /* Go up one frame to __d_eh_notify_callback, because at the - point when this code is executed, there's garbage in the - arguments of __d_eh_break. */ - fi = find_relative_frame (curr_frame, &level); - if (level != 0) - return (struct exception_event_record *) NULL; - - select_frame (fi); - - /* Read in the arguments */ - /* __d_eh_notify_callback() is called with 3 arguments: - 1. event kind catch or throw - 2. the target address if known - 3. a flag -- not sure what this is. pai/1997-07-17 */ - event_kind = read_register (ARG0_REGNUM); - catch_addr = read_register (ARG1_REGNUM); - - /* Now go down to a user frame */ - /* For a throw, __d_eh_break is called by - __d_eh_notify_callback which is called by - __notify_throw which is called - from user code. - For a catch, __d_eh_break is called by - __d_eh_notify_callback which is called by - <stackwalking stuff> which is called by - __throw__<stuff> or __rethrow_<stuff> which is called - from user code. */ - /* FIXME: Don't use such magic numbers; search for the frames */ - level = (event_kind == EX_EVENT_THROW) ? 3 : 4; - fi = find_relative_frame (curr_frame, &level); - if (level != 0) - return (struct exception_event_record *) NULL; - - select_frame (fi); - throw_addr = get_frame_pc (fi); - - /* Go back to original (top) frame */ - select_frame (curr_frame); - - current_ex_event.kind = (enum exception_event_kind) event_kind; - current_ex_event.throw_sal = find_pc_line (throw_addr, 1); - current_ex_event.catch_sal = find_pc_line (catch_addr, 1); - - return ¤t_ex_event; -} - /* Instead of this nasty cast, add a method pvoid() that prints out a host VOID data type (remember %p isn't portable). */ |