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