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