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