1 /* Target-dependent code for HPUX running on PA-RISC, for GDB.
3 Copyright 2002, 2003 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 #include "arch-utils.h"
25 #include "gdb_string.h"
27 #include "frame-unwind.h"
28 #include "trad-frame.h"
33 #include "hppa-tdep.h"
36 #include <machine/save_state.h>
39 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
42 /* Forward declarations. */
43 extern void _initialize_hppa_hpux_tdep (void);
44 extern initialize_file_ftype _initialize_hppa_hpux_tdep
;
48 struct minimal_symbol
*msym
;
49 CORE_ADDR solib_handle
;
54 /* Return one if PC is in the call path of a trampoline, else return zero.
56 Note we return one for *any* call trampoline (long-call, arg-reloc), not
57 just shared library trampolines (import, export). */
60 hppa32_hpux_in_solib_call_trampoline (CORE_ADDR pc
, char *name
)
62 struct minimal_symbol
*minsym
;
63 struct unwind_table_entry
*u
;
64 static CORE_ADDR dyncall
= 0;
65 static CORE_ADDR sr4export
= 0;
67 /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
70 /* First see if PC is in one of the two C-library trampolines. */
73 minsym
= lookup_minimal_symbol ("$$dyncall", NULL
, NULL
);
75 dyncall
= SYMBOL_VALUE_ADDRESS (minsym
);
82 minsym
= lookup_minimal_symbol ("_sr4export", NULL
, NULL
);
84 sr4export
= SYMBOL_VALUE_ADDRESS (minsym
);
89 if (pc
== dyncall
|| pc
== sr4export
)
92 minsym
= lookup_minimal_symbol_by_pc (pc
);
93 if (minsym
&& strcmp (DEPRECATED_SYMBOL_NAME (minsym
), ".stub") == 0)
96 /* Get the unwind descriptor corresponding to PC, return zero
97 if no unwind was found. */
98 u
= find_unwind_entry (pc
);
102 /* If this isn't a linker stub, then return now. */
103 if (u
->stub_unwind
.stub_type
== 0)
106 /* By definition a long-branch stub is a call stub. */
107 if (u
->stub_unwind
.stub_type
== LONG_BRANCH
)
110 /* The call and return path execute the same instructions within
111 an IMPORT stub! So an IMPORT stub is both a call and return
113 if (u
->stub_unwind
.stub_type
== IMPORT
)
116 /* Parameter relocation stubs always have a call path and may have a
118 if (u
->stub_unwind
.stub_type
== PARAMETER_RELOCATION
119 || u
->stub_unwind
.stub_type
== EXPORT
)
123 /* Search forward from the current PC until we hit a branch
124 or the end of the stub. */
125 for (addr
= pc
; addr
<= u
->region_end
; addr
+= 4)
129 insn
= read_memory_integer (addr
, 4);
131 /* Does it look like a bl? If so then it's the call path, if
132 we find a bv or be first, then we're on the return path. */
133 if ((insn
& 0xfc00e000) == 0xe8000000)
135 else if ((insn
& 0xfc00e001) == 0xe800c000
136 || (insn
& 0xfc000000) == 0xe0000000)
140 /* Should never happen. */
141 warning ("Unable to find branch in parameter relocation stub.\n");
145 /* Unknown stub type. For now, just return zero. */
150 hppa64_hpux_in_solib_call_trampoline (CORE_ADDR pc
, char *name
)
152 /* PA64 has a completely different stub/trampoline scheme. Is it
153 better? Maybe. It's certainly harder to determine with any
154 certainty that we are in a stub because we can not refer to the
157 The heuristic is simple. Try to lookup the current PC value in th
158 minimal symbol table. If that fails, then assume we are not in a
161 Then see if the PC value falls within the section bounds for the
162 section containing the minimal symbol we found in the first
163 step. If it does, then assume we are not in a stub and return.
165 Finally peek at the instructions to see if they look like a stub. */
166 struct minimal_symbol
*minsym
;
171 minsym
= lookup_minimal_symbol_by_pc (pc
);
175 sec
= SYMBOL_BFD_SECTION (minsym
);
177 if (bfd_get_section_vma (sec
->owner
, sec
) <= pc
178 && pc
< (bfd_get_section_vma (sec
->owner
, sec
)
179 + bfd_section_size (sec
->owner
, sec
)))
182 /* We might be in a stub. Peek at the instructions. Stubs are 3
183 instructions long. */
184 insn
= read_memory_integer (pc
, 4);
186 /* Find out where we think we are within the stub. */
187 if ((insn
& 0xffffc00e) == 0x53610000)
189 else if ((insn
& 0xffffffff) == 0xe820d000)
191 else if ((insn
& 0xffffc00e) == 0x537b0000)
196 /* Now verify each insn in the range looks like a stub instruction. */
197 insn
= read_memory_integer (addr
, 4);
198 if ((insn
& 0xffffc00e) != 0x53610000)
201 /* Now verify each insn in the range looks like a stub instruction. */
202 insn
= read_memory_integer (addr
+ 4, 4);
203 if ((insn
& 0xffffffff) != 0xe820d000)
206 /* Now verify each insn in the range looks like a stub instruction. */
207 insn
= read_memory_integer (addr
+ 8, 4);
208 if ((insn
& 0xffffc00e) != 0x537b0000)
211 /* Looks like a stub. */
215 /* Return one if PC is in the return path of a trampoline, else return zero.
217 Note we return one for *any* call trampoline (long-call, arg-reloc), not
218 just shared library trampolines (import, export). */
221 hppa_hpux_in_solib_return_trampoline (CORE_ADDR pc
, char *name
)
223 struct unwind_table_entry
*u
;
225 /* Get the unwind descriptor corresponding to PC, return zero
226 if no unwind was found. */
227 u
= find_unwind_entry (pc
);
231 /* If this isn't a linker stub or it's just a long branch stub, then
233 if (u
->stub_unwind
.stub_type
== 0 || u
->stub_unwind
.stub_type
== LONG_BRANCH
)
236 /* The call and return path execute the same instructions within
237 an IMPORT stub! So an IMPORT stub is both a call and return
239 if (u
->stub_unwind
.stub_type
== IMPORT
)
242 /* Parameter relocation stubs always have a call path and may have a
244 if (u
->stub_unwind
.stub_type
== PARAMETER_RELOCATION
245 || u
->stub_unwind
.stub_type
== EXPORT
)
249 /* Search forward from the current PC until we hit a branch
250 or the end of the stub. */
251 for (addr
= pc
; addr
<= u
->region_end
; addr
+= 4)
255 insn
= read_memory_integer (addr
, 4);
257 /* Does it look like a bl? If so then it's the call path, if
258 we find a bv or be first, then we're on the return path. */
259 if ((insn
& 0xfc00e000) == 0xe8000000)
261 else if ((insn
& 0xfc00e001) == 0xe800c000
262 || (insn
& 0xfc000000) == 0xe0000000)
266 /* Should never happen. */
267 warning ("Unable to find branch in parameter relocation stub.\n");
271 /* Unknown stub type. For now, just return zero. */
276 /* Figure out if PC is in a trampoline, and if so find out where
277 the trampoline will jump to. If not in a trampoline, return zero.
279 Simple code examination probably is not a good idea since the code
280 sequences in trampolines can also appear in user code.
282 We use unwinds and information from the minimal symbol table to
283 determine when we're in a trampoline. This won't work for ELF
284 (yet) since it doesn't create stub unwind entries. Whether or
285 not ELF will create stub unwinds or normal unwinds for linker
286 stubs is still being debated.
288 This should handle simple calls through dyncall or sr4export,
289 long calls, argument relocation stubs, and dyncall/sr4export
290 calling an argument relocation stub. It even handles some stubs
291 used in dynamic executables. */
294 hppa_hpux_skip_trampoline_code (CORE_ADDR pc
)
297 long prev_inst
, curr_inst
, loc
;
298 static CORE_ADDR dyncall
= 0;
299 static CORE_ADDR dyncall_external
= 0;
300 static CORE_ADDR sr4export
= 0;
301 struct minimal_symbol
*msym
;
302 struct unwind_table_entry
*u
;
304 /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
309 msym
= lookup_minimal_symbol ("$$dyncall", NULL
, NULL
);
311 dyncall
= SYMBOL_VALUE_ADDRESS (msym
);
316 if (!dyncall_external
)
318 msym
= lookup_minimal_symbol ("$$dyncall_external", NULL
, NULL
);
320 dyncall_external
= SYMBOL_VALUE_ADDRESS (msym
);
322 dyncall_external
= -1;
327 msym
= lookup_minimal_symbol ("_sr4export", NULL
, NULL
);
329 sr4export
= SYMBOL_VALUE_ADDRESS (msym
);
334 /* Addresses passed to dyncall may *NOT* be the actual address
335 of the function. So we may have to do something special. */
338 pc
= (CORE_ADDR
) read_register (22);
340 /* If bit 30 (counting from the left) is on, then pc is the address of
341 the PLT entry for this function, not the address of the function
342 itself. Bit 31 has meaning too, but only for MPE. */
344 pc
= (CORE_ADDR
) read_memory_integer (pc
& ~0x3, TARGET_PTR_BIT
/ 8);
346 if (pc
== dyncall_external
)
348 pc
= (CORE_ADDR
) read_register (22);
349 pc
= (CORE_ADDR
) read_memory_integer (pc
& ~0x3, TARGET_PTR_BIT
/ 8);
351 else if (pc
== sr4export
)
352 pc
= (CORE_ADDR
) (read_register (22));
354 /* Get the unwind descriptor corresponding to PC, return zero
355 if no unwind was found. */
356 u
= find_unwind_entry (pc
);
360 /* If this isn't a linker stub, then return now. */
361 /* elz: attention here! (FIXME) because of a compiler/linker
362 error, some stubs which should have a non zero stub_unwind.stub_type
363 have unfortunately a value of zero. So this function would return here
364 as if we were not in a trampoline. To fix this, we go look at the partial
365 symbol information, which reports this guy as a stub.
366 (FIXME): Unfortunately, we are not that lucky: it turns out that the
367 partial symbol information is also wrong sometimes. This is because
368 when it is entered (somread.c::som_symtab_read()) it can happen that
369 if the type of the symbol (from the som) is Entry, and the symbol is
370 in a shared library, then it can also be a trampoline. This would
371 be OK, except that I believe the way they decide if we are ina shared library
372 does not work. SOOOO..., even if we have a regular function w/o trampolines
373 its minimal symbol can be assigned type mst_solib_trampoline.
374 Also, if we find that the symbol is a real stub, then we fix the unwind
375 descriptor, and define the stub type to be EXPORT.
376 Hopefully this is correct most of the times. */
377 if (u
->stub_unwind
.stub_type
== 0)
380 /* elz: NOTE (FIXME!) once the problem with the unwind information is fixed
381 we can delete all the code which appears between the lines */
382 /*--------------------------------------------------------------------------*/
383 msym
= lookup_minimal_symbol_by_pc (pc
);
385 if (msym
== NULL
|| MSYMBOL_TYPE (msym
) != mst_solib_trampoline
)
386 return orig_pc
== pc
? 0 : pc
& ~0x3;
388 else if (msym
!= NULL
&& MSYMBOL_TYPE (msym
) == mst_solib_trampoline
)
390 struct objfile
*objfile
;
391 struct minimal_symbol
*msymbol
;
392 int function_found
= 0;
394 /* go look if there is another minimal symbol with the same name as
395 this one, but with type mst_text. This would happen if the msym
396 is an actual trampoline, in which case there would be another
397 symbol with the same name corresponding to the real function */
399 ALL_MSYMBOLS (objfile
, msymbol
)
401 if (MSYMBOL_TYPE (msymbol
) == mst_text
402 && DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (msymbol
), DEPRECATED_SYMBOL_NAME (msym
)))
410 /* the type of msym is correct (mst_solib_trampoline), but
411 the unwind info is wrong, so set it to the correct value */
412 u
->stub_unwind
.stub_type
= EXPORT
;
414 /* the stub type info in the unwind is correct (this is not a
415 trampoline), but the msym type information is wrong, it
416 should be mst_text. So we need to fix the msym, and also
417 get out of this function */
419 MSYMBOL_TYPE (msym
) = mst_text
;
420 return orig_pc
== pc
? 0 : pc
& ~0x3;
424 /*--------------------------------------------------------------------------*/
427 /* It's a stub. Search for a branch and figure out where it goes.
428 Note we have to handle multi insn branch sequences like ldil;ble.
429 Most (all?) other branches can be determined by examining the contents
430 of certain registers and the stack. */
437 /* Make sure we haven't walked outside the range of this stub. */
438 if (u
!= find_unwind_entry (loc
))
440 warning ("Unable to find branch in linker stub");
441 return orig_pc
== pc
? 0 : pc
& ~0x3;
444 prev_inst
= curr_inst
;
445 curr_inst
= read_memory_integer (loc
, 4);
447 /* Does it look like a branch external using %r1? Then it's the
448 branch from the stub to the actual function. */
449 if ((curr_inst
& 0xffe0e000) == 0xe0202000)
451 /* Yup. See if the previous instruction loaded
452 a value into %r1. If so compute and return the jump address. */
453 if ((prev_inst
& 0xffe00000) == 0x20200000)
454 return (hppa_extract_21 (prev_inst
) + hppa_extract_17 (curr_inst
)) & ~0x3;
457 warning ("Unable to find ldil X,%%r1 before ble Y(%%sr4,%%r1).");
458 return orig_pc
== pc
? 0 : pc
& ~0x3;
462 /* Does it look like a be 0(sr0,%r21)? OR
463 Does it look like a be, n 0(sr0,%r21)? OR
464 Does it look like a bve (r21)? (this is on PA2.0)
465 Does it look like a bve, n(r21)? (this is also on PA2.0)
466 That's the branch from an
467 import stub to an export stub.
469 It is impossible to determine the target of the branch via
470 simple examination of instructions and/or data (consider
471 that the address in the plabel may be the address of the
472 bind-on-reference routine in the dynamic loader).
474 So we have try an alternative approach.
476 Get the name of the symbol at our current location; it should
477 be a stub symbol with the same name as the symbol in the
480 Then lookup a minimal symbol with the same name; we should
481 get the minimal symbol for the target routine in the shared
482 library as those take precedence of import/export stubs. */
483 if ((curr_inst
== 0xe2a00000) ||
484 (curr_inst
== 0xe2a00002) ||
485 (curr_inst
== 0xeaa0d000) ||
486 (curr_inst
== 0xeaa0d002))
488 struct minimal_symbol
*stubsym
, *libsym
;
490 stubsym
= lookup_minimal_symbol_by_pc (loc
);
493 warning ("Unable to find symbol for 0x%lx", loc
);
494 return orig_pc
== pc
? 0 : pc
& ~0x3;
497 libsym
= lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (stubsym
), NULL
, NULL
);
500 warning ("Unable to find library symbol for %s\n",
501 DEPRECATED_SYMBOL_NAME (stubsym
));
502 return orig_pc
== pc
? 0 : pc
& ~0x3;
505 return SYMBOL_VALUE (libsym
);
508 /* Does it look like bl X,%rp or bl X,%r0? Another way to do a
509 branch from the stub to the actual function. */
511 else if ((curr_inst
& 0xffe0e000) == 0xe8400000
512 || (curr_inst
& 0xffe0e000) == 0xe8000000
513 || (curr_inst
& 0xffe0e000) == 0xe800A000)
514 return (loc
+ hppa_extract_17 (curr_inst
) + 8) & ~0x3;
516 /* Does it look like bv (rp)? Note this depends on the
517 current stack pointer being the same as the stack
518 pointer in the stub itself! This is a branch on from the
519 stub back to the original caller. */
520 /*else if ((curr_inst & 0xffe0e000) == 0xe840c000) */
521 else if ((curr_inst
& 0xffe0f000) == 0xe840c000)
523 /* Yup. See if the previous instruction loaded
525 if (prev_inst
== 0x4bc23ff1)
526 return (read_memory_integer
527 (read_register (HPPA_SP_REGNUM
) - 8, 4)) & ~0x3;
530 warning ("Unable to find restore of %%rp before bv (%%rp).");
531 return orig_pc
== pc
? 0 : pc
& ~0x3;
535 /* elz: added this case to capture the new instruction
536 at the end of the return part of an export stub used by
537 the PA2.0: BVE, n (rp) */
538 else if ((curr_inst
& 0xffe0f000) == 0xe840d000)
540 return (read_memory_integer
541 (read_register (HPPA_SP_REGNUM
) - 24, TARGET_PTR_BIT
/ 8)) & ~0x3;
544 /* What about be,n 0(sr0,%rp)? It's just another way we return to
545 the original caller from the stub. Used in dynamic executables. */
546 else if (curr_inst
== 0xe0400002)
548 /* The value we jump to is sitting in sp - 24. But that's
549 loaded several instructions before the be instruction.
550 I guess we could check for the previous instruction being
551 mtsp %r1,%sr0 if we want to do sanity checking. */
552 return (read_memory_integer
553 (read_register (HPPA_SP_REGNUM
) - 24, TARGET_PTR_BIT
/ 8)) & ~0x3;
556 /* Haven't found the branch yet, but we're still in the stub.
563 /* Exception handling support for the HP-UX ANSI C++ compiler.
564 The compiler (aCC) provides a callback for exception events;
565 GDB can set a breakpoint on this callback and find out what
566 exception event has occurred. */
568 /* The name of the hook to be set to point to the callback function */
569 static char HP_ACC_EH_notify_hook
[] = "__eh_notify_hook";
570 /* The name of the function to be used to set the hook value */
571 static char HP_ACC_EH_set_hook_value
[] = "__eh_set_hook_value";
572 /* The name of the callback function in end.o */
573 static char HP_ACC_EH_notify_callback
[] = "__d_eh_notify_callback";
574 /* Name of function in end.o on which a break is set (called by above) */
575 static char HP_ACC_EH_break
[] = "__d_eh_break";
576 /* Name of flag (in end.o) that enables catching throws */
577 static char HP_ACC_EH_catch_throw
[] = "__d_eh_catch_throw";
578 /* Name of flag (in end.o) that enables catching catching */
579 static char HP_ACC_EH_catch_catch
[] = "__d_eh_catch_catch";
580 /* The enum used by aCC */
588 /* Is exception-handling support available with this executable? */
589 static int hp_cxx_exception_support
= 0;
590 /* Has the initialize function been run? */
591 int hp_cxx_exception_support_initialized
= 0;
592 /* Address of __eh_notify_hook */
593 static CORE_ADDR eh_notify_hook_addr
= 0;
594 /* Address of __d_eh_notify_callback */
595 static CORE_ADDR eh_notify_callback_addr
= 0;
596 /* Address of __d_eh_break */
597 static CORE_ADDR eh_break_addr
= 0;
598 /* Address of __d_eh_catch_catch */
599 static CORE_ADDR eh_catch_catch_addr
= 0;
600 /* Address of __d_eh_catch_throw */
601 static CORE_ADDR eh_catch_throw_addr
= 0;
602 /* Sal for __d_eh_break */
603 static struct symtab_and_line
*break_callback_sal
= 0;
605 /* Code in end.c expects __d_pid to be set in the inferior,
606 otherwise __d_eh_notify_callback doesn't bother to call
607 __d_eh_break! So we poke the pid into this symbol
612 setup_d_pid_in_inferior (void)
615 struct minimal_symbol
*msymbol
;
616 char buf
[4]; /* FIXME 32x64? */
618 /* Slam the pid of the process into __d_pid; failing is only a warning! */
619 msymbol
= lookup_minimal_symbol ("__d_pid", NULL
, symfile_objfile
);
622 warning ("Unable to find __d_pid symbol in object file.");
623 warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
627 anaddr
= SYMBOL_VALUE_ADDRESS (msymbol
);
628 store_unsigned_integer (buf
, 4, PIDGET (inferior_ptid
)); /* FIXME 32x64? */
629 if (target_write_memory (anaddr
, buf
, 4)) /* FIXME 32x64? */
631 warning ("Unable to write __d_pid");
632 warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
638 /* elz: Used to lookup a symbol in the shared libraries.
639 This function calls shl_findsym, indirectly through a
640 call to __d_shl_get. __d_shl_get is in end.c, which is always
641 linked in by the hp compilers/linkers.
642 The call to shl_findsym cannot be made directly because it needs
643 to be active in target address space.
644 inputs: - minimal symbol pointer for the function we want to look up
645 - address in target space of the descriptor for the library
646 where we want to look the symbol up.
647 This address is retrieved using the
648 som_solib_get_solib_by_pc function (somsolib.c).
649 output: - real address in the library of the function.
650 note: the handle can be null, in which case shl_findsym will look for
651 the symbol in all the loaded shared libraries.
652 files to look at if you need reference on this stuff:
653 dld.c, dld_shl_findsym.c
655 man entry for shl_findsym */
658 find_stub_with_shl_get (struct minimal_symbol
*function
, CORE_ADDR handle
)
660 struct symbol
*get_sym
, *symbol2
;
661 struct minimal_symbol
*buff_minsym
, *msymbol
;
664 struct value
*funcval
;
667 int x
, namelen
, err_value
, tmp
= -1;
668 CORE_ADDR endo_buff_addr
, value_return_addr
, errno_return_addr
;
672 args
= alloca (sizeof (struct value
*) * 8); /* 6 for the arguments and one null one??? */
673 funcval
= find_function_in_inferior ("__d_shl_get");
674 get_sym
= lookup_symbol ("__d_shl_get", NULL
, VAR_DOMAIN
, NULL
, NULL
);
675 buff_minsym
= lookup_minimal_symbol ("__buffer", NULL
, NULL
);
676 msymbol
= lookup_minimal_symbol ("__shldp", NULL
, NULL
);
677 symbol2
= lookup_symbol ("__shldp", NULL
, VAR_DOMAIN
, NULL
, NULL
);
678 endo_buff_addr
= SYMBOL_VALUE_ADDRESS (buff_minsym
);
679 namelen
= strlen (DEPRECATED_SYMBOL_NAME (function
));
680 value_return_addr
= endo_buff_addr
+ namelen
;
681 ftype
= check_typedef (SYMBOL_TYPE (get_sym
));
684 if ((x
= value_return_addr
% 64) != 0)
685 value_return_addr
= value_return_addr
+ 64 - x
;
687 errno_return_addr
= value_return_addr
+ 64;
690 /* set up stuff needed by __d_shl_get in buffer in end.o */
692 target_write_memory (endo_buff_addr
, DEPRECATED_SYMBOL_NAME (function
), namelen
);
694 target_write_memory (value_return_addr
, (char *) &tmp
, 4);
696 target_write_memory (errno_return_addr
, (char *) &tmp
, 4);
698 target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol
),
699 (char *) &handle
, 4);
701 /* now prepare the arguments for the call */
703 args
[0] = value_from_longest (TYPE_FIELD_TYPE (ftype
, 0), 12);
704 args
[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype
, 1), SYMBOL_VALUE_ADDRESS (msymbol
));
705 args
[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype
, 2), endo_buff_addr
);
706 args
[3] = value_from_longest (TYPE_FIELD_TYPE (ftype
, 3), TYPE_PROCEDURE
);
707 args
[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype
, 4), value_return_addr
);
708 args
[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype
, 5), errno_return_addr
);
710 /* now call the function */
712 val
= call_function_by_hand (funcval
, 6, args
);
714 /* now get the results */
716 target_read_memory (errno_return_addr
, (char *) &err_value
, sizeof (err_value
));
718 target_read_memory (value_return_addr
, (char *) &stub_addr
, sizeof (stub_addr
));
720 error ("call to __d_shl_get failed, error code is %d", err_value
);
725 /* Cover routine for find_stub_with_shl_get to pass to catch_errors */
727 cover_find_stub_with_shl_get (void *args_untyped
)
729 args_for_find_stub
*args
= args_untyped
;
730 args
->return_val
= find_stub_with_shl_get (args
->msym
, args
->solib_handle
);
734 /* Initialize exception catchpoint support by looking for the
735 necessary hooks/callbacks in end.o, etc., and set the hook value to
736 point to the required debug function
742 initialize_hp_cxx_exception_support (void)
744 struct symtabs_and_lines sals
;
745 struct cleanup
*old_chain
;
746 struct cleanup
*canonical_strings_chain
= NULL
;
749 char *addr_end
= NULL
;
750 char **canonical
= (char **) NULL
;
752 struct symbol
*sym
= NULL
;
753 struct minimal_symbol
*msym
= NULL
;
754 struct objfile
*objfile
;
755 asection
*shlib_info
;
757 /* Detect and disallow recursion. On HP-UX with aCC, infinite
758 recursion is a possibility because finding the hook for exception
759 callbacks involves making a call in the inferior, which means
760 re-inserting breakpoints which can re-invoke this code */
762 static int recurse
= 0;
765 hp_cxx_exception_support_initialized
= 0;
766 deprecated_exception_support_initialized
= 0;
770 hp_cxx_exception_support
= 0;
772 /* First check if we have seen any HP compiled objects; if not,
773 it is very unlikely that HP's idiosyncratic callback mechanism
774 for exception handling debug support will be available!
775 This will percolate back up to breakpoint.c, where our callers
776 will decide to try the g++ exception-handling support instead. */
777 if (!deprecated_hp_som_som_object_present
)
780 /* We have a SOM executable with SOM debug info; find the hooks */
782 /* First look for the notify hook provided by aCC runtime libs */
783 /* If we find this symbol, we conclude that the executable must
784 have HP aCC exception support built in. If this symbol is not
785 found, even though we're a HP SOM-SOM file, we may have been
786 built with some other compiler (not aCC). This results percolates
787 back up to our callers in breakpoint.c which can decide to
788 try the g++ style of exception support instead.
789 If this symbol is found but the other symbols we require are
790 not found, there is something weird going on, and g++ support
791 should *not* be tried as an alternative.
793 ASSUMPTION: Only HP aCC code will have __eh_notify_hook defined.
794 ASSUMPTION: HP aCC and g++ modules cannot be linked together. */
796 /* libCsup has this hook; it'll usually be non-debuggable */
797 msym
= lookup_minimal_symbol (HP_ACC_EH_notify_hook
, NULL
, NULL
);
800 eh_notify_hook_addr
= SYMBOL_VALUE_ADDRESS (msym
);
801 hp_cxx_exception_support
= 1;
805 warning ("Unable to find exception callback hook (%s).", HP_ACC_EH_notify_hook
);
806 warning ("Executable may not have been compiled debuggable with HP aCC.");
807 warning ("GDB will be unable to intercept exception events.");
808 eh_notify_hook_addr
= 0;
809 hp_cxx_exception_support
= 0;
813 /* Next look for the notify callback routine in end.o */
814 /* This is always available in the SOM symbol dictionary if end.o is linked in */
815 msym
= lookup_minimal_symbol (HP_ACC_EH_notify_callback
, NULL
, NULL
);
818 eh_notify_callback_addr
= SYMBOL_VALUE_ADDRESS (msym
);
819 hp_cxx_exception_support
= 1;
823 warning ("Unable to find exception callback routine (%s).", HP_ACC_EH_notify_callback
);
824 warning ("Suggest linking executable with -g (links in /opt/langtools/lib/end.o).");
825 warning ("GDB will be unable to intercept exception events.");
826 eh_notify_callback_addr
= 0;
830 #ifndef GDB_TARGET_IS_HPPA_20W
831 /* Check whether the executable is dynamically linked or archive bound */
832 /* With an archive-bound executable we can use the raw addresses we find
833 for the callback function, etc. without modification. For an executable
834 with shared libraries, we have to do more work to find the plabel, which
835 can be the target of a call through $$dyncall from the aCC runtime support
836 library (libCsup) which is linked shared by default by aCC. */
837 /* This test below was copied from somsolib.c/somread.c. It may not be a very
838 reliable one to test that an executable is linked shared. pai/1997-07-18 */
839 shlib_info
= bfd_get_section_by_name (symfile_objfile
->obfd
, "$SHLIB_INFO$");
840 if (shlib_info
&& (bfd_section_size (symfile_objfile
->obfd
, shlib_info
) != 0))
842 /* The minsym we have has the local code address, but that's not the
843 plabel that can be used by an inter-load-module call. */
844 /* Find solib handle for main image (which has end.o), and use that
845 and the min sym as arguments to __d_shl_get() (which does the equivalent
846 of shl_findsym()) to find the plabel. */
848 args_for_find_stub args
;
849 static char message
[] = "Error while finding exception callback hook:\n";
851 args
.solib_handle
= som_solib_get_solib_by_pc (eh_notify_callback_addr
);
856 catch_errors (cover_find_stub_with_shl_get
, &args
, message
,
858 eh_notify_callback_addr
= args
.return_val
;
861 deprecated_exception_catchpoints_are_fragile
= 1;
863 if (!eh_notify_callback_addr
)
865 /* We can get here either if there is no plabel in the export list
866 for the main image, or if something strange happened (?) */
867 warning ("Couldn't find a plabel (indirect function label) for the exception callback.");
868 warning ("GDB will not be able to intercept exception events.");
873 deprecated_exception_catchpoints_are_fragile
= 0;
876 /* Now, look for the breakpointable routine in end.o */
877 /* This should also be available in the SOM symbol dict. if end.o linked in */
878 msym
= lookup_minimal_symbol (HP_ACC_EH_break
, NULL
, NULL
);
881 eh_break_addr
= SYMBOL_VALUE_ADDRESS (msym
);
882 hp_cxx_exception_support
= 1;
886 warning ("Unable to find exception callback routine to set breakpoint (%s).", HP_ACC_EH_break
);
887 warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
888 warning ("GDB will be unable to intercept exception events.");
893 /* Next look for the catch enable flag provided in end.o */
894 sym
= lookup_symbol (HP_ACC_EH_catch_catch
, (struct block
*) NULL
,
895 VAR_DOMAIN
, 0, (struct symtab
**) NULL
);
896 if (sym
) /* sometimes present in debug info */
898 eh_catch_catch_addr
= SYMBOL_VALUE_ADDRESS (sym
);
899 hp_cxx_exception_support
= 1;
902 /* otherwise look in SOM symbol dict. */
904 msym
= lookup_minimal_symbol (HP_ACC_EH_catch_catch
, NULL
, NULL
);
907 eh_catch_catch_addr
= SYMBOL_VALUE_ADDRESS (msym
);
908 hp_cxx_exception_support
= 1;
912 warning ("Unable to enable interception of exception catches.");
913 warning ("Executable may not have been compiled debuggable with HP aCC.");
914 warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
919 /* Next look for the catch enable flag provided end.o */
920 sym
= lookup_symbol (HP_ACC_EH_catch_catch
, (struct block
*) NULL
,
921 VAR_DOMAIN
, 0, (struct symtab
**) NULL
);
922 if (sym
) /* sometimes present in debug info */
924 eh_catch_throw_addr
= SYMBOL_VALUE_ADDRESS (sym
);
925 hp_cxx_exception_support
= 1;
928 /* otherwise look in SOM symbol dict. */
930 msym
= lookup_minimal_symbol (HP_ACC_EH_catch_throw
, NULL
, NULL
);
933 eh_catch_throw_addr
= SYMBOL_VALUE_ADDRESS (msym
);
934 hp_cxx_exception_support
= 1;
938 warning ("Unable to enable interception of exception throws.");
939 warning ("Executable may not have been compiled debuggable with HP aCC.");
940 warning ("Suggest linking executable with -g (link in /opt/langtools/lib/end.o).");
946 hp_cxx_exception_support
= 2; /* everything worked so far */
947 hp_cxx_exception_support_initialized
= 1;
948 deprecated_exception_support_initialized
= 1;
953 /* Target operation for enabling or disabling interception of
955 KIND is either EX_EVENT_THROW or EX_EVENT_CATCH
956 ENABLE is either 0 (disable) or 1 (enable).
957 Return value is NULL if no support found;
958 -1 if something went wrong,
959 or a pointer to a symtab/line struct if the breakpointable
960 address was found. */
962 struct symtab_and_line
*
963 child_enable_exception_callback (enum exception_event_kind kind
, int enable
)
967 if (!deprecated_exception_support_initialized
968 || !hp_cxx_exception_support_initialized
)
969 if (!initialize_hp_cxx_exception_support ())
972 switch (hp_cxx_exception_support
)
975 /* Assuming no HP support at all */
978 /* HP support should be present, but something went wrong */
979 return (struct symtab_and_line
*) -1; /* yuck! */
980 /* there may be other cases in the future */
983 /* Set the EH hook to point to the callback routine */
984 store_unsigned_integer (buf
, 4, enable
? eh_notify_callback_addr
: 0); /* FIXME 32x64 problem */
985 /* pai: (temp) FIXME should there be a pack operation first? */
986 if (target_write_memory (eh_notify_hook_addr
, buf
, 4)) /* FIXME 32x64 problem */
988 warning ("Could not write to target memory for exception event callback.");
989 warning ("Interception of exception events may not work.");
990 return (struct symtab_and_line
*) -1;
994 /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
995 if (PIDGET (inferior_ptid
) > 0)
997 if (setup_d_pid_in_inferior ())
998 return (struct symtab_and_line
*) -1;
1002 warning ("Internal error: Invalid inferior pid? Cannot intercept exception events.");
1003 return (struct symtab_and_line
*) -1;
1009 case EX_EVENT_THROW
:
1010 store_unsigned_integer (buf
, 4, enable
? 1 : 0);
1011 if (target_write_memory (eh_catch_throw_addr
, buf
, 4)) /* FIXME 32x64? */
1013 warning ("Couldn't enable exception throw interception.");
1014 return (struct symtab_and_line
*) -1;
1017 case EX_EVENT_CATCH
:
1018 store_unsigned_integer (buf
, 4, enable
? 1 : 0);
1019 if (target_write_memory (eh_catch_catch_addr
, buf
, 4)) /* FIXME 32x64? */
1021 warning ("Couldn't enable exception catch interception.");
1022 return (struct symtab_and_line
*) -1;
1026 error ("Request to enable unknown or unsupported exception event.");
1029 /* Copy break address into new sal struct, malloc'ing if needed. */
1030 if (!break_callback_sal
)
1032 break_callback_sal
= (struct symtab_and_line
*) xmalloc (sizeof (struct symtab_and_line
));
1034 init_sal (break_callback_sal
);
1035 break_callback_sal
->symtab
= NULL
;
1036 break_callback_sal
->pc
= eh_break_addr
;
1037 break_callback_sal
->line
= 0;
1038 break_callback_sal
->end
= eh_break_addr
;
1040 return break_callback_sal
;
1043 /* Record some information about the current exception event */
1044 static struct exception_event_record current_ex_event
;
1045 /* Convenience struct */
1046 static struct symtab_and_line null_symtab_and_line
=
1049 /* Report current exception event. Returns a pointer to a record
1050 that describes the kind of the event, where it was thrown from,
1051 and where it will be caught. More information may be reported
1053 struct exception_event_record
*
1054 child_get_current_exception_event (void)
1056 CORE_ADDR event_kind
;
1057 CORE_ADDR throw_addr
;
1058 CORE_ADDR catch_addr
;
1059 struct frame_info
*fi
, *curr_frame
;
1062 curr_frame
= get_current_frame ();
1064 return (struct exception_event_record
*) NULL
;
1066 /* Go up one frame to __d_eh_notify_callback, because at the
1067 point when this code is executed, there's garbage in the
1068 arguments of __d_eh_break. */
1069 fi
= find_relative_frame (curr_frame
, &level
);
1071 return (struct exception_event_record
*) NULL
;
1075 /* Read in the arguments */
1076 /* __d_eh_notify_callback() is called with 3 arguments:
1077 1. event kind catch or throw
1078 2. the target address if known
1079 3. a flag -- not sure what this is. pai/1997-07-17 */
1080 event_kind
= read_register (HPPA_ARG0_REGNUM
);
1081 catch_addr
= read_register (HPPA_ARG1_REGNUM
);
1083 /* Now go down to a user frame */
1084 /* For a throw, __d_eh_break is called by
1085 __d_eh_notify_callback which is called by
1086 __notify_throw which is called
1088 For a catch, __d_eh_break is called by
1089 __d_eh_notify_callback which is called by
1090 <stackwalking stuff> which is called by
1091 __throw__<stuff> or __rethrow_<stuff> which is called
1093 /* FIXME: Don't use such magic numbers; search for the frames */
1094 level
= (event_kind
== EX_EVENT_THROW
) ? 3 : 4;
1095 fi
= find_relative_frame (curr_frame
, &level
);
1097 return (struct exception_event_record
*) NULL
;
1100 throw_addr
= get_frame_pc (fi
);
1102 /* Go back to original (top) frame */
1103 select_frame (curr_frame
);
1105 current_ex_event
.kind
= (enum exception_event_kind
) event_kind
;
1106 current_ex_event
.throw_sal
= find_pc_line (throw_addr
, 1);
1107 current_ex_event
.catch_sal
= find_pc_line (catch_addr
, 1);
1109 return ¤t_ex_event
;
1112 /* Signal frames. */
1113 struct hppa_hpux_sigtramp_unwind_cache
1116 struct trad_frame_saved_reg
*saved_regs
;
1119 static int hppa_hpux_tramp_reg
[] = {
1121 HPPA_PCOQ_HEAD_REGNUM
,
1122 HPPA_PCSQ_HEAD_REGNUM
,
1123 HPPA_PCOQ_TAIL_REGNUM
,
1124 HPPA_PCSQ_TAIL_REGNUM
,
1132 HPPA_SR4_REGNUM
+ 1,
1133 HPPA_SR4_REGNUM
+ 2,
1134 HPPA_SR4_REGNUM
+ 3,
1135 HPPA_SR4_REGNUM
+ 4,
1136 HPPA_SR4_REGNUM
+ 5,
1137 HPPA_SR4_REGNUM
+ 6,
1138 HPPA_SR4_REGNUM
+ 7,
1146 HPPA_TR0_REGNUM
+ 1,
1147 HPPA_TR0_REGNUM
+ 2,
1151 static struct hppa_hpux_sigtramp_unwind_cache
*
1152 hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info
*next_frame
,
1156 struct gdbarch
*gdbarch
= get_frame_arch (next_frame
);
1157 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
1158 struct hppa_hpux_sigtramp_unwind_cache
*info
;
1160 CORE_ADDR sp
, scptr
;
1161 int i
, incr
, off
, szoff
;
1166 info
= FRAME_OBSTACK_ZALLOC (struct hppa_hpux_sigtramp_unwind_cache
);
1168 info
->saved_regs
= trad_frame_alloc_saved_regs (next_frame
);
1170 sp
= frame_unwind_register_unsigned (next_frame
, HPPA_SP_REGNUM
);
1175 /* See /usr/include/machine/save_state.h for the structure of the save_state_t
1178 flag
= read_memory_unsigned_integer(scptr
, 4);
1182 /* Narrow registers. */
1183 off
= scptr
+ offsetof (save_state_t
, ss_narrow
);
1189 /* Wide registers. */
1190 off
= scptr
+ offsetof (save_state_t
, ss_wide
) + 8;
1192 szoff
= (tdep
->bytes_per_address
== 4 ? 4 : 0);
1195 for (i
= 1; i
< 32; i
++)
1197 info
->saved_regs
[HPPA_R0_REGNUM
+ i
].addr
= off
+ szoff
;
1202 i
< sizeof(hppa_hpux_tramp_reg
) / sizeof(hppa_hpux_tramp_reg
[0]);
1205 if (hppa_hpux_tramp_reg
[i
] > 0)
1206 info
->saved_regs
[hppa_hpux_tramp_reg
[i
]].addr
= off
+ szoff
;
1212 info
->base
= frame_unwind_register_unsigned (next_frame
, HPPA_SP_REGNUM
);
1218 hppa_hpux_sigtramp_frame_this_id (struct frame_info
*next_frame
,
1219 void **this_prologue_cache
,
1220 struct frame_id
*this_id
)
1222 struct hppa_hpux_sigtramp_unwind_cache
*info
1223 = hppa_hpux_sigtramp_frame_unwind_cache (next_frame
, this_prologue_cache
);
1224 *this_id
= frame_id_build (info
->base
, frame_pc_unwind (next_frame
));
1228 hppa_hpux_sigtramp_frame_prev_register (struct frame_info
*next_frame
,
1229 void **this_prologue_cache
,
1230 int regnum
, int *optimizedp
,
1231 enum lval_type
*lvalp
,
1233 int *realnump
, void *valuep
)
1235 struct hppa_hpux_sigtramp_unwind_cache
*info
1236 = hppa_hpux_sigtramp_frame_unwind_cache (next_frame
, this_prologue_cache
);
1237 hppa_frame_prev_register_helper (next_frame
, info
->saved_regs
, regnum
,
1238 optimizedp
, lvalp
, addrp
, realnump
, valuep
);
1241 static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind
= {
1243 hppa_hpux_sigtramp_frame_this_id
,
1244 hppa_hpux_sigtramp_frame_prev_register
1247 static const struct frame_unwind
*
1248 hppa_hpux_sigtramp_unwind_sniffer (struct frame_info
*next_frame
)
1250 CORE_ADDR pc
= frame_pc_unwind (next_frame
);
1253 find_pc_partial_function (pc
, &name
, NULL
, NULL
);
1255 if (name
&& strcmp(name
, "_sigreturn") == 0)
1256 return &hppa_hpux_sigtramp_frame_unwind
;
1262 hppa_hpux_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
1264 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
1266 if (tdep
->bytes_per_address
== 4)
1267 set_gdbarch_in_solib_call_trampoline (gdbarch
,
1268 hppa32_hpux_in_solib_call_trampoline
);
1270 set_gdbarch_in_solib_call_trampoline (gdbarch
,
1271 hppa64_hpux_in_solib_call_trampoline
);
1273 set_gdbarch_in_solib_return_trampoline (gdbarch
,
1274 hppa_hpux_in_solib_return_trampoline
);
1275 set_gdbarch_skip_trampoline_code (gdbarch
, hppa_hpux_skip_trampoline_code
);
1277 frame_unwind_append_sniffer (gdbarch
, hppa_hpux_sigtramp_unwind_sniffer
);
1281 hppa_hpux_som_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
1283 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
1286 hppa_hpux_init_abi (info
, gdbarch
);
1290 hppa_hpux_elf_init_abi (struct gdbarch_info info
, struct gdbarch
*gdbarch
)
1292 struct gdbarch_tdep
*tdep
= gdbarch_tdep (gdbarch
);
1295 hppa_hpux_init_abi (info
, gdbarch
);
1299 _initialize_hppa_hpux_tdep (void)
1301 gdbarch_register_osabi (bfd_arch_hppa
, 0, GDB_OSABI_HPUX_SOM
,
1302 hppa_hpux_som_init_abi
);
1303 gdbarch_register_osabi (bfd_arch_hppa
, bfd_mach_hppa20w
, GDB_OSABI_HPUX_ELF
,
1304 hppa_hpux_elf_init_abi
);