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