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