2006-02-24 Randolph Chung <tausq@debian.org>
[external/binutils.git] / gdb / hppa-hpux-tdep.c
1 /* Target-dependent code for HP-UX on PA-RISC.
2
3    Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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., 51 Franklin Street, Fifth Floor,
20    Boston, MA 02110-1301, USA.  */
21
22 #include "defs.h"
23 #include "arch-utils.h"
24 #include "gdbcore.h"
25 #include "osabi.h"
26 #include "frame.h"
27 #include "frame-unwind.h"
28 #include "trad-frame.h"
29 #include "symtab.h"
30 #include "objfiles.h"
31 #include "inferior.h"
32 #include "infcall.h"
33 #include "observer.h"
34 #include "hppa-tdep.h"
35 #include "solib-som.h"
36 #include "solib-pa64.h"
37 #include "regset.h"
38 #include "exceptions.h"
39
40 #include "gdb_string.h"
41
42 #include <dl.h>
43 #include <machine/save_state.h>
44
45 #ifndef offsetof
46 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
47 #endif
48
49 #define IS_32BIT_TARGET(_gdbarch) \
50         ((gdbarch_tdep (_gdbarch))->bytes_per_address == 4)
51
52 /* Bit in the `ss_flag' member of `struct save_state' that indicates
53    that the 64-bit register values are live.  From
54    <machine/save_state.h>.  */
55 #define HPPA_HPUX_SS_WIDEREGS           0x40
56
57 /* Offsets of various parts of `struct save_state'.  From
58    <machine/save_state.h>.  */
59 #define HPPA_HPUX_SS_FLAGS_OFFSET       0
60 #define HPPA_HPUX_SS_NARROW_OFFSET      4
61 #define HPPA_HPUX_SS_FPBLOCK_OFFSET     256
62 #define HPPA_HPUX_SS_WIDE_OFFSET        640
63
64 /* The size of `struct save_state.  */
65 #define HPPA_HPUX_SAVE_STATE_SIZE       1152
66
67 /* The size of `struct pa89_save_state', which corresponds to PA-RISC
68    1.1, the lowest common denominator that we support.  */
69 #define HPPA_HPUX_PA89_SAVE_STATE_SIZE  512
70
71
72 /* Forward declarations.  */
73 extern void _initialize_hppa_hpux_tdep (void);
74 extern initialize_file_ftype _initialize_hppa_hpux_tdep;
75
76 typedef struct
77   {
78     struct minimal_symbol *msym;
79     CORE_ADDR solib_handle;
80     CORE_ADDR return_val;
81   }
82 args_for_find_stub;
83
84 static int
85 in_opd_section (CORE_ADDR pc)
86 {
87   struct obj_section *s;
88   int retval = 0;
89
90   s = find_pc_section (pc);
91
92   retval = (s != NULL
93             && s->the_bfd_section->name != NULL
94             && strcmp (s->the_bfd_section->name, ".opd") == 0);
95   return (retval);
96 }
97
98 /* Return one if PC is in the call path of a trampoline, else return zero.
99
100    Note we return one for *any* call trampoline (long-call, arg-reloc), not
101    just shared library trampolines (import, export).  */
102
103 static int
104 hppa32_hpux_in_solib_call_trampoline (CORE_ADDR pc, char *name)
105 {
106   struct minimal_symbol *minsym;
107   struct unwind_table_entry *u;
108
109   /* First see if PC is in one of the two C-library trampolines.  */
110   if (pc == hppa_symbol_address("$$dyncall") 
111       || pc == hppa_symbol_address("_sr4export"))
112     return 1;
113
114   minsym = lookup_minimal_symbol_by_pc (pc);
115   if (minsym && strcmp (DEPRECATED_SYMBOL_NAME (minsym), ".stub") == 0)
116     return 1;
117
118   /* Get the unwind descriptor corresponding to PC, return zero
119      if no unwind was found.  */
120   u = find_unwind_entry (pc);
121   if (!u)
122     return 0;
123
124   /* If this isn't a linker stub, then return now.  */
125   if (u->stub_unwind.stub_type == 0)
126     return 0;
127
128   /* By definition a long-branch stub is a call stub.  */
129   if (u->stub_unwind.stub_type == LONG_BRANCH)
130     return 1;
131
132   /* The call and return path execute the same instructions within
133      an IMPORT stub!  So an IMPORT stub is both a call and return
134      trampoline.  */
135   if (u->stub_unwind.stub_type == IMPORT)
136     return 1;
137
138   /* Parameter relocation stubs always have a call path and may have a
139      return path.  */
140   if (u->stub_unwind.stub_type == PARAMETER_RELOCATION
141       || u->stub_unwind.stub_type == EXPORT)
142     {
143       CORE_ADDR addr;
144
145       /* Search forward from the current PC until we hit a branch
146          or the end of the stub.  */
147       for (addr = pc; addr <= u->region_end; addr += 4)
148         {
149           unsigned long insn;
150
151           insn = read_memory_integer (addr, 4);
152
153           /* Does it look like a bl?  If so then it's the call path, if
154              we find a bv or be first, then we're on the return path.  */
155           if ((insn & 0xfc00e000) == 0xe8000000)
156             return 1;
157           else if ((insn & 0xfc00e001) == 0xe800c000
158                    || (insn & 0xfc000000) == 0xe0000000)
159             return 0;
160         }
161
162       /* Should never happen.  */
163       warning (_("Unable to find branch in parameter relocation stub."));
164       return 0;
165     }
166
167   /* Unknown stub type.  For now, just return zero.  */
168   return 0;
169 }
170
171 static int
172 hppa64_hpux_in_solib_call_trampoline (CORE_ADDR pc, char *name)
173 {
174   /* PA64 has a completely different stub/trampoline scheme.  Is it
175      better?  Maybe.  It's certainly harder to determine with any
176      certainty that we are in a stub because we can not refer to the
177      unwinders to help. 
178
179      The heuristic is simple.  Try to lookup the current PC value in th
180      minimal symbol table.  If that fails, then assume we are not in a
181      stub and return.
182
183      Then see if the PC value falls within the section bounds for the
184      section containing the minimal symbol we found in the first
185      step.  If it does, then assume we are not in a stub and return.
186
187      Finally peek at the instructions to see if they look like a stub.  */
188   struct minimal_symbol *minsym;
189   asection *sec;
190   CORE_ADDR addr;
191   int insn, i;
192
193   minsym = lookup_minimal_symbol_by_pc (pc);
194   if (! minsym)
195     return 0;
196
197   sec = SYMBOL_BFD_SECTION (minsym);
198
199   if (bfd_get_section_vma (sec->owner, sec) <= pc
200       && pc < (bfd_get_section_vma (sec->owner, sec)
201                  + bfd_section_size (sec->owner, sec)))
202       return 0;
203
204   /* We might be in a stub.  Peek at the instructions.  Stubs are 3
205      instructions long. */
206   insn = read_memory_integer (pc, 4);
207
208   /* Find out where we think we are within the stub.  */
209   if ((insn & 0xffffc00e) == 0x53610000)
210     addr = pc;
211   else if ((insn & 0xffffffff) == 0xe820d000)
212     addr = pc - 4;
213   else if ((insn & 0xffffc00e) == 0x537b0000)
214     addr = pc - 8;
215   else
216     return 0;
217
218   /* Now verify each insn in the range looks like a stub instruction.  */
219   insn = read_memory_integer (addr, 4);
220   if ((insn & 0xffffc00e) != 0x53610000)
221     return 0;
222         
223   /* Now verify each insn in the range looks like a stub instruction.  */
224   insn = read_memory_integer (addr + 4, 4);
225   if ((insn & 0xffffffff) != 0xe820d000)
226     return 0;
227     
228   /* Now verify each insn in the range looks like a stub instruction.  */
229   insn = read_memory_integer (addr + 8, 4);
230   if ((insn & 0xffffc00e) != 0x537b0000)
231     return 0;
232
233   /* Looks like a stub.  */
234   return 1;
235 }
236
237 /* Return one if PC is in the return path of a trampoline, else return zero.
238
239    Note we return one for *any* call trampoline (long-call, arg-reloc), not
240    just shared library trampolines (import, export).  */
241
242 static int
243 hppa_hpux_in_solib_return_trampoline (CORE_ADDR pc, char *name)
244 {
245   struct unwind_table_entry *u;
246
247   /* Get the unwind descriptor corresponding to PC, return zero
248      if no unwind was found.  */
249   u = find_unwind_entry (pc);
250   if (!u)
251     return 0;
252
253   /* If this isn't a linker stub or it's just a long branch stub, then
254      return zero.  */
255   if (u->stub_unwind.stub_type == 0 || u->stub_unwind.stub_type == LONG_BRANCH)
256     return 0;
257
258   /* The call and return path execute the same instructions within
259      an IMPORT stub!  So an IMPORT stub is both a call and return
260      trampoline.  */
261   if (u->stub_unwind.stub_type == IMPORT)
262     return 1;
263
264   /* Parameter relocation stubs always have a call path and may have a
265      return path.  */
266   if (u->stub_unwind.stub_type == PARAMETER_RELOCATION
267       || u->stub_unwind.stub_type == EXPORT)
268     {
269       CORE_ADDR addr;
270
271       /* Search forward from the current PC until we hit a branch
272          or the end of the stub.  */
273       for (addr = pc; addr <= u->region_end; addr += 4)
274         {
275           unsigned long insn;
276
277           insn = read_memory_integer (addr, 4);
278
279           /* Does it look like a bl?  If so then it's the call path, if
280              we find a bv or be first, then we're on the return path.  */
281           if ((insn & 0xfc00e000) == 0xe8000000)
282             return 0;
283           else if ((insn & 0xfc00e001) == 0xe800c000
284                    || (insn & 0xfc000000) == 0xe0000000)
285             return 1;
286         }
287
288       /* Should never happen.  */
289       warning (_("Unable to find branch in parameter relocation stub."));
290       return 0;
291     }
292
293   /* Unknown stub type.  For now, just return zero.  */
294   return 0;
295
296 }
297
298 /* Figure out if PC is in a trampoline, and if so find out where
299    the trampoline will jump to.  If not in a trampoline, return zero.
300
301    Simple code examination probably is not a good idea since the code
302    sequences in trampolines can also appear in user code.
303
304    We use unwinds and information from the minimal symbol table to
305    determine when we're in a trampoline.  This won't work for ELF
306    (yet) since it doesn't create stub unwind entries.  Whether or
307    not ELF will create stub unwinds or normal unwinds for linker
308    stubs is still being debated.
309
310    This should handle simple calls through dyncall or sr4export,
311    long calls, argument relocation stubs, and dyncall/sr4export
312    calling an argument relocation stub.  It even handles some stubs
313    used in dynamic executables.  */
314
315 static CORE_ADDR
316 hppa_hpux_skip_trampoline_code (CORE_ADDR pc)
317 {
318   long orig_pc = pc;
319   long prev_inst, curr_inst, loc;
320   struct minimal_symbol *msym;
321   struct unwind_table_entry *u;
322
323   /* Addresses passed to dyncall may *NOT* be the actual address
324      of the function.  So we may have to do something special.  */
325   if (pc == hppa_symbol_address("$$dyncall"))
326     {
327       pc = (CORE_ADDR) read_register (22);
328
329       /* If bit 30 (counting from the left) is on, then pc is the address of
330          the PLT entry for this function, not the address of the function
331          itself.  Bit 31 has meaning too, but only for MPE.  */
332       if (pc & 0x2)
333         pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
334     }
335   if (pc == hppa_symbol_address("$$dyncall_external"))
336     {
337       pc = (CORE_ADDR) read_register (22);
338       pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
339     }
340   else if (pc == hppa_symbol_address("_sr4export"))
341     pc = (CORE_ADDR) (read_register (22));
342
343   /* Get the unwind descriptor corresponding to PC, return zero
344      if no unwind was found.  */
345   u = find_unwind_entry (pc);
346   if (!u)
347     return 0;
348
349   /* If this isn't a linker stub, then return now.  */
350   /* elz: attention here! (FIXME) because of a compiler/linker 
351      error, some stubs which should have a non zero stub_unwind.stub_type 
352      have unfortunately a value of zero. So this function would return here
353      as if we were not in a trampoline. To fix this, we go look at the partial
354      symbol information, which reports this guy as a stub.
355      (FIXME): Unfortunately, we are not that lucky: it turns out that the 
356      partial symbol information is also wrong sometimes. This is because 
357      when it is entered (somread.c::som_symtab_read()) it can happen that
358      if the type of the symbol (from the som) is Entry, and the symbol is
359      in a shared library, then it can also be a trampoline.  This would
360      be OK, except that I believe the way they decide if we are ina shared library
361      does not work. SOOOO..., even if we have a regular function w/o trampolines
362      its minimal symbol can be assigned type mst_solib_trampoline.
363      Also, if we find that the symbol is a real stub, then we fix the unwind
364      descriptor, and define the stub type to be EXPORT.
365      Hopefully this is correct most of the times. */
366   if (u->stub_unwind.stub_type == 0)
367     {
368
369 /* elz: NOTE (FIXME!) once the problem with the unwind information is fixed
370    we can delete all the code which appears between the lines */
371 /*--------------------------------------------------------------------------*/
372       msym = lookup_minimal_symbol_by_pc (pc);
373
374       if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline)
375         return orig_pc == pc ? 0 : pc & ~0x3;
376
377       else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline)
378         {
379           struct objfile *objfile;
380           struct minimal_symbol *msymbol;
381           int function_found = 0;
382
383           /* go look if there is another minimal symbol with the same name as 
384              this one, but with type mst_text. This would happen if the msym
385              is an actual trampoline, in which case there would be another
386              symbol with the same name corresponding to the real function */
387
388           ALL_MSYMBOLS (objfile, msymbol)
389           {
390             if (MSYMBOL_TYPE (msymbol) == mst_text
391                 && DEPRECATED_STREQ (DEPRECATED_SYMBOL_NAME (msymbol), DEPRECATED_SYMBOL_NAME (msym)))
392               {
393                 function_found = 1;
394                 break;
395               }
396           }
397
398           if (function_found)
399             /* the type of msym is correct (mst_solib_trampoline), but
400                the unwind info is wrong, so set it to the correct value */
401             u->stub_unwind.stub_type = EXPORT;
402           else
403             /* the stub type info in the unwind is correct (this is not a
404                trampoline), but the msym type information is wrong, it
405                should be mst_text. So we need to fix the msym, and also
406                get out of this function */
407             {
408               MSYMBOL_TYPE (msym) = mst_text;
409               return orig_pc == pc ? 0 : pc & ~0x3;
410             }
411         }
412
413 /*--------------------------------------------------------------------------*/
414     }
415
416   /* It's a stub.  Search for a branch and figure out where it goes.
417      Note we have to handle multi insn branch sequences like ldil;ble.
418      Most (all?) other branches can be determined by examining the contents
419      of certain registers and the stack.  */
420
421   loc = pc;
422   curr_inst = 0;
423   prev_inst = 0;
424   while (1)
425     {
426       /* Make sure we haven't walked outside the range of this stub.  */
427       if (u != find_unwind_entry (loc))
428         {
429           warning (_("Unable to find branch in linker stub"));
430           return orig_pc == pc ? 0 : pc & ~0x3;
431         }
432
433       prev_inst = curr_inst;
434       curr_inst = read_memory_integer (loc, 4);
435
436       /* Does it look like a branch external using %r1?  Then it's the
437          branch from the stub to the actual function.  */
438       if ((curr_inst & 0xffe0e000) == 0xe0202000)
439         {
440           /* Yup.  See if the previous instruction loaded
441              a value into %r1.  If so compute and return the jump address.  */
442           if ((prev_inst & 0xffe00000) == 0x20200000)
443             return (hppa_extract_21 (prev_inst) + hppa_extract_17 (curr_inst)) & ~0x3;
444           else
445             {
446               warning (_("Unable to find ldil X,%%r1 before ble Y(%%sr4,%%r1)."));
447               return orig_pc == pc ? 0 : pc & ~0x3;
448             }
449         }
450
451       /* Does it look like a be 0(sr0,%r21)? OR 
452          Does it look like a be, n 0(sr0,%r21)? OR 
453          Does it look like a bve (r21)? (this is on PA2.0)
454          Does it look like a bve, n(r21)? (this is also on PA2.0)
455          That's the branch from an
456          import stub to an export stub.
457
458          It is impossible to determine the target of the branch via
459          simple examination of instructions and/or data (consider
460          that the address in the plabel may be the address of the
461          bind-on-reference routine in the dynamic loader).
462
463          So we have try an alternative approach.
464
465          Get the name of the symbol at our current location; it should
466          be a stub symbol with the same name as the symbol in the
467          shared library.
468
469          Then lookup a minimal symbol with the same name; we should
470          get the minimal symbol for the target routine in the shared
471          library as those take precedence of import/export stubs.  */
472       if ((curr_inst == 0xe2a00000) ||
473           (curr_inst == 0xe2a00002) ||
474           (curr_inst == 0xeaa0d000) ||
475           (curr_inst == 0xeaa0d002))
476         {
477           struct minimal_symbol *stubsym, *libsym;
478
479           stubsym = lookup_minimal_symbol_by_pc (loc);
480           if (stubsym == NULL)
481             {
482               warning (_("Unable to find symbol for 0x%lx"), loc);
483               return orig_pc == pc ? 0 : pc & ~0x3;
484             }
485
486           libsym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (stubsym), NULL, NULL);
487           if (libsym == NULL)
488             {
489               warning (_("Unable to find library symbol for %s."),
490                        DEPRECATED_SYMBOL_NAME (stubsym));
491               return orig_pc == pc ? 0 : pc & ~0x3;
492             }
493
494           return SYMBOL_VALUE (libsym);
495         }
496
497       /* Does it look like bl X,%rp or bl X,%r0?  Another way to do a
498          branch from the stub to the actual function.  */
499       /*elz */
500       else if ((curr_inst & 0xffe0e000) == 0xe8400000
501                || (curr_inst & 0xffe0e000) == 0xe8000000
502                || (curr_inst & 0xffe0e000) == 0xe800A000)
503         return (loc + hppa_extract_17 (curr_inst) + 8) & ~0x3;
504
505       /* Does it look like bv (rp)?   Note this depends on the
506          current stack pointer being the same as the stack
507          pointer in the stub itself!  This is a branch on from the
508          stub back to the original caller.  */
509       /*else if ((curr_inst & 0xffe0e000) == 0xe840c000) */
510       else if ((curr_inst & 0xffe0f000) == 0xe840c000)
511         {
512           /* Yup.  See if the previous instruction loaded
513              rp from sp - 8.  */
514           if (prev_inst == 0x4bc23ff1)
515             return (read_memory_integer
516                     (read_register (HPPA_SP_REGNUM) - 8, 4)) & ~0x3;
517           else
518             {
519               warning (_("Unable to find restore of %%rp before bv (%%rp)."));
520               return orig_pc == pc ? 0 : pc & ~0x3;
521             }
522         }
523
524       /* elz: added this case to capture the new instruction
525          at the end of the return part of an export stub used by
526          the PA2.0: BVE, n (rp) */
527       else if ((curr_inst & 0xffe0f000) == 0xe840d000)
528         {
529           return (read_memory_integer
530                   (read_register (HPPA_SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
531         }
532
533       /* What about be,n 0(sr0,%rp)?  It's just another way we return to
534          the original caller from the stub.  Used in dynamic executables.  */
535       else if (curr_inst == 0xe0400002)
536         {
537           /* The value we jump to is sitting in sp - 24.  But that's
538              loaded several instructions before the be instruction.
539              I guess we could check for the previous instruction being
540              mtsp %r1,%sr0 if we want to do sanity checking.  */
541           return (read_memory_integer
542                   (read_register (HPPA_SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
543         }
544
545       /* Haven't found the branch yet, but we're still in the stub.
546          Keep looking.  */
547       loc += 4;
548     }
549 }
550
551 void
552 hppa_skip_permanent_breakpoint (void)
553 {
554   /* To step over a breakpoint instruction on the PA takes some
555      fiddling with the instruction address queue.
556
557      When we stop at a breakpoint, the IA queue front (the instruction
558      we're executing now) points at the breakpoint instruction, and
559      the IA queue back (the next instruction to execute) points to
560      whatever instruction we would execute after the breakpoint, if it
561      were an ordinary instruction.  This is the case even if the
562      breakpoint is in the delay slot of a branch instruction.
563
564      Clearly, to step past the breakpoint, we need to set the queue
565      front to the back.  But what do we put in the back?  What
566      instruction comes after that one?  Because of the branch delay
567      slot, the next insn is always at the back + 4.  */
568   write_register (HPPA_PCOQ_HEAD_REGNUM, read_register (HPPA_PCOQ_TAIL_REGNUM));
569   write_register (HPPA_PCSQ_HEAD_REGNUM, read_register (HPPA_PCSQ_TAIL_REGNUM));
570
571   write_register (HPPA_PCOQ_TAIL_REGNUM, read_register (HPPA_PCOQ_TAIL_REGNUM) + 4);
572   /* We can leave the tail's space the same, since there's no jump.  */
573 }
574
575 /* Exception handling support for the HP-UX ANSI C++ compiler.
576    The compiler (aCC) provides a callback for exception events;
577    GDB can set a breakpoint on this callback and find out what
578    exception event has occurred. */
579
580 /* The name of the hook to be set to point to the callback function.  */
581 static char HP_ACC_EH_notify_hook[] = "__eh_notify_hook";
582 /* The name of the function to be used to set the hook value.  */
583 static char HP_ACC_EH_set_hook_value[] = "__eh_set_hook_value";
584 /* The name of the callback function in end.o */
585 static char HP_ACC_EH_notify_callback[] = "__d_eh_notify_callback";
586 /* Name of function in end.o on which a break is set (called by above).  */
587 static char HP_ACC_EH_break[] = "__d_eh_break";
588 /* Name of flag (in end.o) that enables catching throws.  */
589 static char HP_ACC_EH_catch_throw[] = "__d_eh_catch_throw";
590 /* Name of flag (in end.o) that enables catching catching.  */
591 static char HP_ACC_EH_catch_catch[] = "__d_eh_catch_catch";
592 /* The enum used by aCC.  */
593 typedef enum
594   {
595     __EH_NOTIFY_THROW,
596     __EH_NOTIFY_CATCH
597   }
598 __eh_notification;
599
600 /* Is exception-handling support available with this executable? */
601 static int hp_cxx_exception_support = 0;
602 /* Has the initialize function been run? */
603 static int hp_cxx_exception_support_initialized = 0;
604 /* Address of __eh_notify_hook */
605 static CORE_ADDR eh_notify_hook_addr = 0;
606 /* Address of __d_eh_notify_callback */
607 static CORE_ADDR eh_notify_callback_addr = 0;
608 /* Address of __d_eh_break */
609 static CORE_ADDR eh_break_addr = 0;
610 /* Address of __d_eh_catch_catch */
611 static CORE_ADDR eh_catch_catch_addr = 0;
612 /* Address of __d_eh_catch_throw */
613 static CORE_ADDR eh_catch_throw_addr = 0;
614 /* Sal for __d_eh_break */
615 static struct symtab_and_line *break_callback_sal = 0;
616
617 /* Code in end.c expects __d_pid to be set in the inferior,
618    otherwise __d_eh_notify_callback doesn't bother to call
619    __d_eh_break!  So we poke the pid into this symbol
620    ourselves.
621    0 => success
622    1 => failure  */
623 static int
624 setup_d_pid_in_inferior (void)
625 {
626   CORE_ADDR anaddr;
627   struct minimal_symbol *msymbol;
628   char buf[4];                  /* FIXME 32x64? */
629
630   /* Slam the pid of the process into __d_pid; failing is only a warning!  */
631   msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
632   if (msymbol == NULL)
633     {
634       warning (_("Unable to find __d_pid symbol in object file.\n"
635                  "Suggest linking executable with -g (links in /opt/langtools/lib/end.o)."));
636       return 1;
637     }
638
639   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
640   store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); /* FIXME 32x64? */
641   if (target_write_memory (anaddr, buf, 4))     /* FIXME 32x64? */
642     {
643       warning (_("Unable to write __d_pid.\n"
644                  "Suggest linking executable with -g (links in /opt/langtools/lib/end.o)."));
645       return 1;
646     }
647   return 0;
648 }
649
650 /* elz: Used to lookup a symbol in the shared libraries.
651    This function calls shl_findsym, indirectly through a
652    call to __d_shl_get. __d_shl_get is in end.c, which is always
653    linked in by the hp compilers/linkers. 
654    The call to shl_findsym cannot be made directly because it needs
655    to be active in target address space. 
656    inputs: - minimal symbol pointer for the function we want to look up
657    - address in target space of the descriptor for the library
658    where we want to look the symbol up.
659    This address is retrieved using the 
660    som_solib_get_solib_by_pc function (somsolib.c). 
661    output: - real address in the library of the function.          
662    note: the handle can be null, in which case shl_findsym will look for
663    the symbol in all the loaded shared libraries.
664    files to look at if you need reference on this stuff:
665    dld.c, dld_shl_findsym.c
666    end.c
667    man entry for shl_findsym */
668
669 static CORE_ADDR
670 find_stub_with_shl_get (struct minimal_symbol *function, CORE_ADDR handle)
671 {
672   struct symbol *get_sym, *symbol2;
673   struct minimal_symbol *buff_minsym, *msymbol;
674   struct type *ftype;
675   struct value **args;
676   struct value *funcval;
677   struct value *val;
678
679   int x, namelen, err_value, tmp = -1;
680   CORE_ADDR endo_buff_addr, value_return_addr, errno_return_addr;
681   CORE_ADDR stub_addr;
682
683
684   args = alloca (sizeof (struct value *) * 8);          /* 6 for the arguments and one null one??? */
685   funcval = find_function_in_inferior ("__d_shl_get");
686   get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_DOMAIN, NULL, NULL);
687   buff_minsym = lookup_minimal_symbol ("__buffer", NULL, NULL);
688   msymbol = lookup_minimal_symbol ("__shldp", NULL, NULL);
689   symbol2 = lookup_symbol ("__shldp", NULL, VAR_DOMAIN, NULL, NULL);
690   endo_buff_addr = SYMBOL_VALUE_ADDRESS (buff_minsym);
691   namelen = strlen (DEPRECATED_SYMBOL_NAME (function));
692   value_return_addr = endo_buff_addr + namelen;
693   ftype = check_typedef (SYMBOL_TYPE (get_sym));
694
695   /* do alignment */
696   if ((x = value_return_addr % 64) != 0)
697     value_return_addr = value_return_addr + 64 - x;
698
699   errno_return_addr = value_return_addr + 64;
700
701
702   /* set up stuff needed by __d_shl_get in buffer in end.o */
703
704   target_write_memory (endo_buff_addr, DEPRECATED_SYMBOL_NAME (function), namelen);
705
706   target_write_memory (value_return_addr, (char *) &tmp, 4);
707
708   target_write_memory (errno_return_addr, (char *) &tmp, 4);
709
710   target_write_memory (SYMBOL_VALUE_ADDRESS (msymbol),
711                        (char *) &handle, 4);
712
713   /* now prepare the arguments for the call */
714
715   args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12);
716   args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
717   args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
718   args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE);
719   args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
720   args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
721
722   /* now call the function */
723
724   val = call_function_by_hand (funcval, 6, args);
725
726   /* now get the results */
727
728   target_read_memory (errno_return_addr, (char *) &err_value, sizeof (err_value));
729
730   target_read_memory (value_return_addr, (char *) &stub_addr, sizeof (stub_addr));
731   if (stub_addr <= 0)
732     error (_("call to __d_shl_get failed, error code is %d"), err_value);
733
734   return (stub_addr);
735 }
736
737 /* Cover routine for find_stub_with_shl_get to pass to catch_errors */
738 static int
739 cover_find_stub_with_shl_get (void *args_untyped)
740 {
741   args_for_find_stub *args = args_untyped;
742   args->return_val = find_stub_with_shl_get (args->msym, args->solib_handle);
743   return 0;
744 }
745
746 /* Initialize exception catchpoint support by looking for the
747    necessary hooks/callbacks in end.o, etc., and set the hook value
748    to point to the required debug function.
749
750    Return 0 => failure
751    1 => success          */
752
753 static int
754 initialize_hp_cxx_exception_support (void)
755 {
756   struct symtabs_and_lines sals;
757   struct cleanup *old_chain;
758   struct cleanup *canonical_strings_chain = NULL;
759   int i;
760   char *addr_start;
761   char *addr_end = NULL;
762   char **canonical = (char **) NULL;
763   int thread = -1;
764   struct symbol *sym = NULL;
765   struct minimal_symbol *msym = NULL;
766   struct objfile *objfile;
767   asection *shlib_info;
768
769   /* Detect and disallow recursion.  On HP-UX with aCC, infinite
770      recursion is a possibility because finding the hook for exception
771      callbacks involves making a call in the inferior, which means
772      re-inserting breakpoints which can re-invoke this code.  */
773
774   static int recurse = 0;
775   if (recurse > 0)
776     {
777       hp_cxx_exception_support_initialized = 0;
778       deprecated_exception_support_initialized = 0;
779       return 0;
780     }
781
782   hp_cxx_exception_support = 0;
783
784   /* First check if we have seen any HP compiled objects; if not,
785      it is very unlikely that HP's idiosyncratic callback mechanism
786      for exception handling debug support will be available!
787      This will percolate back up to breakpoint.c, where our callers
788      will decide to try the g++ exception-handling support instead. */
789   if (!deprecated_hp_som_som_object_present)
790     return 0;
791
792   /* We have a SOM executable with SOM debug info; find the hooks.  */
793
794   /* First look for the notify hook provided by aCC runtime libs */
795   /* If we find this symbol, we conclude that the executable must
796      have HP aCC exception support built in.  If this symbol is not
797      found, even though we're a HP SOM-SOM file, we may have been
798      built with some other compiler (not aCC).  This results percolates
799      back up to our callers in breakpoint.c which can decide to
800      try the g++ style of exception support instead.
801      If this symbol is found but the other symbols we require are
802      not found, there is something weird going on, and g++ support
803      should *not* be tried as an alternative.
804
805      ASSUMPTION: Only HP aCC code will have __eh_notify_hook defined.  
806      ASSUMPTION: HP aCC and g++ modules cannot be linked together.  */
807
808   /* libCsup has this hook; it'll usually be non-debuggable */
809   msym = lookup_minimal_symbol (HP_ACC_EH_notify_hook, NULL, NULL);
810   if (msym)
811     {
812       eh_notify_hook_addr = SYMBOL_VALUE_ADDRESS (msym);
813       hp_cxx_exception_support = 1;
814     }
815   else
816     {
817       warning (_("\
818 Unable to find exception callback hook (%s).\n\
819 Executable may not have been compiled debuggable with HP aCC.\n\
820 GDB will be unable to intercept exception events."),
821                HP_ACC_EH_notify_hook);
822       eh_notify_hook_addr = 0;
823       hp_cxx_exception_support = 0;
824       return 0;
825     }
826
827   /* Next look for the notify callback routine in end.o */
828   /* This is always available in the SOM symbol dictionary if end.o is
829      linked in. */
830   msym = lookup_minimal_symbol (HP_ACC_EH_notify_callback, NULL, NULL);
831   if (msym)
832     {
833       eh_notify_callback_addr = SYMBOL_VALUE_ADDRESS (msym);
834       hp_cxx_exception_support = 1;
835     }
836   else
837     {
838       warning (_("\
839 Unable to find exception callback routine (%s).\n\
840 Suggest linking executable with -g (links in /opt/langtools/lib/end.o).\n\
841 GDB will be unable to intercept exception events."),
842                HP_ACC_EH_notify_callback);
843       eh_notify_callback_addr = 0;
844       return 0;
845     }
846
847 #ifndef GDB_TARGET_IS_HPPA_20W
848   /* Check whether the executable is dynamically linked or archive bound */
849   /* With an archive-bound executable we can use the raw addresses we find
850      for the callback function, etc. without modification. For an executable
851      with shared libraries, we have to do more work to find the plabel, which
852      can be the target of a call through $$dyncall from the aCC runtime support
853      library (libCsup) which is linked shared by default by aCC. */
854   /* This test below was copied from somsolib.c/somread.c.  It may not be a very
855      reliable one to test that an executable is linked shared. pai/1997-07-18 */
856   shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
857   if (shlib_info && (bfd_section_size (symfile_objfile->obfd, shlib_info) != 0))
858     {
859       /* The minsym we have has the local code address, but that's not
860          the plabel that can be used by an inter-load-module call.  */
861       /* Find solib handle for main image (which has end.o), and use
862          that and the min sym as arguments to __d_shl_get() (which
863          does the equivalent of shl_findsym()) to find the plabel.  */
864
865       args_for_find_stub args;
866       static char message[] = "Error while finding exception callback hook:\n";
867
868       args.solib_handle = gdbarch_tdep (current_gdbarch)->solib_get_solib_by_pc (eh_notify_callback_addr);
869       args.msym = msym;
870       args.return_val = 0;
871
872       recurse++;
873       catch_errors (cover_find_stub_with_shl_get, &args, message,
874                     RETURN_MASK_ALL);
875       eh_notify_callback_addr = args.return_val;
876       recurse--;
877
878       deprecated_exception_catchpoints_are_fragile = 1;
879
880       if (!eh_notify_callback_addr)
881         {
882           /* We can get here either if there is no plabel in the export list
883              for the main image, or if something strange happened (?) */
884           warning (_("\
885 Couldn't find a plabel (indirect function label) for the exception callback.\n\
886 GDB will not be able to intercept exception events."));
887           return 0;
888         }
889     }
890   else
891     deprecated_exception_catchpoints_are_fragile = 0;
892 #endif
893
894   /* Now, look for the breakpointable routine in end.o */
895   /* This should also be available in the SOM symbol dict. if end.o linked in */
896   msym = lookup_minimal_symbol (HP_ACC_EH_break, NULL, NULL);
897   if (msym)
898     {
899       eh_break_addr = SYMBOL_VALUE_ADDRESS (msym);
900       hp_cxx_exception_support = 1;
901     }
902   else
903     {
904       warning (_("\
905 Unable to find exception callback routine to set breakpoint (%s).\n\
906 Suggest linking executable with -g (link in /opt/langtools/lib/end.o).\n\
907 GDB will be unable to intercept exception events."),
908                HP_ACC_EH_break);
909       eh_break_addr = 0;
910       return 0;
911     }
912
913   /* Next look for the catch enable flag provided in end.o */
914   sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
915                        VAR_DOMAIN, 0, (struct symtab **) NULL);
916   if (sym)                      /* sometimes present in debug info */
917     {
918       eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (sym);
919       hp_cxx_exception_support = 1;
920     }
921   else
922     /* otherwise look in SOM symbol dict. */
923     {
924       msym = lookup_minimal_symbol (HP_ACC_EH_catch_catch, NULL, NULL);
925       if (msym)
926         {
927           eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (msym);
928           hp_cxx_exception_support = 1;
929         }
930       else
931         {
932           warning (_("\
933 Unable to enable interception of exception catches.\n\
934 Executable may not have been compiled debuggable with HP aCC.\n\
935 Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
936           return 0;
937         }
938     }
939
940   /* Next look for the catch enable flag provided end.o */
941   sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
942                        VAR_DOMAIN, 0, (struct symtab **) NULL);
943   if (sym)                      /* sometimes present in debug info */
944     {
945       eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (sym);
946       hp_cxx_exception_support = 1;
947     }
948   else
949     /* otherwise look in SOM symbol dict. */
950     {
951       msym = lookup_minimal_symbol (HP_ACC_EH_catch_throw, NULL, NULL);
952       if (msym)
953         {
954           eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (msym);
955           hp_cxx_exception_support = 1;
956         }
957       else
958         {
959           warning (_("\
960 Unable to enable interception of exception throws.\n\
961 Executable may not have been compiled debuggable with HP aCC.\n\
962 Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
963           return 0;
964         }
965     }
966
967   /* Set the flags */
968   hp_cxx_exception_support = 2; /* everything worked so far */
969   hp_cxx_exception_support_initialized = 1;
970   deprecated_exception_support_initialized = 1;
971
972   return 1;
973 }
974
975 /* Target operation for enabling or disabling interception of
976    exception events.
977    KIND is either EX_EVENT_THROW or EX_EVENT_CATCH
978    ENABLE is either 0 (disable) or 1 (enable).
979    Return value is NULL if no support found;
980    -1 if something went wrong,
981    or a pointer to a symtab/line struct if the breakpointable
982    address was found. */
983
984 struct symtab_and_line *
985 child_enable_exception_callback (enum exception_event_kind kind, int enable)
986 {
987   char buf[4];
988
989   if (!deprecated_exception_support_initialized
990       || !hp_cxx_exception_support_initialized)
991     if (!initialize_hp_cxx_exception_support ())
992       return NULL;
993
994   switch (hp_cxx_exception_support)
995     {
996     case 0:
997       /* Assuming no HP support at all */
998       return NULL;
999     case 1:
1000       /* HP support should be present, but something went wrong */
1001       return (struct symtab_and_line *) -1;     /* yuck! */
1002       /* there may be other cases in the future */
1003     }
1004
1005   /* Set the EH hook to point to the callback routine.  */
1006   store_unsigned_integer (buf, 4, enable ? eh_notify_callback_addr : 0);        /* FIXME 32x64 problem */
1007   /* pai: (temp) FIXME should there be a pack operation first? */
1008   if (target_write_memory (eh_notify_hook_addr, buf, 4))        /* FIXME 32x64 problem */
1009     {
1010       warning (_("\
1011 Could not write to target memory for exception event callback.\n\
1012 Interception of exception events may not work."));
1013       return (struct symtab_and_line *) -1;
1014     }
1015   if (enable)
1016     {
1017       /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
1018       if (PIDGET (inferior_ptid) > 0)
1019         {
1020           if (setup_d_pid_in_inferior ())
1021             return (struct symtab_and_line *) -1;
1022         }
1023       else
1024         {
1025           warning (_("Internal error: Invalid inferior pid?  Cannot intercept exception events."));
1026           return (struct symtab_and_line *) -1;
1027         }
1028     }
1029
1030   switch (kind)
1031     {
1032     case EX_EVENT_THROW:
1033       store_unsigned_integer (buf, 4, enable ? 1 : 0);
1034       if (target_write_memory (eh_catch_throw_addr, buf, 4))    /* FIXME 32x64? */
1035         {
1036           warning (_("Couldn't enable exception throw interception."));
1037           return (struct symtab_and_line *) -1;
1038         }
1039       break;
1040     case EX_EVENT_CATCH:
1041       store_unsigned_integer (buf, 4, enable ? 1 : 0);
1042       if (target_write_memory (eh_catch_catch_addr, buf, 4))    /* FIXME 32x64? */
1043         {
1044           warning (_("Couldn't enable exception catch interception."));
1045           return (struct symtab_and_line *) -1;
1046         }
1047       break;
1048     default:
1049       error (_("Request to enable unknown or unsupported exception event."));
1050     }
1051
1052   /* Copy break address into new sal struct, malloc'ing if needed.  */
1053   if (!break_callback_sal)
1054     break_callback_sal = XMALLOC (struct symtab_and_line);
1055   init_sal (break_callback_sal);
1056   break_callback_sal->symtab = NULL;
1057   break_callback_sal->pc = eh_break_addr;
1058   break_callback_sal->line = 0;
1059   break_callback_sal->end = eh_break_addr;
1060
1061   return break_callback_sal;
1062 }
1063
1064 /* Record some information about the current exception event */
1065 static struct exception_event_record current_ex_event;
1066 /* Convenience struct */
1067 static struct symtab_and_line null_symtab_and_line =
1068 {NULL, 0, 0, 0};
1069
1070 /* Report current exception event.  Returns a pointer to a record
1071    that describes the kind of the event, where it was thrown from,
1072    and where it will be caught.  More information may be reported
1073    in the future */
1074 struct exception_event_record *
1075 child_get_current_exception_event (void)
1076 {
1077   CORE_ADDR event_kind;
1078   CORE_ADDR throw_addr;
1079   CORE_ADDR catch_addr;
1080   struct frame_info *fi, *curr_frame;
1081   int level = 1;
1082
1083   curr_frame = get_current_frame ();
1084   if (!curr_frame)
1085     return (struct exception_event_record *) NULL;
1086
1087   /* Go up one frame to __d_eh_notify_callback, because at the
1088      point when this code is executed, there's garbage in the
1089      arguments of __d_eh_break. */
1090   fi = find_relative_frame (curr_frame, &level);
1091   if (level != 0)
1092     return (struct exception_event_record *) NULL;
1093
1094   select_frame (fi);
1095
1096   /* Read in the arguments */
1097   /* __d_eh_notify_callback() is called with 3 arguments:
1098      1. event kind catch or throw
1099      2. the target address if known
1100      3. a flag -- not sure what this is. pai/1997-07-17 */
1101   event_kind = read_register (HPPA_ARG0_REGNUM);
1102   catch_addr = read_register (HPPA_ARG1_REGNUM);
1103
1104   /* Now go down to a user frame */
1105   /* For a throw, __d_eh_break is called by
1106      __d_eh_notify_callback which is called by
1107      __notify_throw which is called
1108      from user code.
1109      For a catch, __d_eh_break is called by
1110      __d_eh_notify_callback which is called by
1111      <stackwalking stuff> which is called by
1112      __throw__<stuff> or __rethrow_<stuff> which is called
1113      from user code. */
1114   /* FIXME: Don't use such magic numbers; search for the frames */
1115   level = (event_kind == EX_EVENT_THROW) ? 3 : 4;
1116   fi = find_relative_frame (curr_frame, &level);
1117   if (level != 0)
1118     return (struct exception_event_record *) NULL;
1119
1120   select_frame (fi);
1121   throw_addr = get_frame_pc (fi);
1122
1123   /* Go back to original (top) frame */
1124   select_frame (curr_frame);
1125
1126   current_ex_event.kind = (enum exception_event_kind) event_kind;
1127   current_ex_event.throw_sal = find_pc_line (throw_addr, 1);
1128   current_ex_event.catch_sal = find_pc_line (catch_addr, 1);
1129
1130   return &current_ex_event;
1131 }
1132
1133 /* Signal frames.  */
1134 struct hppa_hpux_sigtramp_unwind_cache
1135 {
1136   CORE_ADDR base;
1137   struct trad_frame_saved_reg *saved_regs;
1138 };
1139
1140 static int hppa_hpux_tramp_reg[] = {
1141   HPPA_SAR_REGNUM,
1142   HPPA_PCOQ_HEAD_REGNUM,
1143   HPPA_PCSQ_HEAD_REGNUM,
1144   HPPA_PCOQ_TAIL_REGNUM,
1145   HPPA_PCSQ_TAIL_REGNUM,
1146   HPPA_EIEM_REGNUM,
1147   HPPA_IIR_REGNUM,
1148   HPPA_ISR_REGNUM,
1149   HPPA_IOR_REGNUM,
1150   HPPA_IPSW_REGNUM,
1151   -1,
1152   HPPA_SR4_REGNUM,
1153   HPPA_SR4_REGNUM + 1,
1154   HPPA_SR4_REGNUM + 2,
1155   HPPA_SR4_REGNUM + 3,
1156   HPPA_SR4_REGNUM + 4,
1157   HPPA_SR4_REGNUM + 5,
1158   HPPA_SR4_REGNUM + 6,
1159   HPPA_SR4_REGNUM + 7,
1160   HPPA_RCR_REGNUM,
1161   HPPA_PID0_REGNUM,
1162   HPPA_PID1_REGNUM,
1163   HPPA_CCR_REGNUM,
1164   HPPA_PID2_REGNUM,
1165   HPPA_PID3_REGNUM,
1166   HPPA_TR0_REGNUM,
1167   HPPA_TR0_REGNUM + 1,
1168   HPPA_TR0_REGNUM + 2,
1169   HPPA_CR27_REGNUM
1170 };
1171
1172 static struct hppa_hpux_sigtramp_unwind_cache *
1173 hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
1174                                        void **this_cache)
1175
1176 {
1177   struct gdbarch *gdbarch = get_frame_arch (next_frame);
1178   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1179   struct hppa_hpux_sigtramp_unwind_cache *info;
1180   unsigned int flag;
1181   CORE_ADDR sp, scptr, off;
1182   int i, incr, szoff;
1183
1184   if (*this_cache)
1185     return *this_cache;
1186
1187   info = FRAME_OBSTACK_ZALLOC (struct hppa_hpux_sigtramp_unwind_cache);
1188   *this_cache = info;
1189   info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
1190
1191   sp = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
1192
1193   if (IS_32BIT_TARGET (gdbarch))
1194     scptr = sp - 1352;
1195   else
1196     scptr = sp - 1520;
1197
1198   off = scptr;
1199
1200   /* See /usr/include/machine/save_state.h for the structure of the save_state_t
1201      structure. */
1202   
1203   flag = read_memory_unsigned_integer(scptr + HPPA_HPUX_SS_FLAGS_OFFSET, 4);
1204
1205   if (!(flag & HPPA_HPUX_SS_WIDEREGS))
1206     {
1207       /* Narrow registers. */
1208       off = scptr + HPPA_HPUX_SS_NARROW_OFFSET;
1209       incr = 4;
1210       szoff = 0;
1211     }
1212   else
1213     {
1214       /* Wide registers. */
1215       off = scptr + HPPA_HPUX_SS_WIDE_OFFSET + 8;
1216       incr = 8;
1217       szoff = (tdep->bytes_per_address == 4 ? 4 : 0);
1218     }
1219
1220   for (i = 1; i < 32; i++)
1221     {
1222       info->saved_regs[HPPA_R0_REGNUM + i].addr = off + szoff;
1223       off += incr;
1224     }
1225
1226   for (i = 0; i < ARRAY_SIZE (hppa_hpux_tramp_reg); i++)
1227     {
1228       if (hppa_hpux_tramp_reg[i] > 0)
1229         info->saved_regs[hppa_hpux_tramp_reg[i]].addr = off + szoff;
1230
1231       off += incr;
1232     }
1233
1234   /* TODO: fp regs */
1235
1236   info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
1237
1238   return info;
1239 }
1240
1241 static void
1242 hppa_hpux_sigtramp_frame_this_id (struct frame_info *next_frame,
1243                                    void **this_prologue_cache,
1244                                    struct frame_id *this_id)
1245 {
1246   struct hppa_hpux_sigtramp_unwind_cache *info
1247     = hppa_hpux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
1248   *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
1249 }
1250
1251 static void
1252 hppa_hpux_sigtramp_frame_prev_register (struct frame_info *next_frame,
1253                                         void **this_prologue_cache,
1254                                         int regnum, int *optimizedp,
1255                                         enum lval_type *lvalp, 
1256                                         CORE_ADDR *addrp,
1257                                         int *realnump, gdb_byte *valuep)
1258 {
1259   struct hppa_hpux_sigtramp_unwind_cache *info
1260     = hppa_hpux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
1261   hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
1262                                    optimizedp, lvalp, addrp, realnump, valuep);
1263 }
1264
1265 static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind = {
1266   SIGTRAMP_FRAME,
1267   hppa_hpux_sigtramp_frame_this_id,
1268   hppa_hpux_sigtramp_frame_prev_register
1269 };
1270
1271 static const struct frame_unwind *
1272 hppa_hpux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
1273 {
1274   struct unwind_table_entry *u;
1275   CORE_ADDR pc = frame_pc_unwind (next_frame);
1276
1277   u = find_unwind_entry (pc);
1278
1279   /* If this is an export stub, try to get the unwind descriptor for
1280      the actual function itself.  */
1281   if (u && u->stub_unwind.stub_type == EXPORT)
1282     {
1283       gdb_byte buf[HPPA_INSN_SIZE];
1284       unsigned long insn;
1285
1286       if (!safe_frame_unwind_memory (next_frame, u->region_start,
1287                                      buf, sizeof buf))
1288         return NULL;
1289
1290       insn = extract_unsigned_integer (buf, sizeof buf);
1291       if ((insn & 0xffe0e000) == 0xe8400000)
1292         u = find_unwind_entry(u->region_start + hppa_extract_17 (insn) + 8);
1293     }
1294
1295   if (u && u->HP_UX_interrupt_marker)
1296     return &hppa_hpux_sigtramp_frame_unwind;
1297
1298   return NULL;
1299 }
1300
1301 static CORE_ADDR
1302 hppa32_hpux_find_global_pointer (struct value *function)
1303 {
1304   CORE_ADDR faddr;
1305   
1306   faddr = value_as_address (function);
1307
1308   /* Is this a plabel? If so, dereference it to get the gp value.  */
1309   if (faddr & 2)
1310     {
1311       int status;
1312       char buf[4];
1313
1314       faddr &= ~3;
1315
1316       status = target_read_memory (faddr + 4, buf, sizeof (buf));
1317       if (status == 0)
1318         return extract_unsigned_integer (buf, sizeof (buf));
1319     }
1320
1321   return gdbarch_tdep (current_gdbarch)->solib_get_got_by_pc (faddr);
1322 }
1323
1324 static CORE_ADDR
1325 hppa64_hpux_find_global_pointer (struct value *function)
1326 {
1327   CORE_ADDR faddr;
1328   char buf[32];
1329
1330   faddr = value_as_address (function);
1331
1332   if (in_opd_section (faddr))
1333     {
1334       target_read_memory (faddr, buf, sizeof (buf));
1335       return extract_unsigned_integer (&buf[24], 8);
1336     }
1337   else
1338     {
1339       return gdbarch_tdep (current_gdbarch)->solib_get_got_by_pc (faddr);
1340     }
1341 }
1342
1343 static unsigned int ldsid_pattern[] = {
1344   0x000010a0, /* ldsid (rX),rY */
1345   0x00001820, /* mtsp rY,sr0 */
1346   0xe0000000  /* be,n (sr0,rX) */
1347 };
1348
1349 static CORE_ADDR
1350 hppa_hpux_search_pattern (CORE_ADDR start, CORE_ADDR end, 
1351                           unsigned int *patterns, int count)
1352 {
1353   int num_insns = (end - start + HPPA_INSN_SIZE) / HPPA_INSN_SIZE;
1354   unsigned int *insns;
1355   gdb_byte *buf;
1356   int offset, i;
1357
1358   buf = alloca (num_insns * HPPA_INSN_SIZE);
1359   insns = alloca (num_insns * sizeof (unsigned int));
1360
1361   read_memory (start, buf, num_insns * HPPA_INSN_SIZE);
1362   for (i = 0; i < num_insns; i++, buf += HPPA_INSN_SIZE)
1363     insns[i] = extract_unsigned_integer (buf, HPPA_INSN_SIZE);
1364
1365   for (offset = 0; offset <= num_insns - count; offset++)
1366     {
1367       for (i = 0; i < count; i++)
1368         {
1369           if ((insns[offset + i] & patterns[i]) != patterns[i])
1370             break;
1371         }
1372       if (i == count)
1373         break;
1374     }
1375
1376   if (offset <= num_insns - count)
1377     return start + offset * HPPA_INSN_SIZE;
1378   else
1379     return 0;
1380 }
1381
1382 static CORE_ADDR
1383 hppa32_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
1384                                         int *argreg)
1385 {
1386   struct objfile *obj;
1387   struct obj_section *sec;
1388   struct hppa_objfile_private *priv;
1389   struct frame_info *frame;
1390   struct unwind_table_entry *u;
1391   CORE_ADDR addr, rp;
1392   char buf[4];
1393   unsigned int insn;
1394
1395   sec = find_pc_section (pc);
1396   obj = sec->objfile;
1397   priv = objfile_data (obj, hppa_objfile_priv_data);
1398
1399   if (!priv)
1400     priv = hppa_init_objfile_priv_data (obj);
1401   if (!priv)
1402     error (_("Internal error creating objfile private data."));
1403
1404   /* Use the cached value if we have one.  */
1405   if (priv->dummy_call_sequence_addr != 0)
1406     {
1407       *argreg = priv->dummy_call_sequence_reg;
1408       return priv->dummy_call_sequence_addr;
1409     }
1410
1411   /* First try a heuristic; if we are in a shared library call, our return
1412      pointer is likely to point at an export stub.  */
1413   frame = get_current_frame ();
1414   rp = frame_unwind_register_unsigned (frame, 2);
1415   u = find_unwind_entry (rp);
1416   if (u && u->stub_unwind.stub_type == EXPORT)
1417     {
1418       addr = hppa_hpux_search_pattern (u->region_start, u->region_end, 
1419                                        ldsid_pattern, 
1420                                        ARRAY_SIZE (ldsid_pattern));
1421       if (addr)
1422         goto found_pattern;
1423     }
1424
1425   /* Next thing to try is to look for an export stub.  */
1426   if (priv->unwind_info)
1427     {
1428       int i;
1429
1430       for (i = 0; i < priv->unwind_info->last; i++)
1431         {
1432           struct unwind_table_entry *u;
1433           u = &priv->unwind_info->table[i];
1434           if (u->stub_unwind.stub_type == EXPORT)
1435             {
1436               addr = hppa_hpux_search_pattern (u->region_start, u->region_end, 
1437                                                ldsid_pattern, 
1438                                                ARRAY_SIZE (ldsid_pattern));
1439               if (addr)
1440                 {
1441                   goto found_pattern;
1442                 }
1443             }
1444         }
1445     }
1446
1447   /* Finally, if this is the main executable, try to locate a sequence 
1448      from noshlibs */
1449   addr = hppa_symbol_address ("noshlibs");
1450   sec = find_pc_section (addr);
1451
1452   if (sec && sec->objfile == obj)
1453     {
1454       CORE_ADDR start, end;
1455
1456       find_pc_partial_function (addr, NULL, &start, &end);
1457       if (start != 0 && end != 0)
1458         {
1459           addr = hppa_hpux_search_pattern (start, end, ldsid_pattern,
1460                                            ARRAY_SIZE (ldsid_pattern));
1461           if (addr)
1462             goto found_pattern;
1463         }
1464     }
1465
1466   /* Can't find a suitable sequence.  */
1467   return 0;
1468
1469 found_pattern:
1470   target_read_memory (addr, buf, sizeof (buf));
1471   insn = extract_unsigned_integer (buf, sizeof (buf));
1472   priv->dummy_call_sequence_addr = addr;
1473   priv->dummy_call_sequence_reg = (insn >> 21) & 0x1f;
1474
1475   *argreg = priv->dummy_call_sequence_reg;
1476   return priv->dummy_call_sequence_addr;
1477 }
1478
1479 static CORE_ADDR
1480 hppa64_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
1481                                         int *argreg)
1482 {
1483   struct objfile *obj;
1484   struct obj_section *sec;
1485   struct hppa_objfile_private *priv;
1486   CORE_ADDR addr;
1487   struct minimal_symbol *msym;
1488   int i;
1489
1490   sec = find_pc_section (pc);
1491   obj = sec->objfile;
1492   priv = objfile_data (obj, hppa_objfile_priv_data);
1493
1494   if (!priv)
1495     priv = hppa_init_objfile_priv_data (obj);
1496   if (!priv)
1497     error (_("Internal error creating objfile private data."));
1498
1499   /* Use the cached value if we have one.  */
1500   if (priv->dummy_call_sequence_addr != 0)
1501     {
1502       *argreg = priv->dummy_call_sequence_reg;
1503       return priv->dummy_call_sequence_addr;
1504     }
1505
1506   /* FIXME: Without stub unwind information, locating a suitable sequence is
1507      fairly difficult.  For now, we implement a very naive and inefficient
1508      scheme; try to read in blocks of code, and look for a "bve,n (rp)" 
1509      instruction.  These are likely to occur at the end of functions, so
1510      we only look at the last two instructions of each function.  */
1511   for (i = 0, msym = obj->msymbols; i < obj->minimal_symbol_count; i++, msym++)
1512     {
1513       CORE_ADDR begin, end;
1514       char *name;
1515       gdb_byte buf[2 * HPPA_INSN_SIZE];
1516       int offset;
1517
1518       find_pc_partial_function (SYMBOL_VALUE_ADDRESS (msym), &name,
1519                                 &begin, &end);
1520
1521       if (name == NULL || begin == 0 || end == 0)
1522         continue;
1523
1524       if (target_read_memory (end - sizeof (buf), buf, sizeof (buf)) == 0)
1525         {
1526           for (offset = 0; offset < sizeof (buf); offset++)
1527             {
1528               unsigned int insn;
1529
1530               insn = extract_unsigned_integer (buf + offset, HPPA_INSN_SIZE);
1531               if (insn == 0xe840d002) /* bve,n (rp) */
1532                 {
1533                   addr = (end - sizeof (buf)) + offset;
1534                   goto found_pattern;
1535                 }
1536             }
1537         }
1538     }
1539
1540   /* Can't find a suitable sequence.  */
1541   return 0;
1542
1543 found_pattern:
1544   priv->dummy_call_sequence_addr = addr;
1545   /* Right now we only look for a "bve,l (rp)" sequence, so the register is 
1546      always HPPA_RP_REGNUM.  */
1547   priv->dummy_call_sequence_reg = HPPA_RP_REGNUM;
1548
1549   *argreg = priv->dummy_call_sequence_reg;
1550   return priv->dummy_call_sequence_addr;
1551 }
1552
1553 static CORE_ADDR
1554 hppa_hpux_find_import_stub_for_addr (CORE_ADDR funcaddr)
1555 {
1556   struct objfile *objfile;
1557   struct minimal_symbol *funsym, *stubsym;
1558   CORE_ADDR stubaddr;
1559
1560   funsym = lookup_minimal_symbol_by_pc (funcaddr);
1561   stubaddr = 0;
1562
1563   ALL_OBJFILES (objfile)
1564     {
1565       stubsym = lookup_minimal_symbol_solib_trampoline
1566         (SYMBOL_LINKAGE_NAME (funsym), objfile);
1567
1568       if (stubsym)
1569         {
1570           struct unwind_table_entry *u;
1571
1572           u = find_unwind_entry (SYMBOL_VALUE (stubsym));
1573           if (u == NULL 
1574               || (u->stub_unwind.stub_type != IMPORT
1575                   && u->stub_unwind.stub_type != IMPORT_SHLIB))
1576             continue;
1577
1578           stubaddr = SYMBOL_VALUE (stubsym);
1579
1580           /* If we found an IMPORT stub, then we can stop searching;
1581              if we found an IMPORT_SHLIB, we want to continue the search
1582              in the hopes that we will find an IMPORT stub.  */
1583           if (u->stub_unwind.stub_type == IMPORT)
1584             break;
1585         }
1586     }
1587
1588   return stubaddr;
1589 }
1590
1591 static int
1592 hppa_hpux_sr_for_addr (CORE_ADDR addr)
1593 {
1594   int sr;
1595   /* The space register to use is encoded in the top 2 bits of the address.  */
1596   sr = addr >> (gdbarch_tdep (current_gdbarch)->bytes_per_address * 8 - 2);
1597   return sr + 4;
1598 }
1599
1600 static CORE_ADDR
1601 hppa_hpux_find_dummy_bpaddr (CORE_ADDR addr)
1602 {
1603   /* In order for us to restore the space register to its starting state, 
1604      we need the dummy trampoline to return to the an instruction address in 
1605      the same space as where we started the call.  We used to place the 
1606      breakpoint near the current pc, however, this breaks nested dummy calls 
1607      as the nested call will hit the breakpoint address and terminate 
1608      prematurely.  Instead, we try to look for an address in the same space to 
1609      put the breakpoint.  
1610      
1611      This is similar in spirit to putting the breakpoint at the "entry point"
1612      of an executable.  */
1613
1614   struct obj_section *sec;
1615   struct unwind_table_entry *u;
1616   struct minimal_symbol *msym;
1617   CORE_ADDR func;
1618   int i;
1619
1620   sec = find_pc_section (addr);
1621   if (sec)
1622     {
1623       /* First try the lowest address in the section; we can use it as long
1624          as it is "regular" code (i.e. not a stub) */
1625       u = find_unwind_entry (sec->addr);
1626       if (!u || u->stub_unwind.stub_type == 0)
1627         return sec->addr;
1628
1629       /* Otherwise, we need to find a symbol for a regular function.  We
1630          do this by walking the list of msymbols in the objfile.  The symbol
1631          we find should not be the same as the function that was passed in.  */
1632
1633       /* FIXME: this is broken, because we can find a function that will be
1634          called by the dummy call target function, which will still not 
1635          work.  */
1636
1637       find_pc_partial_function (addr, NULL, &func, NULL);
1638       for (i = 0, msym = sec->objfile->msymbols;
1639            i < sec->objfile->minimal_symbol_count;
1640            i++, msym++)
1641         {
1642           u = find_unwind_entry (SYMBOL_VALUE_ADDRESS (msym));
1643           if (func != SYMBOL_VALUE_ADDRESS (msym) 
1644               && (!u || u->stub_unwind.stub_type == 0))
1645             return SYMBOL_VALUE_ADDRESS (msym);
1646         }
1647     }
1648
1649   warning (_("Cannot find suitable address to place dummy breakpoint; nested "
1650              "calls may fail."));
1651   return addr - 4;
1652 }
1653
1654 static CORE_ADDR
1655 hppa_hpux_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
1656                            CORE_ADDR funcaddr, int using_gcc,
1657                            struct value **args, int nargs,
1658                            struct type *value_type,
1659                            CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
1660 {
1661   CORE_ADDR pc, stubaddr;
1662   int argreg = 0;
1663
1664   pc = read_pc ();
1665
1666   /* Note: we don't want to pass a function descriptor here; push_dummy_call
1667      fills in the PIC register for us.  */
1668   funcaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funcaddr, NULL);
1669
1670   /* The simple case is where we call a function in the same space that we are
1671      currently in; in that case we don't really need to do anything.  */
1672   if (hppa_hpux_sr_for_addr (pc) == hppa_hpux_sr_for_addr (funcaddr))
1673     {
1674       /* Intraspace call.  */
1675       *bp_addr = hppa_hpux_find_dummy_bpaddr (pc);
1676       *real_pc = funcaddr;
1677       regcache_cooked_write_unsigned (current_regcache, HPPA_RP_REGNUM, *bp_addr);
1678
1679       return sp;
1680     }
1681
1682   /* In order to make an interspace call, we need to go through a stub.
1683      gcc supplies an appropriate stub called "__gcc_plt_call", however, if
1684      an application is compiled with HP compilers then this stub is not
1685      available.  We used to fallback to "__d_plt_call", however that stub
1686      is not entirely useful for us because it doesn't do an interspace
1687      return back to the caller.  Also, on hppa64-hpux, there is no 
1688      __gcc_plt_call available.  In order to keep the code uniform, we
1689      instead don't use either of these stubs, but instead write our own
1690      onto the stack.
1691
1692      A problem arises since the stack is located in a different space than
1693      code, so in order to branch to a stack stub, we will need to do an
1694      interspace branch.  Previous versions of gdb did this by modifying code
1695      at the current pc and doing single-stepping to set the pcsq.  Since this
1696      is highly undesirable, we use a different scheme:
1697
1698      All we really need to do the branch to the stub is a short instruction
1699      sequence like this:
1700       
1701      PA1.1:
1702                 ldsid (rX),r1
1703                 mtsp r1,sr0
1704                 be,n (sr0,rX)
1705
1706      PA2.0:
1707                 bve,n (sr0,rX)
1708
1709      Instead of writing these sequences ourselves, we can find it in
1710      the instruction stream that belongs to the current space.  While this
1711      seems difficult at first, we are actually guaranteed to find the sequences
1712      in several places:
1713
1714      For 32-bit code:
1715      - in export stubs for shared libraries
1716      - in the "noshlibs" routine in the main module
1717
1718      For 64-bit code:
1719      - at the end of each "regular" function
1720
1721      We cache the address of these sequences in the objfile's private data
1722      since these operations can potentially be quite expensive.
1723
1724      So, what we do is:
1725      - write a stack trampoline
1726      - look for a suitable instruction sequence in the current space
1727      - point the sequence at the trampoline
1728      - set the return address of the trampoline to the current space 
1729        (see hppa_hpux_find_dummy_call_bpaddr)
1730      - set the continuing address of the "dummy code" as the sequence.
1731
1732 */
1733
1734   if (IS_32BIT_TARGET (gdbarch))
1735     {
1736       static unsigned int hppa32_tramp[] = {
1737         0x0fdf1291, /* stw r31,-8(,sp) */
1738         0x02c010a1, /* ldsid (,r22),r1 */
1739         0x00011820, /* mtsp r1,sr0 */
1740         0xe6c00000, /* be,l 0(sr0,r22),%sr0,%r31 */
1741         0x081f0242, /* copy r31,rp */
1742         0x0fd11082, /* ldw -8(,sp),rp */
1743         0x004010a1, /* ldsid (,rp),r1 */
1744         0x00011820, /* mtsp r1,sr0 */
1745         0xe0400000, /* be 0(sr0,rp) */
1746         0x08000240  /* nop */
1747       };
1748
1749       /* for hppa32, we must call the function through a stub so that on
1750          return it can return to the space of our trampoline.  */
1751       stubaddr = hppa_hpux_find_import_stub_for_addr (funcaddr);
1752       if (stubaddr == 0)
1753         error (_("Cannot call external function not referenced by application "
1754                "(no import stub).\n"));
1755       regcache_cooked_write_unsigned (current_regcache, 22, stubaddr);
1756
1757       write_memory (sp, (char *)&hppa32_tramp, sizeof (hppa32_tramp));
1758
1759       *bp_addr = hppa_hpux_find_dummy_bpaddr (pc);
1760       regcache_cooked_write_unsigned (current_regcache, 31, *bp_addr);
1761
1762       *real_pc = hppa32_hpux_search_dummy_call_sequence (gdbarch, pc, &argreg);
1763       if (*real_pc == 0)
1764         error (_("Cannot make interspace call from here."));
1765
1766       regcache_cooked_write_unsigned (current_regcache, argreg, sp);
1767
1768       sp += sizeof (hppa32_tramp);
1769     }
1770   else
1771     {
1772       static unsigned int hppa64_tramp[] = {
1773         0xeac0f000, /* bve,l (r22),%r2 */
1774         0x0fdf12d1, /* std r31,-8(,sp) */
1775         0x0fd110c2, /* ldd -8(,sp),rp */
1776         0xe840d002, /* bve,n (rp) */
1777         0x08000240  /* nop */
1778       };
1779
1780       /* for hppa64, we don't need to call through a stub; all functions
1781          return via a bve.  */
1782       regcache_cooked_write_unsigned (current_regcache, 22, funcaddr);
1783       write_memory (sp, (char *)&hppa64_tramp, sizeof (hppa64_tramp));
1784
1785       *bp_addr = pc - 4;
1786       regcache_cooked_write_unsigned (current_regcache, 31, *bp_addr);
1787
1788       *real_pc = hppa64_hpux_search_dummy_call_sequence (gdbarch, pc, &argreg);
1789       if (*real_pc == 0)
1790         error (_("Cannot make interspace call from here."));
1791
1792       regcache_cooked_write_unsigned (current_regcache, argreg, sp);
1793
1794       sp += sizeof (hppa64_tramp);
1795     }
1796
1797   sp = gdbarch_frame_align (gdbarch, sp);
1798
1799   return sp;
1800 }
1801
1802 \f
1803
1804 static void
1805 hppa_hpux_supply_ss_narrow (struct regcache *regcache,
1806                             int regnum, const char *save_state)
1807 {
1808   const char *ss_narrow = save_state + HPPA_HPUX_SS_NARROW_OFFSET;
1809   int i, offset = 0;
1810
1811   for (i = HPPA_R1_REGNUM; i < HPPA_FP0_REGNUM; i++)
1812     {
1813       if (regnum == i || regnum == -1)
1814         regcache_raw_supply (regcache, i, ss_narrow + offset);
1815
1816       offset += 4;
1817     }
1818 }
1819
1820 static void
1821 hppa_hpux_supply_ss_fpblock (struct regcache *regcache,
1822                              int regnum, const char *save_state)
1823 {
1824   const char *ss_fpblock = save_state + HPPA_HPUX_SS_FPBLOCK_OFFSET;
1825   int i, offset = 0;
1826
1827   /* FIXME: We view the floating-point state as 64 single-precision
1828      registers for 32-bit code, and 32 double-precision register for
1829      64-bit code.  This distinction is artificial and should be
1830      eliminated.  If that ever happens, we should remove the if-clause
1831      below.  */
1832
1833   if (register_size (get_regcache_arch (regcache), HPPA_FP0_REGNUM) == 4)
1834     {
1835       for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 64; i++)
1836         {
1837           if (regnum == i || regnum == -1)
1838             regcache_raw_supply (regcache, i, ss_fpblock + offset);
1839
1840           offset += 4;
1841         }
1842     }
1843   else
1844     {
1845       for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32; i++)
1846         {
1847           if (regnum == i || regnum == -1)
1848             regcache_raw_supply (regcache, i, ss_fpblock + offset);
1849
1850           offset += 8;
1851         }
1852     }
1853 }
1854
1855 static void
1856 hppa_hpux_supply_ss_wide (struct regcache *regcache,
1857                           int regnum, const char *save_state)
1858 {
1859   const char *ss_wide = save_state + HPPA_HPUX_SS_WIDE_OFFSET;
1860   int i, offset = 8;
1861
1862   if (register_size (get_regcache_arch (regcache), HPPA_R1_REGNUM) == 4)
1863     offset += 4;
1864
1865   for (i = HPPA_R1_REGNUM; i < HPPA_FP0_REGNUM; i++)
1866     {
1867       if (regnum == i || regnum == -1)
1868         regcache_raw_supply (regcache, i, ss_wide + offset);
1869
1870       offset += 8;
1871     }
1872 }
1873
1874 static void
1875 hppa_hpux_supply_save_state (const struct regset *regset,
1876                              struct regcache *regcache,
1877                              int regnum, const void *regs, size_t len)
1878 {
1879   const char *proc_info = regs;
1880   const char *save_state = proc_info + 8;
1881   ULONGEST flags;
1882
1883   flags = extract_unsigned_integer (save_state + HPPA_HPUX_SS_FLAGS_OFFSET, 4);
1884   if (regnum == -1 || regnum == HPPA_FLAGS_REGNUM)
1885     {
1886       struct gdbarch *arch = get_regcache_arch (regcache);
1887       size_t size = register_size (arch, HPPA_FLAGS_REGNUM);
1888       char buf[8];
1889
1890       store_unsigned_integer (buf, size, flags);
1891       regcache_raw_supply (regcache, HPPA_FLAGS_REGNUM, buf);
1892     }
1893
1894   /* If the SS_WIDEREGS flag is set, we really do need the full
1895      `struct save_state'.  */
1896   if (flags & HPPA_HPUX_SS_WIDEREGS && len < HPPA_HPUX_SAVE_STATE_SIZE)
1897     error (_("Register set contents too small"));
1898
1899   if (flags & HPPA_HPUX_SS_WIDEREGS)
1900     hppa_hpux_supply_ss_wide (regcache, regnum, save_state);
1901   else
1902     hppa_hpux_supply_ss_narrow (regcache, regnum, save_state);
1903
1904   hppa_hpux_supply_ss_fpblock (regcache, regnum, save_state);
1905 }
1906
1907 /* HP-UX register set.  */
1908
1909 static struct regset hppa_hpux_regset =
1910 {
1911   NULL,
1912   hppa_hpux_supply_save_state
1913 };
1914
1915 static const struct regset *
1916 hppa_hpux_regset_from_core_section (struct gdbarch *gdbarch,
1917                                     const char *sect_name, size_t sect_size)
1918 {
1919   if (strcmp (sect_name, ".reg") == 0
1920       && sect_size >= HPPA_HPUX_PA89_SAVE_STATE_SIZE + 8)
1921     return &hppa_hpux_regset;
1922
1923   return NULL;
1924 }
1925 \f
1926
1927 /* Bit in the `ss_flag' member of `struct save_state' that indicates
1928    the state was saved from a system call.  From
1929    <machine/save_state.h>.  */
1930 #define HPPA_HPUX_SS_INSYSCALL  0x02
1931
1932 static CORE_ADDR
1933 hppa_hpux_read_pc (ptid_t ptid)
1934 {
1935   ULONGEST flags;
1936
1937   /* If we're currently in a system call return the contents of %r31.  */
1938   flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
1939   if (flags & HPPA_HPUX_SS_INSYSCALL)
1940     return read_register_pid (HPPA_R31_REGNUM, ptid) & ~0x3;
1941
1942   return hppa_read_pc (ptid);
1943 }
1944
1945 static void
1946 hppa_hpux_write_pc (CORE_ADDR pc, ptid_t ptid)
1947 {
1948   ULONGEST flags;
1949
1950   /* If we're currently in a system call also write PC into %r31.  */
1951   flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
1952   if (flags & HPPA_HPUX_SS_INSYSCALL)
1953     write_register_pid (HPPA_R31_REGNUM, pc | 0x3, ptid);
1954
1955   return hppa_write_pc (pc, ptid);
1956 }
1957
1958 static CORE_ADDR
1959 hppa_hpux_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
1960 {
1961   ULONGEST flags;
1962
1963   /* If we're currently in a system call return the contents of %r31.  */
1964   flags = frame_unwind_register_unsigned (next_frame, HPPA_FLAGS_REGNUM);
1965   if (flags & HPPA_HPUX_SS_INSYSCALL)
1966     return frame_unwind_register_unsigned (next_frame, HPPA_R31_REGNUM) & ~0x3;
1967
1968   return hppa_unwind_pc (gdbarch, next_frame);
1969 }
1970 \f
1971
1972 static void
1973 hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty)
1974 {
1975   /* Some HP-UX related globals to clear when a new "main"
1976      symbol file is loaded.  HP-specific.  */
1977   deprecated_hp_som_som_object_present = 0;
1978   hp_cxx_exception_support_initialized = 0;
1979 }
1980
1981 /* Given the current value of the pc, check to see if it is inside a stub, and
1982    if so, change the value of the pc to point to the caller of the stub.
1983    NEXT_FRAME is the next frame in the current list of frames.
1984    BASE contains to stack frame base of the current frame. 
1985    SAVE_REGS is the register file stored in the frame cache. */
1986 static void
1987 hppa_hpux_unwind_adjust_stub (struct frame_info *next_frame, CORE_ADDR base,
1988                               struct trad_frame_saved_reg *saved_regs)
1989 {
1990   int optimized, realreg;
1991   enum lval_type lval;
1992   CORE_ADDR addr;
1993   char buffer[sizeof(ULONGEST)];
1994   ULONGEST val;
1995   CORE_ADDR stubpc;
1996   struct unwind_table_entry *u;
1997
1998   trad_frame_get_prev_register (next_frame, saved_regs, 
1999                                 HPPA_PCOQ_HEAD_REGNUM, 
2000                                 &optimized, &lval, &addr, &realreg, buffer);
2001   val = extract_unsigned_integer (buffer, 
2002                                   register_size (get_frame_arch (next_frame), 
2003                                                  HPPA_PCOQ_HEAD_REGNUM));
2004
2005   u = find_unwind_entry (val);
2006   if (u && u->stub_unwind.stub_type == EXPORT)
2007     {
2008       stubpc = read_memory_integer (base - 24, TARGET_PTR_BIT / 8);
2009       trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
2010     }
2011   else if (hppa_symbol_address ("__gcc_plt_call") 
2012            == get_pc_function_start (val))
2013     {
2014       stubpc = read_memory_integer (base - 8, TARGET_PTR_BIT / 8);
2015       trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
2016     }
2017 }
2018
2019 static void
2020 hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2021 {
2022   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2023
2024   if (IS_32BIT_TARGET (gdbarch))
2025     tdep->in_solib_call_trampoline = hppa32_hpux_in_solib_call_trampoline;
2026   else
2027     tdep->in_solib_call_trampoline = hppa64_hpux_in_solib_call_trampoline;
2028
2029   tdep->unwind_adjust_stub = hppa_hpux_unwind_adjust_stub;
2030
2031   set_gdbarch_in_solib_return_trampoline
2032     (gdbarch, hppa_hpux_in_solib_return_trampoline);
2033   set_gdbarch_skip_trampoline_code (gdbarch, hppa_hpux_skip_trampoline_code);
2034
2035   set_gdbarch_push_dummy_code (gdbarch, hppa_hpux_push_dummy_code);
2036   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
2037
2038   set_gdbarch_read_pc (gdbarch, hppa_hpux_read_pc);
2039   set_gdbarch_write_pc (gdbarch, hppa_hpux_write_pc);
2040   set_gdbarch_unwind_pc (gdbarch, hppa_hpux_unwind_pc);
2041
2042   set_gdbarch_regset_from_core_section
2043     (gdbarch, hppa_hpux_regset_from_core_section);
2044
2045   frame_unwind_append_sniffer (gdbarch, hppa_hpux_sigtramp_unwind_sniffer);
2046
2047   observer_attach_inferior_created (hppa_hpux_inferior_created);
2048 }
2049
2050 static void
2051 hppa_hpux_som_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2052 {
2053   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2054
2055   tdep->is_elf = 0;
2056
2057   tdep->find_global_pointer = hppa32_hpux_find_global_pointer;
2058
2059   hppa_hpux_init_abi (info, gdbarch);
2060   som_solib_select (tdep);
2061 }
2062
2063 static void
2064 hppa_hpux_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2065 {
2066   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2067
2068   tdep->is_elf = 1;
2069   tdep->find_global_pointer = hppa64_hpux_find_global_pointer;
2070
2071   hppa_hpux_init_abi (info, gdbarch);
2072   pa64_solib_select (tdep);
2073 }
2074
2075 static enum gdb_osabi
2076 hppa_hpux_core_osabi_sniffer (bfd *abfd)
2077 {
2078   if (strcmp (bfd_get_target (abfd), "hpux-core") == 0)
2079     return GDB_OSABI_HPUX_SOM;
2080   else if (strcmp (bfd_get_target (abfd), "elf64-hppa") == 0)
2081     {
2082       asection *section;
2083       
2084       section = bfd_get_section_by_name (abfd, ".kernel");
2085       if (section)
2086         {
2087           bfd_size_type size;
2088           char *contents;
2089
2090           size = bfd_section_size (abfd, section);
2091           contents = alloca (size);
2092           if (bfd_get_section_contents (abfd, section, contents, 
2093                                         (file_ptr) 0, size)
2094               && strcmp (contents, "HP-UX") == 0)
2095             return GDB_OSABI_HPUX_ELF;
2096         }
2097     }
2098
2099   return GDB_OSABI_UNKNOWN;
2100 }
2101
2102 void
2103 _initialize_hppa_hpux_tdep (void)
2104 {
2105   /* BFD doesn't set a flavour for HP-UX style core files.  It doesn't
2106      set the architecture either.  */
2107   gdbarch_register_osabi_sniffer (bfd_arch_unknown,
2108                                   bfd_target_unknown_flavour,
2109                                   hppa_hpux_core_osabi_sniffer);
2110   gdbarch_register_osabi_sniffer (bfd_arch_hppa,
2111                                   bfd_target_elf_flavour,
2112                                   hppa_hpux_core_osabi_sniffer);
2113
2114   gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_HPUX_SOM,
2115                           hppa_hpux_som_init_abi);
2116   gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w, GDB_OSABI_HPUX_ELF,
2117                           hppa_hpux_elf_init_abi);
2118 }