OSDN Git Service

2006-03-01 Randolph Chung <tausq@debian.org>
[pf3gnuchains/pf3gnuchains3x.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   if (!gdbarch_tdep (current_gdbarch)->is_elf)
848     {
849     /* Check whether the executable is dynamically linked or archive bound */
850     /* With an archive-bound executable we can use the raw addresses we find
851        for the callback function, etc. without modification. For an executable
852        with shared libraries, we have to do more work to find the plabel, which
853        can be the target of a call through $$dyncall from the aCC runtime 
854        support library (libCsup) which is linked shared by default by aCC. */
855     /* This test below was copied from somsolib.c/somread.c.  It may not be a very
856        reliable one to test that an executable is linked shared. 
857        pai/1997-07-18 */
858     shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
859     if (shlib_info && (bfd_section_size (symfile_objfile->obfd, shlib_info) != 0))
860       {
861         /* The minsym we have has the local code address, but that's not
862            the plabel that can be used by an inter-load-module call.  */
863         /* Find solib handle for main image (which has end.o), and use
864            that and the min sym as arguments to __d_shl_get() (which
865            does the equivalent of shl_findsym()) to find the plabel.  */
866
867         args_for_find_stub args;
868         static char message[] = _("Error while finding exception callback hook:\n");
869
870         args.solib_handle = gdbarch_tdep (current_gdbarch)->solib_get_solib_by_pc (eh_notify_callback_addr);
871         args.msym = msym;
872         args.return_val = 0;
873
874         recurse++;
875         catch_errors (cover_find_stub_with_shl_get, &args, message,
876                       RETURN_MASK_ALL);
877         eh_notify_callback_addr = args.return_val;
878         recurse--;
879
880         deprecated_exception_catchpoints_are_fragile = 1;
881
882         if (!eh_notify_callback_addr)
883           {
884             /* We can get here either if there is no plabel in the export list
885                for the main image, or if something strange happened (?) */
886             warning (_("\
887 Couldn't find a plabel (indirect function label) for the exception callback.\n\
888 GDB will not be able to intercept exception events."));
889             return 0;
890           }
891       }
892     else
893       deprecated_exception_catchpoints_are_fragile = 0;
894     }
895
896   /* Now, look for the breakpointable routine in end.o */
897   /* This should also be available in the SOM symbol dict. if end.o linked in */
898   msym = lookup_minimal_symbol (HP_ACC_EH_break, NULL, NULL);
899   if (msym)
900     {
901       eh_break_addr = SYMBOL_VALUE_ADDRESS (msym);
902       hp_cxx_exception_support = 1;
903     }
904   else
905     {
906       warning (_("\
907 Unable to find exception callback routine to set breakpoint (%s).\n\
908 Suggest linking executable with -g (link in /opt/langtools/lib/end.o).\n\
909 GDB will be unable to intercept exception events."),
910                HP_ACC_EH_break);
911       eh_break_addr = 0;
912       return 0;
913     }
914
915   /* Next look for the catch enable flag provided in end.o */
916   sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
917                        VAR_DOMAIN, 0, (struct symtab **) NULL);
918   if (sym)                      /* sometimes present in debug info */
919     {
920       eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (sym);
921       hp_cxx_exception_support = 1;
922     }
923   else
924     /* otherwise look in SOM symbol dict. */
925     {
926       msym = lookup_minimal_symbol (HP_ACC_EH_catch_catch, NULL, NULL);
927       if (msym)
928         {
929           eh_catch_catch_addr = SYMBOL_VALUE_ADDRESS (msym);
930           hp_cxx_exception_support = 1;
931         }
932       else
933         {
934           warning (_("\
935 Unable to enable interception of exception catches.\n\
936 Executable may not have been compiled debuggable with HP aCC.\n\
937 Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
938           return 0;
939         }
940     }
941
942   /* Next look for the catch enable flag provided end.o */
943   sym = lookup_symbol (HP_ACC_EH_catch_catch, (struct block *) NULL,
944                        VAR_DOMAIN, 0, (struct symtab **) NULL);
945   if (sym)                      /* sometimes present in debug info */
946     {
947       eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (sym);
948       hp_cxx_exception_support = 1;
949     }
950   else
951     /* otherwise look in SOM symbol dict. */
952     {
953       msym = lookup_minimal_symbol (HP_ACC_EH_catch_throw, NULL, NULL);
954       if (msym)
955         {
956           eh_catch_throw_addr = SYMBOL_VALUE_ADDRESS (msym);
957           hp_cxx_exception_support = 1;
958         }
959       else
960         {
961           warning (_("\
962 Unable to enable interception of exception throws.\n\
963 Executable may not have been compiled debuggable with HP aCC.\n\
964 Suggest linking executable with -g (link in /opt/langtools/lib/end.o)."));
965           return 0;
966         }
967     }
968
969   /* Set the flags */
970   hp_cxx_exception_support = 2; /* everything worked so far */
971   hp_cxx_exception_support_initialized = 1;
972   deprecated_exception_support_initialized = 1;
973
974   return 1;
975 }
976
977 /* Target operation for enabling or disabling interception of
978    exception events.
979    KIND is either EX_EVENT_THROW or EX_EVENT_CATCH
980    ENABLE is either 0 (disable) or 1 (enable).
981    Return value is NULL if no support found;
982    -1 if something went wrong,
983    or a pointer to a symtab/line struct if the breakpointable
984    address was found. */
985
986 struct symtab_and_line *
987 child_enable_exception_callback (enum exception_event_kind kind, int enable)
988 {
989   char buf[4];
990
991   if (!deprecated_exception_support_initialized
992       || !hp_cxx_exception_support_initialized)
993     if (!initialize_hp_cxx_exception_support ())
994       return NULL;
995
996   switch (hp_cxx_exception_support)
997     {
998     case 0:
999       /* Assuming no HP support at all */
1000       return NULL;
1001     case 1:
1002       /* HP support should be present, but something went wrong */
1003       return (struct symtab_and_line *) -1;     /* yuck! */
1004       /* there may be other cases in the future */
1005     }
1006
1007   /* Set the EH hook to point to the callback routine.  */
1008   store_unsigned_integer (buf, 4, enable ? eh_notify_callback_addr : 0);        /* FIXME 32x64 problem */
1009   /* pai: (temp) FIXME should there be a pack operation first? */
1010   if (target_write_memory (eh_notify_hook_addr, buf, 4))        /* FIXME 32x64 problem */
1011     {
1012       warning (_("\
1013 Could not write to target memory for exception event callback.\n\
1014 Interception of exception events may not work."));
1015       return (struct symtab_and_line *) -1;
1016     }
1017   if (enable)
1018     {
1019       /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
1020       if (PIDGET (inferior_ptid) > 0)
1021         {
1022           if (setup_d_pid_in_inferior ())
1023             return (struct symtab_and_line *) -1;
1024         }
1025       else
1026         {
1027           warning (_("Internal error: Invalid inferior pid?  Cannot intercept exception events."));
1028           return (struct symtab_and_line *) -1;
1029         }
1030     }
1031
1032   switch (kind)
1033     {
1034     case EX_EVENT_THROW:
1035       store_unsigned_integer (buf, 4, enable ? 1 : 0);
1036       if (target_write_memory (eh_catch_throw_addr, buf, 4))    /* FIXME 32x64? */
1037         {
1038           warning (_("Couldn't enable exception throw interception."));
1039           return (struct symtab_and_line *) -1;
1040         }
1041       break;
1042     case EX_EVENT_CATCH:
1043       store_unsigned_integer (buf, 4, enable ? 1 : 0);
1044       if (target_write_memory (eh_catch_catch_addr, buf, 4))    /* FIXME 32x64? */
1045         {
1046           warning (_("Couldn't enable exception catch interception."));
1047           return (struct symtab_and_line *) -1;
1048         }
1049       break;
1050     default:
1051       error (_("Request to enable unknown or unsupported exception event."));
1052     }
1053
1054   /* Copy break address into new sal struct, malloc'ing if needed.  */
1055   if (!break_callback_sal)
1056     break_callback_sal = XMALLOC (struct symtab_and_line);
1057   init_sal (break_callback_sal);
1058   break_callback_sal->symtab = NULL;
1059   break_callback_sal->pc = eh_break_addr;
1060   break_callback_sal->line = 0;
1061   break_callback_sal->end = eh_break_addr;
1062
1063   return break_callback_sal;
1064 }
1065
1066 /* Record some information about the current exception event */
1067 static struct exception_event_record current_ex_event;
1068
1069 /* Report current exception event.  Returns a pointer to a record
1070    that describes the kind of the event, where it was thrown from,
1071    and where it will be caught.  More information may be reported
1072    in the future */
1073 struct exception_event_record *
1074 child_get_current_exception_event (void)
1075 {
1076   CORE_ADDR event_kind;
1077   CORE_ADDR throw_addr;
1078   CORE_ADDR catch_addr;
1079   struct frame_info *fi, *curr_frame;
1080   int level = 1;
1081
1082   curr_frame = get_current_frame ();
1083   if (!curr_frame)
1084     return (struct exception_event_record *) NULL;
1085
1086   /* Go up one frame to __d_eh_notify_callback, because at the
1087      point when this code is executed, there's garbage in the
1088      arguments of __d_eh_break. */
1089   fi = find_relative_frame (curr_frame, &level);
1090   if (level != 0)
1091     return (struct exception_event_record *) NULL;
1092
1093   select_frame (fi);
1094
1095   /* Read in the arguments */
1096   /* __d_eh_notify_callback() is called with 3 arguments:
1097      1. event kind catch or throw
1098      2. the target address if known
1099      3. a flag -- not sure what this is. pai/1997-07-17 */
1100   event_kind = read_register (HPPA_ARG0_REGNUM);
1101   catch_addr = read_register (HPPA_ARG1_REGNUM);
1102
1103   /* Now go down to a user frame */
1104   /* For a throw, __d_eh_break is called by
1105      __d_eh_notify_callback which is called by
1106      __notify_throw which is called
1107      from user code.
1108      For a catch, __d_eh_break is called by
1109      __d_eh_notify_callback which is called by
1110      <stackwalking stuff> which is called by
1111      __throw__<stuff> or __rethrow_<stuff> which is called
1112      from user code. */
1113   /* FIXME: Don't use such magic numbers; search for the frames */
1114   level = (event_kind == EX_EVENT_THROW) ? 3 : 4;
1115   fi = find_relative_frame (curr_frame, &level);
1116   if (level != 0)
1117     return (struct exception_event_record *) NULL;
1118
1119   select_frame (fi);
1120   throw_addr = get_frame_pc (fi);
1121
1122   /* Go back to original (top) frame */
1123   select_frame (curr_frame);
1124
1125   current_ex_event.kind = (enum exception_event_kind) event_kind;
1126   current_ex_event.throw_sal = find_pc_line (throw_addr, 1);
1127   current_ex_event.catch_sal = find_pc_line (catch_addr, 1);
1128
1129   return &current_ex_event;
1130 }
1131
1132 /* Signal frames.  */
1133 struct hppa_hpux_sigtramp_unwind_cache
1134 {
1135   CORE_ADDR base;
1136   struct trad_frame_saved_reg *saved_regs;
1137 };
1138
1139 static int hppa_hpux_tramp_reg[] = {
1140   HPPA_SAR_REGNUM,
1141   HPPA_PCOQ_HEAD_REGNUM,
1142   HPPA_PCSQ_HEAD_REGNUM,
1143   HPPA_PCOQ_TAIL_REGNUM,
1144   HPPA_PCSQ_TAIL_REGNUM,
1145   HPPA_EIEM_REGNUM,
1146   HPPA_IIR_REGNUM,
1147   HPPA_ISR_REGNUM,
1148   HPPA_IOR_REGNUM,
1149   HPPA_IPSW_REGNUM,
1150   -1,
1151   HPPA_SR4_REGNUM,
1152   HPPA_SR4_REGNUM + 1,
1153   HPPA_SR4_REGNUM + 2,
1154   HPPA_SR4_REGNUM + 3,
1155   HPPA_SR4_REGNUM + 4,
1156   HPPA_SR4_REGNUM + 5,
1157   HPPA_SR4_REGNUM + 6,
1158   HPPA_SR4_REGNUM + 7,
1159   HPPA_RCR_REGNUM,
1160   HPPA_PID0_REGNUM,
1161   HPPA_PID1_REGNUM,
1162   HPPA_CCR_REGNUM,
1163   HPPA_PID2_REGNUM,
1164   HPPA_PID3_REGNUM,
1165   HPPA_TR0_REGNUM,
1166   HPPA_TR0_REGNUM + 1,
1167   HPPA_TR0_REGNUM + 2,
1168   HPPA_CR27_REGNUM
1169 };
1170
1171 static struct hppa_hpux_sigtramp_unwind_cache *
1172 hppa_hpux_sigtramp_frame_unwind_cache (struct frame_info *next_frame,
1173                                        void **this_cache)
1174
1175 {
1176   struct gdbarch *gdbarch = get_frame_arch (next_frame);
1177   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
1178   struct hppa_hpux_sigtramp_unwind_cache *info;
1179   unsigned int flag;
1180   CORE_ADDR sp, scptr, off;
1181   int i, incr, szoff;
1182
1183   if (*this_cache)
1184     return *this_cache;
1185
1186   info = FRAME_OBSTACK_ZALLOC (struct hppa_hpux_sigtramp_unwind_cache);
1187   *this_cache = info;
1188   info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
1189
1190   sp = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
1191
1192   if (IS_32BIT_TARGET (gdbarch))
1193     scptr = sp - 1352;
1194   else
1195     scptr = sp - 1520;
1196
1197   off = scptr;
1198
1199   /* See /usr/include/machine/save_state.h for the structure of the save_state_t
1200      structure. */
1201   
1202   flag = read_memory_unsigned_integer(scptr + HPPA_HPUX_SS_FLAGS_OFFSET, 4);
1203
1204   if (!(flag & HPPA_HPUX_SS_WIDEREGS))
1205     {
1206       /* Narrow registers. */
1207       off = scptr + HPPA_HPUX_SS_NARROW_OFFSET;
1208       incr = 4;
1209       szoff = 0;
1210     }
1211   else
1212     {
1213       /* Wide registers. */
1214       off = scptr + HPPA_HPUX_SS_WIDE_OFFSET + 8;
1215       incr = 8;
1216       szoff = (tdep->bytes_per_address == 4 ? 4 : 0);
1217     }
1218
1219   for (i = 1; i < 32; i++)
1220     {
1221       info->saved_regs[HPPA_R0_REGNUM + i].addr = off + szoff;
1222       off += incr;
1223     }
1224
1225   for (i = 0; i < ARRAY_SIZE (hppa_hpux_tramp_reg); i++)
1226     {
1227       if (hppa_hpux_tramp_reg[i] > 0)
1228         info->saved_regs[hppa_hpux_tramp_reg[i]].addr = off + szoff;
1229
1230       off += incr;
1231     }
1232
1233   /* TODO: fp regs */
1234
1235   info->base = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM);
1236
1237   return info;
1238 }
1239
1240 static void
1241 hppa_hpux_sigtramp_frame_this_id (struct frame_info *next_frame,
1242                                    void **this_prologue_cache,
1243                                    struct frame_id *this_id)
1244 {
1245   struct hppa_hpux_sigtramp_unwind_cache *info
1246     = hppa_hpux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
1247   *this_id = frame_id_build (info->base, frame_pc_unwind (next_frame));
1248 }
1249
1250 static void
1251 hppa_hpux_sigtramp_frame_prev_register (struct frame_info *next_frame,
1252                                         void **this_prologue_cache,
1253                                         int regnum, int *optimizedp,
1254                                         enum lval_type *lvalp, 
1255                                         CORE_ADDR *addrp,
1256                                         int *realnump, gdb_byte *valuep)
1257 {
1258   struct hppa_hpux_sigtramp_unwind_cache *info
1259     = hppa_hpux_sigtramp_frame_unwind_cache (next_frame, this_prologue_cache);
1260   hppa_frame_prev_register_helper (next_frame, info->saved_regs, regnum,
1261                                    optimizedp, lvalp, addrp, realnump, valuep);
1262 }
1263
1264 static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind = {
1265   SIGTRAMP_FRAME,
1266   hppa_hpux_sigtramp_frame_this_id,
1267   hppa_hpux_sigtramp_frame_prev_register
1268 };
1269
1270 static const struct frame_unwind *
1271 hppa_hpux_sigtramp_unwind_sniffer (struct frame_info *next_frame)
1272 {
1273   struct unwind_table_entry *u;
1274   CORE_ADDR pc = frame_pc_unwind (next_frame);
1275
1276   u = find_unwind_entry (pc);
1277
1278   /* If this is an export stub, try to get the unwind descriptor for
1279      the actual function itself.  */
1280   if (u && u->stub_unwind.stub_type == EXPORT)
1281     {
1282       gdb_byte buf[HPPA_INSN_SIZE];
1283       unsigned long insn;
1284
1285       if (!safe_frame_unwind_memory (next_frame, u->region_start,
1286                                      buf, sizeof buf))
1287         return NULL;
1288
1289       insn = extract_unsigned_integer (buf, sizeof buf);
1290       if ((insn & 0xffe0e000) == 0xe8400000)
1291         u = find_unwind_entry(u->region_start + hppa_extract_17 (insn) + 8);
1292     }
1293
1294   if (u && u->HP_UX_interrupt_marker)
1295     return &hppa_hpux_sigtramp_frame_unwind;
1296
1297   return NULL;
1298 }
1299
1300 static CORE_ADDR
1301 hppa32_hpux_find_global_pointer (struct value *function)
1302 {
1303   CORE_ADDR faddr;
1304   
1305   faddr = value_as_address (function);
1306
1307   /* Is this a plabel? If so, dereference it to get the gp value.  */
1308   if (faddr & 2)
1309     {
1310       int status;
1311       char buf[4];
1312
1313       faddr &= ~3;
1314
1315       status = target_read_memory (faddr + 4, buf, sizeof (buf));
1316       if (status == 0)
1317         return extract_unsigned_integer (buf, sizeof (buf));
1318     }
1319
1320   return gdbarch_tdep (current_gdbarch)->solib_get_got_by_pc (faddr);
1321 }
1322
1323 static CORE_ADDR
1324 hppa64_hpux_find_global_pointer (struct value *function)
1325 {
1326   CORE_ADDR faddr;
1327   char buf[32];
1328
1329   faddr = value_as_address (function);
1330
1331   if (in_opd_section (faddr))
1332     {
1333       target_read_memory (faddr, buf, sizeof (buf));
1334       return extract_unsigned_integer (&buf[24], 8);
1335     }
1336   else
1337     {
1338       return gdbarch_tdep (current_gdbarch)->solib_get_got_by_pc (faddr);
1339     }
1340 }
1341
1342 static unsigned int ldsid_pattern[] = {
1343   0x000010a0, /* ldsid (rX),rY */
1344   0x00001820, /* mtsp rY,sr0 */
1345   0xe0000000  /* be,n (sr0,rX) */
1346 };
1347
1348 static CORE_ADDR
1349 hppa_hpux_search_pattern (CORE_ADDR start, CORE_ADDR end, 
1350                           unsigned int *patterns, int count)
1351 {
1352   int num_insns = (end - start + HPPA_INSN_SIZE) / HPPA_INSN_SIZE;
1353   unsigned int *insns;
1354   gdb_byte *buf;
1355   int offset, i;
1356
1357   buf = alloca (num_insns * HPPA_INSN_SIZE);
1358   insns = alloca (num_insns * sizeof (unsigned int));
1359
1360   read_memory (start, buf, num_insns * HPPA_INSN_SIZE);
1361   for (i = 0; i < num_insns; i++, buf += HPPA_INSN_SIZE)
1362     insns[i] = extract_unsigned_integer (buf, HPPA_INSN_SIZE);
1363
1364   for (offset = 0; offset <= num_insns - count; offset++)
1365     {
1366       for (i = 0; i < count; i++)
1367         {
1368           if ((insns[offset + i] & patterns[i]) != patterns[i])
1369             break;
1370         }
1371       if (i == count)
1372         break;
1373     }
1374
1375   if (offset <= num_insns - count)
1376     return start + offset * HPPA_INSN_SIZE;
1377   else
1378     return 0;
1379 }
1380
1381 static CORE_ADDR
1382 hppa32_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
1383                                         int *argreg)
1384 {
1385   struct objfile *obj;
1386   struct obj_section *sec;
1387   struct hppa_objfile_private *priv;
1388   struct frame_info *frame;
1389   struct unwind_table_entry *u;
1390   CORE_ADDR addr, rp;
1391   char buf[4];
1392   unsigned int insn;
1393
1394   sec = find_pc_section (pc);
1395   obj = sec->objfile;
1396   priv = objfile_data (obj, hppa_objfile_priv_data);
1397
1398   if (!priv)
1399     priv = hppa_init_objfile_priv_data (obj);
1400   if (!priv)
1401     error (_("Internal error creating objfile private data."));
1402
1403   /* Use the cached value if we have one.  */
1404   if (priv->dummy_call_sequence_addr != 0)
1405     {
1406       *argreg = priv->dummy_call_sequence_reg;
1407       return priv->dummy_call_sequence_addr;
1408     }
1409
1410   /* First try a heuristic; if we are in a shared library call, our return
1411      pointer is likely to point at an export stub.  */
1412   frame = get_current_frame ();
1413   rp = frame_unwind_register_unsigned (frame, 2);
1414   u = find_unwind_entry (rp);
1415   if (u && u->stub_unwind.stub_type == EXPORT)
1416     {
1417       addr = hppa_hpux_search_pattern (u->region_start, u->region_end, 
1418                                        ldsid_pattern, 
1419                                        ARRAY_SIZE (ldsid_pattern));
1420       if (addr)
1421         goto found_pattern;
1422     }
1423
1424   /* Next thing to try is to look for an export stub.  */
1425   if (priv->unwind_info)
1426     {
1427       int i;
1428
1429       for (i = 0; i < priv->unwind_info->last; i++)
1430         {
1431           struct unwind_table_entry *u;
1432           u = &priv->unwind_info->table[i];
1433           if (u->stub_unwind.stub_type == EXPORT)
1434             {
1435               addr = hppa_hpux_search_pattern (u->region_start, u->region_end, 
1436                                                ldsid_pattern, 
1437                                                ARRAY_SIZE (ldsid_pattern));
1438               if (addr)
1439                 {
1440                   goto found_pattern;
1441                 }
1442             }
1443         }
1444     }
1445
1446   /* Finally, if this is the main executable, try to locate a sequence 
1447      from noshlibs */
1448   addr = hppa_symbol_address ("noshlibs");
1449   sec = find_pc_section (addr);
1450
1451   if (sec && sec->objfile == obj)
1452     {
1453       CORE_ADDR start, end;
1454
1455       find_pc_partial_function (addr, NULL, &start, &end);
1456       if (start != 0 && end != 0)
1457         {
1458           addr = hppa_hpux_search_pattern (start, end, ldsid_pattern,
1459                                            ARRAY_SIZE (ldsid_pattern));
1460           if (addr)
1461             goto found_pattern;
1462         }
1463     }
1464
1465   /* Can't find a suitable sequence.  */
1466   return 0;
1467
1468 found_pattern:
1469   target_read_memory (addr, buf, sizeof (buf));
1470   insn = extract_unsigned_integer (buf, sizeof (buf));
1471   priv->dummy_call_sequence_addr = addr;
1472   priv->dummy_call_sequence_reg = (insn >> 21) & 0x1f;
1473
1474   *argreg = priv->dummy_call_sequence_reg;
1475   return priv->dummy_call_sequence_addr;
1476 }
1477
1478 static CORE_ADDR
1479 hppa64_hpux_search_dummy_call_sequence (struct gdbarch *gdbarch, CORE_ADDR pc,
1480                                         int *argreg)
1481 {
1482   struct objfile *obj;
1483   struct obj_section *sec;
1484   struct hppa_objfile_private *priv;
1485   CORE_ADDR addr;
1486   struct minimal_symbol *msym;
1487   int i;
1488
1489   sec = find_pc_section (pc);
1490   obj = sec->objfile;
1491   priv = objfile_data (obj, hppa_objfile_priv_data);
1492
1493   if (!priv)
1494     priv = hppa_init_objfile_priv_data (obj);
1495   if (!priv)
1496     error (_("Internal error creating objfile private data."));
1497
1498   /* Use the cached value if we have one.  */
1499   if (priv->dummy_call_sequence_addr != 0)
1500     {
1501       *argreg = priv->dummy_call_sequence_reg;
1502       return priv->dummy_call_sequence_addr;
1503     }
1504
1505   /* FIXME: Without stub unwind information, locating a suitable sequence is
1506      fairly difficult.  For now, we implement a very naive and inefficient
1507      scheme; try to read in blocks of code, and look for a "bve,n (rp)" 
1508      instruction.  These are likely to occur at the end of functions, so
1509      we only look at the last two instructions of each function.  */
1510   for (i = 0, msym = obj->msymbols; i < obj->minimal_symbol_count; i++, msym++)
1511     {
1512       CORE_ADDR begin, end;
1513       char *name;
1514       gdb_byte buf[2 * HPPA_INSN_SIZE];
1515       int offset;
1516
1517       find_pc_partial_function (SYMBOL_VALUE_ADDRESS (msym), &name,
1518                                 &begin, &end);
1519
1520       if (name == NULL || begin == 0 || end == 0)
1521         continue;
1522
1523       if (target_read_memory (end - sizeof (buf), buf, sizeof (buf)) == 0)
1524         {
1525           for (offset = 0; offset < sizeof (buf); offset++)
1526             {
1527               unsigned int insn;
1528
1529               insn = extract_unsigned_integer (buf + offset, HPPA_INSN_SIZE);
1530               if (insn == 0xe840d002) /* bve,n (rp) */
1531                 {
1532                   addr = (end - sizeof (buf)) + offset;
1533                   goto found_pattern;
1534                 }
1535             }
1536         }
1537     }
1538
1539   /* Can't find a suitable sequence.  */
1540   return 0;
1541
1542 found_pattern:
1543   priv->dummy_call_sequence_addr = addr;
1544   /* Right now we only look for a "bve,l (rp)" sequence, so the register is 
1545      always HPPA_RP_REGNUM.  */
1546   priv->dummy_call_sequence_reg = HPPA_RP_REGNUM;
1547
1548   *argreg = priv->dummy_call_sequence_reg;
1549   return priv->dummy_call_sequence_addr;
1550 }
1551
1552 static CORE_ADDR
1553 hppa_hpux_find_import_stub_for_addr (CORE_ADDR funcaddr)
1554 {
1555   struct objfile *objfile;
1556   struct minimal_symbol *funsym, *stubsym;
1557   CORE_ADDR stubaddr;
1558
1559   funsym = lookup_minimal_symbol_by_pc (funcaddr);
1560   stubaddr = 0;
1561
1562   ALL_OBJFILES (objfile)
1563     {
1564       stubsym = lookup_minimal_symbol_solib_trampoline
1565         (SYMBOL_LINKAGE_NAME (funsym), objfile);
1566
1567       if (stubsym)
1568         {
1569           struct unwind_table_entry *u;
1570
1571           u = find_unwind_entry (SYMBOL_VALUE (stubsym));
1572           if (u == NULL 
1573               || (u->stub_unwind.stub_type != IMPORT
1574                   && u->stub_unwind.stub_type != IMPORT_SHLIB))
1575             continue;
1576
1577           stubaddr = SYMBOL_VALUE (stubsym);
1578
1579           /* If we found an IMPORT stub, then we can stop searching;
1580              if we found an IMPORT_SHLIB, we want to continue the search
1581              in the hopes that we will find an IMPORT stub.  */
1582           if (u->stub_unwind.stub_type == IMPORT)
1583             break;
1584         }
1585     }
1586
1587   return stubaddr;
1588 }
1589
1590 static int
1591 hppa_hpux_sr_for_addr (CORE_ADDR addr)
1592 {
1593   int sr;
1594   /* The space register to use is encoded in the top 2 bits of the address.  */
1595   sr = addr >> (gdbarch_tdep (current_gdbarch)->bytes_per_address * 8 - 2);
1596   return sr + 4;
1597 }
1598
1599 static CORE_ADDR
1600 hppa_hpux_find_dummy_bpaddr (CORE_ADDR addr)
1601 {
1602   /* In order for us to restore the space register to its starting state, 
1603      we need the dummy trampoline to return to the an instruction address in 
1604      the same space as where we started the call.  We used to place the 
1605      breakpoint near the current pc, however, this breaks nested dummy calls 
1606      as the nested call will hit the breakpoint address and terminate 
1607      prematurely.  Instead, we try to look for an address in the same space to 
1608      put the breakpoint.  
1609      
1610      This is similar in spirit to putting the breakpoint at the "entry point"
1611      of an executable.  */
1612
1613   struct obj_section *sec;
1614   struct unwind_table_entry *u;
1615   struct minimal_symbol *msym;
1616   CORE_ADDR func;
1617   int i;
1618
1619   sec = find_pc_section (addr);
1620   if (sec)
1621     {
1622       /* First try the lowest address in the section; we can use it as long
1623          as it is "regular" code (i.e. not a stub) */
1624       u = find_unwind_entry (sec->addr);
1625       if (!u || u->stub_unwind.stub_type == 0)
1626         return sec->addr;
1627
1628       /* Otherwise, we need to find a symbol for a regular function.  We
1629          do this by walking the list of msymbols in the objfile.  The symbol
1630          we find should not be the same as the function that was passed in.  */
1631
1632       /* FIXME: this is broken, because we can find a function that will be
1633          called by the dummy call target function, which will still not 
1634          work.  */
1635
1636       find_pc_partial_function (addr, NULL, &func, NULL);
1637       for (i = 0, msym = sec->objfile->msymbols;
1638            i < sec->objfile->minimal_symbol_count;
1639            i++, msym++)
1640         {
1641           u = find_unwind_entry (SYMBOL_VALUE_ADDRESS (msym));
1642           if (func != SYMBOL_VALUE_ADDRESS (msym) 
1643               && (!u || u->stub_unwind.stub_type == 0))
1644             return SYMBOL_VALUE_ADDRESS (msym);
1645         }
1646     }
1647
1648   warning (_("Cannot find suitable address to place dummy breakpoint; nested "
1649              "calls may fail."));
1650   return addr - 4;
1651 }
1652
1653 static CORE_ADDR
1654 hppa_hpux_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
1655                            CORE_ADDR funcaddr, int using_gcc,
1656                            struct value **args, int nargs,
1657                            struct type *value_type,
1658                            CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
1659 {
1660   CORE_ADDR pc, stubaddr;
1661   int argreg = 0;
1662
1663   pc = read_pc ();
1664
1665   /* Note: we don't want to pass a function descriptor here; push_dummy_call
1666      fills in the PIC register for us.  */
1667   funcaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funcaddr, NULL);
1668
1669   /* The simple case is where we call a function in the same space that we are
1670      currently in; in that case we don't really need to do anything.  */
1671   if (hppa_hpux_sr_for_addr (pc) == hppa_hpux_sr_for_addr (funcaddr))
1672     {
1673       /* Intraspace call.  */
1674       *bp_addr = hppa_hpux_find_dummy_bpaddr (pc);
1675       *real_pc = funcaddr;
1676       regcache_cooked_write_unsigned (current_regcache, HPPA_RP_REGNUM, *bp_addr);
1677
1678       return sp;
1679     }
1680
1681   /* In order to make an interspace call, we need to go through a stub.
1682      gcc supplies an appropriate stub called "__gcc_plt_call", however, if
1683      an application is compiled with HP compilers then this stub is not
1684      available.  We used to fallback to "__d_plt_call", however that stub
1685      is not entirely useful for us because it doesn't do an interspace
1686      return back to the caller.  Also, on hppa64-hpux, there is no 
1687      __gcc_plt_call available.  In order to keep the code uniform, we
1688      instead don't use either of these stubs, but instead write our own
1689      onto the stack.
1690
1691      A problem arises since the stack is located in a different space than
1692      code, so in order to branch to a stack stub, we will need to do an
1693      interspace branch.  Previous versions of gdb did this by modifying code
1694      at the current pc and doing single-stepping to set the pcsq.  Since this
1695      is highly undesirable, we use a different scheme:
1696
1697      All we really need to do the branch to the stub is a short instruction
1698      sequence like this:
1699       
1700      PA1.1:
1701                 ldsid (rX),r1
1702                 mtsp r1,sr0
1703                 be,n (sr0,rX)
1704
1705      PA2.0:
1706                 bve,n (sr0,rX)
1707
1708      Instead of writing these sequences ourselves, we can find it in
1709      the instruction stream that belongs to the current space.  While this
1710      seems difficult at first, we are actually guaranteed to find the sequences
1711      in several places:
1712
1713      For 32-bit code:
1714      - in export stubs for shared libraries
1715      - in the "noshlibs" routine in the main module
1716
1717      For 64-bit code:
1718      - at the end of each "regular" function
1719
1720      We cache the address of these sequences in the objfile's private data
1721      since these operations can potentially be quite expensive.
1722
1723      So, what we do is:
1724      - write a stack trampoline
1725      - look for a suitable instruction sequence in the current space
1726      - point the sequence at the trampoline
1727      - set the return address of the trampoline to the current space 
1728        (see hppa_hpux_find_dummy_call_bpaddr)
1729      - set the continuing address of the "dummy code" as the sequence.
1730
1731 */
1732
1733   if (IS_32BIT_TARGET (gdbarch))
1734     {
1735       static unsigned int hppa32_tramp[] = {
1736         0x0fdf1291, /* stw r31,-8(,sp) */
1737         0x02c010a1, /* ldsid (,r22),r1 */
1738         0x00011820, /* mtsp r1,sr0 */
1739         0xe6c00000, /* be,l 0(sr0,r22),%sr0,%r31 */
1740         0x081f0242, /* copy r31,rp */
1741         0x0fd11082, /* ldw -8(,sp),rp */
1742         0x004010a1, /* ldsid (,rp),r1 */
1743         0x00011820, /* mtsp r1,sr0 */
1744         0xe0400000, /* be 0(sr0,rp) */
1745         0x08000240  /* nop */
1746       };
1747
1748       /* for hppa32, we must call the function through a stub so that on
1749          return it can return to the space of our trampoline.  */
1750       stubaddr = hppa_hpux_find_import_stub_for_addr (funcaddr);
1751       if (stubaddr == 0)
1752         error (_("Cannot call external function not referenced by application "
1753                "(no import stub).\n"));
1754       regcache_cooked_write_unsigned (current_regcache, 22, stubaddr);
1755
1756       write_memory (sp, (char *)&hppa32_tramp, sizeof (hppa32_tramp));
1757
1758       *bp_addr = hppa_hpux_find_dummy_bpaddr (pc);
1759       regcache_cooked_write_unsigned (current_regcache, 31, *bp_addr);
1760
1761       *real_pc = hppa32_hpux_search_dummy_call_sequence (gdbarch, pc, &argreg);
1762       if (*real_pc == 0)
1763         error (_("Cannot make interspace call from here."));
1764
1765       regcache_cooked_write_unsigned (current_regcache, argreg, sp);
1766
1767       sp += sizeof (hppa32_tramp);
1768     }
1769   else
1770     {
1771       static unsigned int hppa64_tramp[] = {
1772         0xeac0f000, /* bve,l (r22),%r2 */
1773         0x0fdf12d1, /* std r31,-8(,sp) */
1774         0x0fd110c2, /* ldd -8(,sp),rp */
1775         0xe840d002, /* bve,n (rp) */
1776         0x08000240  /* nop */
1777       };
1778
1779       /* for hppa64, we don't need to call through a stub; all functions
1780          return via a bve.  */
1781       regcache_cooked_write_unsigned (current_regcache, 22, funcaddr);
1782       write_memory (sp, (char *)&hppa64_tramp, sizeof (hppa64_tramp));
1783
1784       *bp_addr = pc - 4;
1785       regcache_cooked_write_unsigned (current_regcache, 31, *bp_addr);
1786
1787       *real_pc = hppa64_hpux_search_dummy_call_sequence (gdbarch, pc, &argreg);
1788       if (*real_pc == 0)
1789         error (_("Cannot make interspace call from here."));
1790
1791       regcache_cooked_write_unsigned (current_regcache, argreg, sp);
1792
1793       sp += sizeof (hppa64_tramp);
1794     }
1795
1796   sp = gdbarch_frame_align (gdbarch, sp);
1797
1798   return sp;
1799 }
1800
1801 \f
1802
1803 static void
1804 hppa_hpux_supply_ss_narrow (struct regcache *regcache,
1805                             int regnum, const char *save_state)
1806 {
1807   const char *ss_narrow = save_state + HPPA_HPUX_SS_NARROW_OFFSET;
1808   int i, offset = 0;
1809
1810   for (i = HPPA_R1_REGNUM; i < HPPA_FP0_REGNUM; i++)
1811     {
1812       if (regnum == i || regnum == -1)
1813         regcache_raw_supply (regcache, i, ss_narrow + offset);
1814
1815       offset += 4;
1816     }
1817 }
1818
1819 static void
1820 hppa_hpux_supply_ss_fpblock (struct regcache *regcache,
1821                              int regnum, const char *save_state)
1822 {
1823   const char *ss_fpblock = save_state + HPPA_HPUX_SS_FPBLOCK_OFFSET;
1824   int i, offset = 0;
1825
1826   /* FIXME: We view the floating-point state as 64 single-precision
1827      registers for 32-bit code, and 32 double-precision register for
1828      64-bit code.  This distinction is artificial and should be
1829      eliminated.  If that ever happens, we should remove the if-clause
1830      below.  */
1831
1832   if (register_size (get_regcache_arch (regcache), HPPA_FP0_REGNUM) == 4)
1833     {
1834       for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 64; i++)
1835         {
1836           if (regnum == i || regnum == -1)
1837             regcache_raw_supply (regcache, i, ss_fpblock + offset);
1838
1839           offset += 4;
1840         }
1841     }
1842   else
1843     {
1844       for (i = HPPA_FP0_REGNUM; i < HPPA_FP0_REGNUM + 32; i++)
1845         {
1846           if (regnum == i || regnum == -1)
1847             regcache_raw_supply (regcache, i, ss_fpblock + offset);
1848
1849           offset += 8;
1850         }
1851     }
1852 }
1853
1854 static void
1855 hppa_hpux_supply_ss_wide (struct regcache *regcache,
1856                           int regnum, const char *save_state)
1857 {
1858   const char *ss_wide = save_state + HPPA_HPUX_SS_WIDE_OFFSET;
1859   int i, offset = 8;
1860
1861   if (register_size (get_regcache_arch (regcache), HPPA_R1_REGNUM) == 4)
1862     offset += 4;
1863
1864   for (i = HPPA_R1_REGNUM; i < HPPA_FP0_REGNUM; i++)
1865     {
1866       if (regnum == i || regnum == -1)
1867         regcache_raw_supply (regcache, i, ss_wide + offset);
1868
1869       offset += 8;
1870     }
1871 }
1872
1873 static void
1874 hppa_hpux_supply_save_state (const struct regset *regset,
1875                              struct regcache *regcache,
1876                              int regnum, const void *regs, size_t len)
1877 {
1878   const char *proc_info = regs;
1879   const char *save_state = proc_info + 8;
1880   ULONGEST flags;
1881
1882   flags = extract_unsigned_integer (save_state + HPPA_HPUX_SS_FLAGS_OFFSET, 4);
1883   if (regnum == -1 || regnum == HPPA_FLAGS_REGNUM)
1884     {
1885       struct gdbarch *arch = get_regcache_arch (regcache);
1886       size_t size = register_size (arch, HPPA_FLAGS_REGNUM);
1887       char buf[8];
1888
1889       store_unsigned_integer (buf, size, flags);
1890       regcache_raw_supply (regcache, HPPA_FLAGS_REGNUM, buf);
1891     }
1892
1893   /* If the SS_WIDEREGS flag is set, we really do need the full
1894      `struct save_state'.  */
1895   if (flags & HPPA_HPUX_SS_WIDEREGS && len < HPPA_HPUX_SAVE_STATE_SIZE)
1896     error (_("Register set contents too small"));
1897
1898   if (flags & HPPA_HPUX_SS_WIDEREGS)
1899     hppa_hpux_supply_ss_wide (regcache, regnum, save_state);
1900   else
1901     hppa_hpux_supply_ss_narrow (regcache, regnum, save_state);
1902
1903   hppa_hpux_supply_ss_fpblock (regcache, regnum, save_state);
1904 }
1905
1906 /* HP-UX register set.  */
1907
1908 static struct regset hppa_hpux_regset =
1909 {
1910   NULL,
1911   hppa_hpux_supply_save_state
1912 };
1913
1914 static const struct regset *
1915 hppa_hpux_regset_from_core_section (struct gdbarch *gdbarch,
1916                                     const char *sect_name, size_t sect_size)
1917 {
1918   if (strcmp (sect_name, ".reg") == 0
1919       && sect_size >= HPPA_HPUX_PA89_SAVE_STATE_SIZE + 8)
1920     return &hppa_hpux_regset;
1921
1922   return NULL;
1923 }
1924 \f
1925
1926 /* Bit in the `ss_flag' member of `struct save_state' that indicates
1927    the state was saved from a system call.  From
1928    <machine/save_state.h>.  */
1929 #define HPPA_HPUX_SS_INSYSCALL  0x02
1930
1931 static CORE_ADDR
1932 hppa_hpux_read_pc (ptid_t ptid)
1933 {
1934   ULONGEST flags;
1935
1936   /* If we're currently in a system call return the contents of %r31.  */
1937   flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
1938   if (flags & HPPA_HPUX_SS_INSYSCALL)
1939     return read_register_pid (HPPA_R31_REGNUM, ptid) & ~0x3;
1940
1941   return hppa_read_pc (ptid);
1942 }
1943
1944 static void
1945 hppa_hpux_write_pc (CORE_ADDR pc, ptid_t ptid)
1946 {
1947   ULONGEST flags;
1948
1949   /* If we're currently in a system call also write PC into %r31.  */
1950   flags = read_register_pid (HPPA_FLAGS_REGNUM, ptid);
1951   if (flags & HPPA_HPUX_SS_INSYSCALL)
1952     write_register_pid (HPPA_R31_REGNUM, pc | 0x3, ptid);
1953
1954   return hppa_write_pc (pc, ptid);
1955 }
1956
1957 static CORE_ADDR
1958 hppa_hpux_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
1959 {
1960   ULONGEST flags;
1961
1962   /* If we're currently in a system call return the contents of %r31.  */
1963   flags = frame_unwind_register_unsigned (next_frame, HPPA_FLAGS_REGNUM);
1964   if (flags & HPPA_HPUX_SS_INSYSCALL)
1965     return frame_unwind_register_unsigned (next_frame, HPPA_R31_REGNUM) & ~0x3;
1966
1967   return hppa_unwind_pc (gdbarch, next_frame);
1968 }
1969 \f
1970
1971 static void
1972 hppa_hpux_inferior_created (struct target_ops *objfile, int from_tty)
1973 {
1974   /* Some HP-UX related globals to clear when a new "main"
1975      symbol file is loaded.  HP-specific.  */
1976   deprecated_hp_som_som_object_present = 0;
1977   hp_cxx_exception_support_initialized = 0;
1978 }
1979
1980 /* Given the current value of the pc, check to see if it is inside a stub, and
1981    if so, change the value of the pc to point to the caller of the stub.
1982    NEXT_FRAME is the next frame in the current list of frames.
1983    BASE contains to stack frame base of the current frame. 
1984    SAVE_REGS is the register file stored in the frame cache. */
1985 static void
1986 hppa_hpux_unwind_adjust_stub (struct frame_info *next_frame, CORE_ADDR base,
1987                               struct trad_frame_saved_reg *saved_regs)
1988 {
1989   int optimized, realreg;
1990   enum lval_type lval;
1991   CORE_ADDR addr;
1992   char buffer[sizeof(ULONGEST)];
1993   ULONGEST val;
1994   CORE_ADDR stubpc;
1995   struct unwind_table_entry *u;
1996
1997   trad_frame_get_prev_register (next_frame, saved_regs, 
1998                                 HPPA_PCOQ_HEAD_REGNUM, 
1999                                 &optimized, &lval, &addr, &realreg, buffer);
2000   val = extract_unsigned_integer (buffer, 
2001                                   register_size (get_frame_arch (next_frame), 
2002                                                  HPPA_PCOQ_HEAD_REGNUM));
2003
2004   u = find_unwind_entry (val);
2005   if (u && u->stub_unwind.stub_type == EXPORT)
2006     {
2007       stubpc = read_memory_integer (base - 24, TARGET_PTR_BIT / 8);
2008       trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
2009     }
2010   else if (hppa_symbol_address ("__gcc_plt_call") 
2011            == get_pc_function_start (val))
2012     {
2013       stubpc = read_memory_integer (base - 8, TARGET_PTR_BIT / 8);
2014       trad_frame_set_value (saved_regs, HPPA_PCOQ_HEAD_REGNUM, stubpc);
2015     }
2016 }
2017
2018 static void
2019 hppa_hpux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2020 {
2021   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2022
2023   if (IS_32BIT_TARGET (gdbarch))
2024     tdep->in_solib_call_trampoline = hppa32_hpux_in_solib_call_trampoline;
2025   else
2026     tdep->in_solib_call_trampoline = hppa64_hpux_in_solib_call_trampoline;
2027
2028   tdep->unwind_adjust_stub = hppa_hpux_unwind_adjust_stub;
2029
2030   set_gdbarch_in_solib_return_trampoline
2031     (gdbarch, hppa_hpux_in_solib_return_trampoline);
2032   set_gdbarch_skip_trampoline_code (gdbarch, hppa_hpux_skip_trampoline_code);
2033
2034   set_gdbarch_push_dummy_code (gdbarch, hppa_hpux_push_dummy_code);
2035   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
2036
2037   set_gdbarch_read_pc (gdbarch, hppa_hpux_read_pc);
2038   set_gdbarch_write_pc (gdbarch, hppa_hpux_write_pc);
2039   set_gdbarch_unwind_pc (gdbarch, hppa_hpux_unwind_pc);
2040
2041   set_gdbarch_regset_from_core_section
2042     (gdbarch, hppa_hpux_regset_from_core_section);
2043
2044   frame_unwind_append_sniffer (gdbarch, hppa_hpux_sigtramp_unwind_sniffer);
2045
2046   observer_attach_inferior_created (hppa_hpux_inferior_created);
2047 }
2048
2049 static void
2050 hppa_hpux_som_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2051 {
2052   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2053
2054   tdep->is_elf = 0;
2055
2056   tdep->find_global_pointer = hppa32_hpux_find_global_pointer;
2057
2058   hppa_hpux_init_abi (info, gdbarch);
2059   som_solib_select (tdep);
2060 }
2061
2062 static void
2063 hppa_hpux_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
2064 {
2065   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
2066
2067   tdep->is_elf = 1;
2068   tdep->find_global_pointer = hppa64_hpux_find_global_pointer;
2069
2070   hppa_hpux_init_abi (info, gdbarch);
2071   pa64_solib_select (tdep);
2072 }
2073
2074 static enum gdb_osabi
2075 hppa_hpux_core_osabi_sniffer (bfd *abfd)
2076 {
2077   if (strcmp (bfd_get_target (abfd), "hpux-core") == 0)
2078     return GDB_OSABI_HPUX_SOM;
2079   else if (strcmp (bfd_get_target (abfd), "elf64-hppa") == 0)
2080     {
2081       asection *section;
2082       
2083       section = bfd_get_section_by_name (abfd, ".kernel");
2084       if (section)
2085         {
2086           bfd_size_type size;
2087           char *contents;
2088
2089           size = bfd_section_size (abfd, section);
2090           contents = alloca (size);
2091           if (bfd_get_section_contents (abfd, section, contents, 
2092                                         (file_ptr) 0, size)
2093               && strcmp (contents, "HP-UX") == 0)
2094             return GDB_OSABI_HPUX_ELF;
2095         }
2096     }
2097
2098   return GDB_OSABI_UNKNOWN;
2099 }
2100
2101 void
2102 _initialize_hppa_hpux_tdep (void)
2103 {
2104   /* BFD doesn't set a flavour for HP-UX style core files.  It doesn't
2105      set the architecture either.  */
2106   gdbarch_register_osabi_sniffer (bfd_arch_unknown,
2107                                   bfd_target_unknown_flavour,
2108                                   hppa_hpux_core_osabi_sniffer);
2109   gdbarch_register_osabi_sniffer (bfd_arch_hppa,
2110                                   bfd_target_elf_flavour,
2111                                   hppa_hpux_core_osabi_sniffer);
2112
2113   gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_HPUX_SOM,
2114                           hppa_hpux_som_init_abi);
2115   gdbarch_register_osabi (bfd_arch_hppa, bfd_mach_hppa20w, GDB_OSABI_HPUX_ELF,
2116                           hppa_hpux_elf_init_abi);
2117 }