diff options
Diffstat (limited to 'gdb/alpha-tdep.c')
-rw-r--r-- | gdb/alpha-tdep.c | 840 |
1 files changed, 429 insertions, 411 deletions
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 7d851d9..664b131 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1,21 +1,22 @@ /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger. Copyright 1993, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include "frame.h" @@ -41,7 +42,7 @@ static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR)); static alpha_extra_func_info_t heuristic_proc_desc PARAMS ((CORE_ADDR, CORE_ADDR, - struct frame_info *)); + struct frame_info *)); static alpha_extra_func_info_t find_proc_desc PARAMS ((CORE_ADDR, struct frame_info *)); @@ -57,7 +58,7 @@ static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc, alpha_extra_func_info_t proc_desc)); static int alpha_in_prologue PARAMS ((CORE_ADDR pc, - alpha_extra_func_info_t proc_desc)); + alpha_extra_func_info_t proc_desc)); static int alpha_about_to_return PARAMS ((CORE_ADDR pc)); @@ -67,7 +68,7 @@ void _initialize_alpha_tdep PARAMS ((void)); time across a 2400 baud serial line. Allows the user to limit this search. */ static unsigned int heuristic_fence_post = 0; - +/* *INDENT-OFF* */ /* Layout of a stack frame on the alpha: | | @@ -110,13 +111,16 @@ static unsigned int heuristic_fence_post = 0; -------------|-------------------------------|<-- sp | | */ +/* *INDENT-ON* */ + + -#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */ +#define PROC_LOW_ADDR(proc) ((proc)->pdr.adr) /* least address */ /* These next two fields are kind of being hijacked. I wonder if iline is too small for the values it needs to hold, if GDB is running on a 32-bit host. */ -#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */ -#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset) /*CALL_DUMMY frame */ +#define PROC_HIGH_ADDR(proc) ((proc)->pdr.iline) /* upper address bound */ +#define PROC_DUMMY_FRAME(proc) ((proc)->pdr.cbLineOffset) /*CALL_DUMMY frame */ #define PROC_FRAME_OFFSET(proc) ((proc)->pdr.frameoffset) #define PROC_FRAME_REG(proc) ((proc)->pdr.framereg) #define PROC_REG_MASK(proc) ((proc)->pdr.regmask) @@ -131,21 +135,22 @@ static unsigned int heuristic_fence_post = 0; #define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->pdr.isym = _PROC_MAGIC_) struct linked_proc_info -{ - struct alpha_extra_func_info info; - struct linked_proc_info *next; -} *linked_proc_desc_table = NULL; - + { + struct alpha_extra_func_info info; + struct linked_proc_info *next; + } + *linked_proc_desc_table = NULL; + /* Under GNU/Linux, signal handler invocations can be identified by the designated code sequence that is used to return from a signal handler. In particular, the return address of a signal handler points to the following sequence (the first instruction is quadword aligned): - bis $30,$30,$16 - addq $31,0x67,$0 - call_pal callsys + bis $30,$30,$16 + addq $31,0x67,$0 + call_pal callsys Each instruction has a unique encoding, so we simply attempt to match the instruction the pc is pointing to with any of the above @@ -159,7 +164,7 @@ struct linked_proc_info middle of the designated sequence, in which case there is no guarantee that we are in the middle of a sigreturn syscall. Don't think this will be a problem in praxis, though. -*/ + */ #ifndef TM_LINUXALPHA_H /* HACK: Provide a prototype when compiling this file for non @@ -173,16 +178,23 @@ alpha_linux_sigtramp_offset (pc) unsigned int i[3], w; long off; - if (read_memory_nobpt(pc, (char *) &w, 4) != 0) + if (read_memory_nobpt (pc, (char *) &w, 4) != 0) return -1; off = -1; switch (w) { - case 0x47de0410: off = 0; break; /* bis $30,$30,$16 */ - case 0x43ecf400: off = 4; break; /* addq $31,0x67,$0 */ - case 0x00000083: off = 8; break; /* call_pal callsys */ - default: return -1; + case 0x47de0410: + off = 0; + break; /* bis $30,$30,$16 */ + case 0x43ecf400: + off = 4; + break; /* addq $31,0x67,$0 */ + case 0x00000083: + off = 8; + break; /* call_pal callsys */ + default: + return -1; } pc -= off; if (pc & 0x7) @@ -191,7 +203,7 @@ alpha_linux_sigtramp_offset (pc) return -1; } - if (read_memory_nobpt(pc, (char *) i, sizeof(i)) != 0) + if (read_memory_nobpt (pc, (char *) i, sizeof (i)) != 0) return -1; if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083) @@ -199,8 +211,8 @@ alpha_linux_sigtramp_offset (pc) return -1; } - + /* Under OSF/1, the __sigtramp routine is frameless and has a frame size of zero, but we are able to backtrace through it. */ CORE_ADDR @@ -209,14 +221,14 @@ alpha_osf_skip_sigtramp_frame (frame, pc) CORE_ADDR pc; { char *name; - find_pc_partial_function (pc, &name, (CORE_ADDR *)NULL, (CORE_ADDR *)NULL); + find_pc_partial_function (pc, &name, (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); if (IN_SIGTRAMP (pc, name)) return frame->frame; else return 0; } - + /* Dynamically create a signal-handler caller procedure descriptor for the signal-handler return code starting at address LOW_ADDR. The descriptor is added to the linked_proc_desc_table. */ @@ -236,20 +248,20 @@ push_sigtramp_desc (low_addr) proc_desc = &link->info; proc_desc->numargs = 0; - PROC_LOW_ADDR (proc_desc) = low_addr; - PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4; - PROC_DUMMY_FRAME (proc_desc) = 0; - PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */ - PROC_FRAME_REG (proc_desc) = SP_REGNUM; - PROC_REG_MASK (proc_desc) = 0xffff; - PROC_FREG_MASK (proc_desc) = 0xffff; - PROC_PC_REG (proc_desc) = 26; - PROC_LOCALOFF (proc_desc) = 0; + PROC_LOW_ADDR (proc_desc) = low_addr; + PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4; + PROC_DUMMY_FRAME (proc_desc) = 0; + PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */ + PROC_FRAME_REG (proc_desc) = SP_REGNUM; + PROC_REG_MASK (proc_desc) = 0xffff; + PROC_FREG_MASK (proc_desc) = 0xffff; + PROC_PC_REG (proc_desc) = 26; + PROC_LOCALOFF (proc_desc) = 0; SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc); return (proc_desc); } - + /* Guaranteed to set frame->saved_regs to some values (it never leaves it NULL). */ @@ -282,13 +294,13 @@ alpha_find_saved_regs (frame) sigcontext_addr = SIGCONTEXT_ADDR (frame); for (ireg = 0; ireg < 32; ireg++) { - reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8; - frame->saved_regs[ireg] = reg_position; + reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8; + frame->saved_regs[ireg] = reg_position; } for (ireg = 0; ireg < 32; ireg++) { - reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8; - frame->saved_regs[FP0_REGNUM + ireg] = reg_position; + reg_position = sigcontext_addr + SIGFRAME_FPREGSAVE_OFF + ireg * 8; + frame->saved_regs[FP0_REGNUM + ireg] = reg_position; } frame->saved_regs[PC_REGNUM] = sigcontext_addr + SIGFRAME_PC_OFF; return; @@ -315,11 +327,11 @@ alpha_find_saved_regs (frame) { frame->saved_regs[returnreg] = reg_position; reg_position += 8; - mask &= ~(1 << returnreg); /* Clear bit for RA so we - don't save again later. */ + mask &= ~(1 << returnreg); /* Clear bit for RA so we + don't save again later. */ } - for (ireg = 0; ireg <= 31 ; ++ireg) + for (ireg = 0; ireg <= 31; ++ireg) if (mask & (1 << ireg)) { frame->saved_regs[ireg] = reg_position; @@ -332,10 +344,10 @@ alpha_find_saved_regs (frame) reg_position = frame->frame + PROC_FREG_OFFSET (proc_desc); mask = PROC_FREG_MASK (proc_desc); - for (ireg = 0; ireg <= 31 ; ++ireg) + for (ireg = 0; ireg <= 31; ++ireg) if (mask & (1 << ireg)) { - frame->saved_regs[FP0_REGNUM+ireg] = reg_position; + frame->saved_regs[FP0_REGNUM + ireg] = reg_position; reg_position += 8; } @@ -343,14 +355,14 @@ alpha_find_saved_regs (frame) } static CORE_ADDR -read_next_frame_reg(fi, regno) +read_next_frame_reg (fi, regno) struct frame_info *fi; int regno; { for (; fi; fi = fi->next) { /* We have to get the saved sp from the sigcontext - if it is a signal handler frame. */ + if it is a signal handler frame. */ if (regno == SP_REGNUM && !fi->signal_handler_caller) return fi->frame; else @@ -358,14 +370,14 @@ read_next_frame_reg(fi, regno) if (fi->saved_regs == NULL) alpha_find_saved_regs (fi); if (fi->saved_regs[regno]) - return read_memory_integer(fi->saved_regs[regno], 8); + return read_memory_integer (fi->saved_regs[regno], 8); } } - return read_register(regno); + return read_register (regno); } CORE_ADDR -alpha_frame_saved_pc(frame) +alpha_frame_saved_pc (frame) struct frame_info *frame; { alpha_extra_func_info_t proc_desc = frame->proc_desc; @@ -373,10 +385,10 @@ alpha_frame_saved_pc(frame) if it is a signal handler frame. */ int pcreg = frame->signal_handler_caller ? PC_REGNUM : frame->pc_reg; - if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc)) - return read_memory_integer(frame->frame - 8, 8); + if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc)) + return read_memory_integer (frame->frame - 8, 8); - return read_next_frame_reg(frame, pcreg); + return read_next_frame_reg (frame, pcreg); } CORE_ADDR @@ -423,177 +435,178 @@ alpha_about_to_return (pc) lines. */ static CORE_ADDR -heuristic_proc_start(pc) - CORE_ADDR pc; +heuristic_proc_start (pc) + CORE_ADDR pc; { - CORE_ADDR start_pc = pc; - CORE_ADDR fence = start_pc - heuristic_fence_post; + CORE_ADDR start_pc = pc; + CORE_ADDR fence = start_pc - heuristic_fence_post; - if (start_pc == 0) return 0; + if (start_pc == 0) + return 0; - if (heuristic_fence_post == UINT_MAX - || fence < VM_MIN_ADDRESS) - fence = VM_MIN_ADDRESS; + if (heuristic_fence_post == UINT_MAX + || fence < VM_MIN_ADDRESS) + fence = VM_MIN_ADDRESS; - /* search back for previous return */ - for (start_pc -= 4; ; start_pc -= 4) - if (start_pc < fence) + /* search back for previous return */ + for (start_pc -= 4;; start_pc -= 4) + if (start_pc < fence) + { + /* It's not clear to me why we reach this point when + stop_soon_quietly, but with this test, at least we + don't print out warnings for every child forked (eg, on + decstation). 22apr93 rich@cygnus.com. */ + if (!stop_soon_quietly) { - /* It's not clear to me why we reach this point when - stop_soon_quietly, but with this test, at least we - don't print out warnings for every child forked (eg, on - decstation). 22apr93 rich@cygnus.com. */ - if (!stop_soon_quietly) + static int blurb_printed = 0; + + if (fence == VM_MIN_ADDRESS) + warning ("Hit beginning of text section without finding"); + else + warning ("Hit heuristic-fence-post without finding"); + + warning ("enclosing function for address 0x%lx", pc); + if (!blurb_printed) { - static int blurb_printed = 0; - - if (fence == VM_MIN_ADDRESS) - warning("Hit beginning of text section without finding"); - else - warning("Hit heuristic-fence-post without finding"); - - warning("enclosing function for address 0x%lx", pc); - if (!blurb_printed) - { - printf_filtered ("\ + printf_filtered ("\ This warning occurs if you are debugging a function without any symbols\n\ (for example, in a stripped executable). In that case, you may wish to\n\ increase the size of the search with the `set heuristic-fence-post' command.\n\ \n\ Otherwise, you told GDB there was a function where there isn't one, or\n\ (more likely) you have encountered a bug in GDB.\n"); - blurb_printed = 1; - } + blurb_printed = 1; } - - return 0; } - else if (alpha_about_to_return (start_pc)) - break; - start_pc += 4; /* skip return */ - return start_pc; + return 0; + } + else if (alpha_about_to_return (start_pc)) + break; + + start_pc += 4; /* skip return */ + return start_pc; } static alpha_extra_func_info_t -heuristic_proc_desc(start_pc, limit_pc, next_frame) - CORE_ADDR start_pc, limit_pc; - struct frame_info *next_frame; +heuristic_proc_desc (start_pc, limit_pc, next_frame) + CORE_ADDR start_pc, limit_pc; + struct frame_info *next_frame; { - CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM); - CORE_ADDR cur_pc; - int frame_size; - int has_frame_reg = 0; - unsigned long reg_mask = 0; - int pcreg = -1; - - if (start_pc == 0) - return NULL; - memset (&temp_proc_desc, '\0', sizeof(temp_proc_desc)); - memset (&temp_saved_regs, '\0', sizeof(struct frame_saved_regs)); - PROC_LOW_ADDR (&temp_proc_desc) = start_pc; - - if (start_pc + 200 < limit_pc) - limit_pc = start_pc + 200; - frame_size = 0; - for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) - { - char buf[4]; - unsigned long word; - int status; + CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM); + CORE_ADDR cur_pc; + int frame_size; + int has_frame_reg = 0; + unsigned long reg_mask = 0; + int pcreg = -1; + + if (start_pc == 0) + return NULL; + memset (&temp_proc_desc, '\0', sizeof (temp_proc_desc)); + memset (&temp_saved_regs, '\0', sizeof (struct frame_saved_regs)); + PROC_LOW_ADDR (&temp_proc_desc) = start_pc; + + if (start_pc + 200 < limit_pc) + limit_pc = start_pc + 200; + frame_size = 0; + for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) + { + char buf[4]; + unsigned long word; + int status; - status = read_memory_nobpt (cur_pc, buf, 4); - if (status) - memory_error (status, cur_pc); - word = extract_unsigned_integer (buf, 4); + status = read_memory_nobpt (cur_pc, buf, 4); + if (status) + memory_error (status, cur_pc); + word = extract_unsigned_integer (buf, 4); - if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ - { - if (word & 0x8000) - frame_size += (-word) & 0xffff; - else - /* Exit loop if a positive stack adjustment is found, which - usually means that the stack cleanup code in the function - epilogue is reached. */ - break; - } - else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ - && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ - { - int reg = (word & 0x03e00000) >> 21; - reg_mask |= 1 << reg; - temp_saved_regs.regs[reg] = sp + (short)word; - - /* Starting with OSF/1-3.2C, the system libraries are shipped - without local symbols, but they still contain procedure - descriptors without a symbol reference. GDB is currently - unable to find these procedure descriptors and uses - heuristic_proc_desc instead. - As some low level compiler support routines (__div*, __add*) - use a non-standard return address register, we have to - add some heuristics to determine the return address register, - or stepping over these routines will fail. - Usually the return address register is the first register - saved on the stack, but assembler optimization might - rearrange the register saves. - So we recognize only a few registers (t7, t9, ra) within - the procedure prologue as valid return address registers. - If we encounter a return instruction, we extract the - the return address register from it. - - FIXME: Rewriting GDB to access the procedure descriptors, - e.g. via the minimal symbol table, might obviate this hack. */ - if (pcreg == -1 - && cur_pc < (start_pc + 80) - && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)) - pcreg = reg; - } - else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ - pcreg = (word >> 16) & 0x1f; - else if (word == 0x47de040f) /* bis sp,sp fp */ - has_frame_reg = 1; - } - if (pcreg == -1) - { - /* If we haven't found a valid return address register yet, - keep searching in the procedure prologue. */ - while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80)) - { - char buf[4]; - unsigned long word; + if ((word & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ + { + if (word & 0x8000) + frame_size += (-word) & 0xffff; + else + /* Exit loop if a positive stack adjustment is found, which + usually means that the stack cleanup code in the function + epilogue is reached. */ + break; + } + else if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ + && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ + { + int reg = (word & 0x03e00000) >> 21; + reg_mask |= 1 << reg; + temp_saved_regs.regs[reg] = sp + (short) word; + + /* Starting with OSF/1-3.2C, the system libraries are shipped + without local symbols, but they still contain procedure + descriptors without a symbol reference. GDB is currently + unable to find these procedure descriptors and uses + heuristic_proc_desc instead. + As some low level compiler support routines (__div*, __add*) + use a non-standard return address register, we have to + add some heuristics to determine the return address register, + or stepping over these routines will fail. + Usually the return address register is the first register + saved on the stack, but assembler optimization might + rearrange the register saves. + So we recognize only a few registers (t7, t9, ra) within + the procedure prologue as valid return address registers. + If we encounter a return instruction, we extract the + the return address register from it. + + FIXME: Rewriting GDB to access the procedure descriptors, + e.g. via the minimal symbol table, might obviate this hack. */ + if (pcreg == -1 + && cur_pc < (start_pc + 80) + && (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM)) + pcreg = reg; + } + else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ + pcreg = (word >> 16) & 0x1f; + else if (word == 0x47de040f) /* bis sp,sp fp */ + has_frame_reg = 1; + } + if (pcreg == -1) + { + /* If we haven't found a valid return address register yet, + keep searching in the procedure prologue. */ + while (cur_pc < (limit_pc + 80) && cur_pc < (start_pc + 80)) + { + char buf[4]; + unsigned long word; - if (read_memory_nobpt (cur_pc, buf, 4)) - break; - cur_pc += 4; - word = extract_unsigned_integer (buf, 4); + if (read_memory_nobpt (cur_pc, buf, 4)) + break; + cur_pc += 4; + word = extract_unsigned_integer (buf, 4); - if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ - && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ - { - int reg = (word & 0x03e00000) >> 21; - if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM) - { - pcreg = reg; - break; - } - } - else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ - { - pcreg = (word >> 16) & 0x1f; - break; - } - } - } + if ((word & 0xfc1f0000) == 0xb41e0000 /* stq reg,n($sp) */ + && (word & 0xffff0000) != 0xb7fe0000) /* reg != $zero */ + { + int reg = (word & 0x03e00000) >> 21; + if (reg == T7_REGNUM || reg == T9_REGNUM || reg == RA_REGNUM) + { + pcreg = reg; + break; + } + } + else if ((word & 0xffe0ffff) == 0x6be08001) /* ret zero,reg,1 */ + { + pcreg = (word >> 16) & 0x1f; + break; + } + } + } - if (has_frame_reg) - PROC_FRAME_REG(&temp_proc_desc) = GCC_FP_REGNUM; - else - PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM; - PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size; - PROC_REG_MASK(&temp_proc_desc) = reg_mask; - PROC_PC_REG(&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg; - PROC_LOCALOFF(&temp_proc_desc) = 0; /* XXX - bogus */ - return &temp_proc_desc; + if (has_frame_reg) + PROC_FRAME_REG (&temp_proc_desc) = GCC_FP_REGNUM; + else + PROC_FRAME_REG (&temp_proc_desc) = SP_REGNUM; + PROC_FRAME_OFFSET (&temp_proc_desc) = frame_size; + PROC_REG_MASK (&temp_proc_desc) = reg_mask; + PROC_PC_REG (&temp_proc_desc) = (pcreg == -1) ? RA_REGNUM : pcreg; + PROC_LOCALOFF (&temp_proc_desc) = 0; /* XXX - bogus */ + return &temp_proc_desc; } /* This returns the PC of the first inst after the prologue. If we can't @@ -616,7 +629,7 @@ after_prologue (pc, proc_desc) return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */ /* If function is frameless, then we need to do it the hard way. I - strongly suspect that frameless always means prologueless... */ + strongly suspect that frameless always means prologueless... */ if (PROC_FRAME_REG (proc_desc) == SP_REGNUM && PROC_FRAME_OFFSET (proc_desc) == 0) return 0; @@ -657,8 +670,8 @@ alpha_in_prologue (pc, proc_desc) static alpha_extra_func_info_t find_proc_desc (pc, next_frame) - CORE_ADDR pc; - struct frame_info *next_frame; + CORE_ADDR pc; + struct frame_info *next_frame; { alpha_extra_func_info_t proc_desc; struct block *b; @@ -693,7 +706,7 @@ find_proc_desc (pc, next_frame) return found_proc_desc; } - b = block_for_pc(pc); + b = block_for_pc (pc); find_pc_partial_function (pc, NULL, &startaddr, NULL); if (b == NULL) @@ -717,57 +730,57 @@ find_proc_desc (pc, next_frame) if (sym) { - /* IF this is the topmost frame AND - * (this proc does not have debugging information OR - * the PC is in the procedure prologue) - * THEN create a "heuristic" proc_desc (by analyzing - * the actual code) to replace the "official" proc_desc. - */ - proc_desc = (alpha_extra_func_info_t)SYMBOL_VALUE(sym); - if (next_frame == NULL) - { - if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc)) - { - alpha_extra_func_info_t found_heuristic = - heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), - pc, next_frame); - if (found_heuristic) - { - PROC_LOCALOFF (found_heuristic) = - PROC_LOCALOFF (proc_desc); - PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc); - proc_desc = found_heuristic; - } - } - } + /* IF this is the topmost frame AND + * (this proc does not have debugging information OR + * the PC is in the procedure prologue) + * THEN create a "heuristic" proc_desc (by analyzing + * the actual code) to replace the "official" proc_desc. + */ + proc_desc = (alpha_extra_func_info_t) SYMBOL_VALUE (sym); + if (next_frame == NULL) + { + if (PROC_DESC_IS_DUMMY (proc_desc) || alpha_in_prologue (pc, proc_desc)) + { + alpha_extra_func_info_t found_heuristic = + heuristic_proc_desc (PROC_LOW_ADDR (proc_desc), + pc, next_frame); + if (found_heuristic) + { + PROC_LOCALOFF (found_heuristic) = + PROC_LOCALOFF (proc_desc); + PROC_PC_REG (found_heuristic) = PROC_PC_REG (proc_desc); + proc_desc = found_heuristic; + } + } + } } else { long offset; /* Is linked_proc_desc_table really necessary? It only seems to be used - by procedure call dummys. However, the procedures being called ought - to have their own proc_descs, and even if they don't, - heuristic_proc_desc knows how to create them! */ + by procedure call dummys. However, the procedures being called ought + to have their own proc_descs, and even if they don't, + heuristic_proc_desc knows how to create them! */ register struct linked_proc_info *link; for (link = linked_proc_desc_table; link; link = link->next) - if (PROC_LOW_ADDR(&link->info) <= pc - && PROC_HIGH_ADDR(&link->info) > pc) - return &link->info; + if (PROC_LOW_ADDR (&link->info) <= pc + && PROC_HIGH_ADDR (&link->info) > pc) + return &link->info; /* If PC is inside a dynamically generated sigtramp handler, - create and push a procedure descriptor for that code: */ + create and push a procedure descriptor for that code: */ offset = DYNAMIC_SIGTRAMP_OFFSET (pc); if (offset >= 0) return push_sigtramp_desc (pc - offset); /* If heuristic_fence_post is non-zero, determine the procedure - start address by examining the instructions. - This allows us to find the start address of static functions which - have no symbolic information, as startaddr would have been set to - the preceding global function start address by the - find_pc_partial_function call above. */ + start address by examining the instructions. + This allows us to find the start address of static functions which + have no symbolic information, as startaddr would have been set to + the preceding global function start address by the + find_pc_partial_function call above. */ if (startaddr == 0 || heuristic_fence_post != 0) startaddr = heuristic_proc_start (pc); @@ -780,38 +793,38 @@ find_proc_desc (pc, next_frame) alpha_extra_func_info_t cached_proc_desc; CORE_ADDR -alpha_frame_chain(frame) - struct frame_info *frame; +alpha_frame_chain (frame) + struct frame_info *frame; { - alpha_extra_func_info_t proc_desc; - CORE_ADDR saved_pc = FRAME_SAVED_PC(frame); - - if (saved_pc == 0 || inside_entry_file (saved_pc)) - return 0; - - proc_desc = find_proc_desc(saved_pc, frame); - if (!proc_desc) - return 0; - - cached_proc_desc = proc_desc; - - /* Fetch the frame pointer for a dummy frame from the procedure - descriptor. */ - if (PROC_DESC_IS_DUMMY(proc_desc)) - return (CORE_ADDR) PROC_DUMMY_FRAME(proc_desc); - - /* If no frame pointer and frame size is zero, we must be at end - of stack (or otherwise hosed). If we don't check frame size, - we loop forever if we see a zero size frame. */ - if (PROC_FRAME_REG (proc_desc) == SP_REGNUM - && PROC_FRAME_OFFSET (proc_desc) == 0 - /* The previous frame from a sigtramp frame might be frameless - and have frame size zero. */ - && !frame->signal_handler_caller) - return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc); - else - return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc)) - + PROC_FRAME_OFFSET(proc_desc); + alpha_extra_func_info_t proc_desc; + CORE_ADDR saved_pc = FRAME_SAVED_PC (frame); + + if (saved_pc == 0 || inside_entry_file (saved_pc)) + return 0; + + proc_desc = find_proc_desc (saved_pc, frame); + if (!proc_desc) + return 0; + + cached_proc_desc = proc_desc; + + /* Fetch the frame pointer for a dummy frame from the procedure + descriptor. */ + if (PROC_DESC_IS_DUMMY (proc_desc)) + return (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc); + + /* If no frame pointer and frame size is zero, we must be at end + of stack (or otherwise hosed). If we don't check frame size, + we loop forever if we see a zero size frame. */ + if (PROC_FRAME_REG (proc_desc) == SP_REGNUM + && PROC_FRAME_OFFSET (proc_desc) == 0 + /* The previous frame from a sigtramp frame might be frameless + and have frame size zero. */ + && !frame->signal_handler_caller) + return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc); + else + return read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc)) + + PROC_FRAME_OFFSET (proc_desc); } void @@ -820,7 +833,7 @@ init_extra_frame_info (frame) { /* Use proc_desc calculated in frame_chain */ alpha_extra_func_info_t proc_desc = - frame->next ? cached_proc_desc : find_proc_desc(frame->pc, frame->next); + frame->next ? cached_proc_desc : find_proc_desc (frame->pc, frame->next); frame->saved_regs = NULL; frame->localoff = 0; @@ -829,21 +842,21 @@ init_extra_frame_info (frame) if (proc_desc) { /* Get the locals offset and the saved pc register from the - procedure descriptor, they are valid even if we are in the - middle of the prologue. */ - frame->localoff = PROC_LOCALOFF(proc_desc); - frame->pc_reg = PROC_PC_REG(proc_desc); + procedure descriptor, they are valid even if we are in the + middle of the prologue. */ + frame->localoff = PROC_LOCALOFF (proc_desc); + frame->pc_reg = PROC_PC_REG (proc_desc); /* Fixup frame-pointer - only needed for top frame */ /* Fetch the frame pointer for a dummy frame from the procedure - descriptor. */ - if (PROC_DESC_IS_DUMMY(proc_desc)) - frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME(proc_desc); + descriptor. */ + if (PROC_DESC_IS_DUMMY (proc_desc)) + frame->frame = (CORE_ADDR) PROC_DUMMY_FRAME (proc_desc); /* This may not be quite right, if proc has a real frame register. - Get the value of the frame relative sp, procedure might have been - interrupted by a signal at it's very start. */ + Get the value of the frame relative sp, procedure might have been + interrupted by a signal at it's very start. */ else if (frame->pc == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)) frame->frame = read_next_frame_reg (frame->next, SP_REGNUM); @@ -859,10 +872,10 @@ init_extra_frame_info (frame) alpha_find_saved_registers will do that for us. We can't use frame->signal_handler_caller, it is not yet set. */ find_pc_partial_function (frame->pc, &name, - (CORE_ADDR *)NULL,(CORE_ADDR *)NULL); + (CORE_ADDR *) NULL, (CORE_ADDR *) NULL); if (!IN_SIGTRAMP (frame->pc, name)) { - frame->saved_regs = (CORE_ADDR*) + frame->saved_regs = (CORE_ADDR *) frame_obstack_alloc (SIZEOF_FRAME_SAVED_REGS); memcpy (frame->saved_regs, temp_saved_regs.regs, SIZEOF_FRAME_SAVED_REGS); frame->saved_regs[PC_REGNUM] @@ -919,9 +932,14 @@ alpha_push_arguments (nargs, args, sp, struct_return, struct_addr) int i; int accumulate_size = struct_return ? 8 : 0; int arg_regs_size = ALPHA_NUM_ARG_REGS * 8; - struct alpha_arg { char *contents; int len; int offset; }; + struct alpha_arg + { + char *contents; + int len; + int offset; + }; struct alpha_arg *alpha_args = - (struct alpha_arg*)alloca (nargs * sizeof (struct alpha_arg)); + (struct alpha_arg *) alloca (nargs * sizeof (struct alpha_arg)); register struct alpha_arg *m_arg; char raw_buffer[sizeof (CORE_ADDR)]; int required_arg_regs; @@ -950,7 +968,7 @@ alpha_push_arguments (nargs, args, sp, struct_return, struct_addr) m_arg->len = TYPE_LENGTH (arg_type); m_arg->offset = accumulate_size; accumulate_size = (accumulate_size + m_arg->len + 7) & ~7; - m_arg->contents = VALUE_CONTENTS(arg); + m_arg->contents = VALUE_CONTENTS (arg); } /* Determine required argument register loads, loading an argument register @@ -961,15 +979,15 @@ alpha_push_arguments (nargs, args, sp, struct_return, struct_addr) /* Make room for the arguments on the stack. */ if (accumulate_size < arg_regs_size) - accumulate_size = arg_regs_size; + accumulate_size = arg_regs_size; sp -= accumulate_size; /* Keep sp aligned to a multiple of 16 as the compiler does it too. */ sp &= ~15; /* `Push' arguments on the stack. */ - for (i = nargs; m_arg--, --i >= 0; ) - write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len); + for (i = nargs; m_arg--, --i >= 0;) + write_memory (sp + m_arg->offset, m_arg->contents, m_arg->len); if (struct_return) { store_address (raw_buffer, sizeof (CORE_ADDR), struct_addr); @@ -990,7 +1008,7 @@ alpha_push_arguments (nargs, args, sp, struct_return, struct_addr) } void -alpha_push_dummy_frame() +alpha_push_dummy_frame () { int ireg; struct linked_proc_info *link; @@ -1000,10 +1018,10 @@ alpha_push_dummy_frame() char raw_buffer[MAX_REGISTER_RAW_SIZE]; unsigned long mask; - link = (struct linked_proc_info *) xmalloc(sizeof (struct linked_proc_info)); + link = (struct linked_proc_info *) xmalloc (sizeof (struct linked_proc_info)); link->next = linked_proc_desc_table; linked_proc_desc_table = link; - + proc_desc = &link->info; /* @@ -1013,15 +1031,15 @@ alpha_push_dummy_frame() * * Dummy frame layout: * (high memory) - * Saved PC + * Saved PC * Saved F30 * ... * Saved F0 - * Saved R29 - * ... - * Saved R0 - * Saved R26 (RA) - * Parameter build area + * Saved R29 + * ... + * Saved R0 + * Saved R26 (RA) + * Parameter build area * (low memory) */ @@ -1035,27 +1053,27 @@ alpha_push_dummy_frame() alpha_frame_saved_pc knows where the pc is saved in a dummy frame. */ #define SPECIAL_REG_SAVE_COUNT 1 - PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK; - PROC_FREG_MASK(proc_desc) = FLOAT_REG_SAVE_MASK; + PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK; + PROC_FREG_MASK (proc_desc) = FLOAT_REG_SAVE_MASK; /* PROC_REG_OFFSET is the offset from the dummy frame to the saved RA, but keep SP aligned to a multiple of 16. */ - PROC_REG_OFFSET(proc_desc) = - - ((8 * (SPECIAL_REG_SAVE_COUNT + PROC_REG_OFFSET (proc_desc) = + -((8 * (SPECIAL_REG_SAVE_COUNT + GEN_REG_SAVE_COUNT + FLOAT_REG_SAVE_COUNT) - + 15) & ~15); - PROC_FREG_OFFSET(proc_desc) = - PROC_REG_OFFSET(proc_desc) + 8 * GEN_REG_SAVE_COUNT; + + 15) & ~15); + PROC_FREG_OFFSET (proc_desc) = + PROC_REG_OFFSET (proc_desc) + 8 * GEN_REG_SAVE_COUNT; /* Save general registers. The return address register is the first saved register, all other registers follow in ascending order. The PC is saved immediately below the SP. */ - save_address = sp + PROC_REG_OFFSET(proc_desc); + save_address = sp + PROC_REG_OFFSET (proc_desc); store_address (raw_buffer, 8, read_register (RA_REGNUM)); write_memory (save_address, raw_buffer, 8); save_address += 8; - mask = PROC_REG_MASK(proc_desc) & 0xffffffffL; + mask = PROC_REG_MASK (proc_desc) & 0xffffffffL; for (ireg = 0; mask; ireg++, mask >>= 1) if (mask & 1) { @@ -1070,8 +1088,8 @@ alpha_push_dummy_frame() write_memory (sp - 8, raw_buffer, 8); /* Save floating point registers. */ - save_address = sp + PROC_FREG_OFFSET(proc_desc); - mask = PROC_FREG_MASK(proc_desc) & 0xffffffffL; + save_address = sp + PROC_FREG_OFFSET (proc_desc); + mask = PROC_FREG_MASK (proc_desc) & 0xffffffffL; for (ireg = 0; mask; ireg++, mask >>= 1) if (mask & 1) { @@ -1092,21 +1110,21 @@ alpha_push_dummy_frame() is set to the virtual frame (pseudo) register, it's value will always be read as zero and will help us to catch any errors in the dummy frame retrieval code. */ - PROC_DUMMY_FRAME(proc_desc) = sp; - PROC_FRAME_REG(proc_desc) = FP_REGNUM; - PROC_FRAME_OFFSET(proc_desc) = 0; - sp += PROC_REG_OFFSET(proc_desc); + PROC_DUMMY_FRAME (proc_desc) = sp; + PROC_FRAME_REG (proc_desc) = FP_REGNUM; + PROC_FRAME_OFFSET (proc_desc) = 0; + sp += PROC_REG_OFFSET (proc_desc); write_register (SP_REGNUM, sp); - PROC_LOW_ADDR(proc_desc) = CALL_DUMMY_ADDRESS (); - PROC_HIGH_ADDR(proc_desc) = PROC_LOW_ADDR(proc_desc) + 4; + PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS (); + PROC_HIGH_ADDR (proc_desc) = PROC_LOW_ADDR (proc_desc) + 4; - SET_PROC_DESC_IS_DUMMY(proc_desc); - PROC_PC_REG(proc_desc) = RA_REGNUM; + SET_PROC_DESC_IS_DUMMY (proc_desc); + PROC_PC_REG (proc_desc) = RA_REGNUM; } void -alpha_pop_frame() +alpha_pop_frame () { register int regnum; struct frame_info *frame = get_current_frame (); @@ -1117,31 +1135,31 @@ alpha_pop_frame() /* we need proc_desc to know how to restore the registers; if it is NULL, construct (a temporary) one */ if (proc_desc == NULL) - proc_desc = find_proc_desc(frame->pc, frame->next); + proc_desc = find_proc_desc (frame->pc, frame->next); /* Question: should we copy this proc_desc and save it in frame->proc_desc? If we do, who will free it? For now, we don't save a copy... */ - write_register (PC_REGNUM, FRAME_SAVED_PC(frame)); + write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); if (frame->saved_regs == NULL) alpha_find_saved_regs (frame); if (proc_desc) { - for (regnum = 32; --regnum >= 0; ) - if (PROC_REG_MASK(proc_desc) & (1 << regnum)) + for (regnum = 32; --regnum >= 0;) + if (PROC_REG_MASK (proc_desc) & (1 << regnum)) write_register (regnum, read_memory_integer (frame->saved_regs[regnum], 8)); - for (regnum = 32; --regnum >= 0; ) - if (PROC_FREG_MASK(proc_desc) & (1 << regnum)) + for (regnum = 32; --regnum >= 0;) + if (PROC_FREG_MASK (proc_desc) & (1 << regnum)) write_register (regnum + FP0_REGNUM, - read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8)); + read_memory_integer (frame->saved_regs[regnum + FP0_REGNUM], 8)); } write_register (SP_REGNUM, new_sp); flush_cached_frames (); - if (proc_desc && (PROC_DESC_IS_DUMMY(proc_desc) + if (proc_desc && (PROC_DESC_IS_DUMMY (proc_desc) || PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))) { struct linked_proc_info *pi_ptr, *prev_ptr; @@ -1180,74 +1198,74 @@ alpha_skip_prologue (pc, lenient) CORE_ADDR pc; int lenient; { - unsigned long inst; - int offset; - CORE_ADDR post_prologue_pc; - char buf[4]; + unsigned long inst; + int offset; + CORE_ADDR post_prologue_pc; + char buf[4]; #ifdef GDB_TARGET_HAS_SHARED_LIBS - /* Silently return the unaltered pc upon memory errors. - This could happen on OSF/1 if decode_line_1 tries to skip the - prologue for quickstarted shared library functions when the - shared library is not yet mapped in. - Reading target memory is slow over serial lines, so we perform - this check only if the target has shared libraries. */ - if (target_read_memory (pc, buf, 4)) - return pc; + /* Silently return the unaltered pc upon memory errors. + This could happen on OSF/1 if decode_line_1 tries to skip the + prologue for quickstarted shared library functions when the + shared library is not yet mapped in. + Reading target memory is slow over serial lines, so we perform + this check only if the target has shared libraries. */ + if (target_read_memory (pc, buf, 4)) + return pc; #endif - /* See if we can determine the end of the prologue via the symbol table. - If so, then return either PC, or the PC after the prologue, whichever - is greater. */ - - post_prologue_pc = after_prologue (pc, NULL); + /* See if we can determine the end of the prologue via the symbol table. + If so, then return either PC, or the PC after the prologue, whichever + is greater. */ - if (post_prologue_pc != 0) - return max (pc, post_prologue_pc); + post_prologue_pc = after_prologue (pc, NULL); - /* Can't determine prologue from the symbol table, need to examine - instructions. */ + if (post_prologue_pc != 0) + return max (pc, post_prologue_pc); - /* Skip the typical prologue instructions. These are the stack adjustment - instruction and the instructions that save registers on the stack - or in the gcc frame. */ - for (offset = 0; offset < 100; offset += 4) - { - int status; + /* Can't determine prologue from the symbol table, need to examine + instructions. */ - status = read_memory_nobpt (pc + offset, buf, 4); - if (status) - memory_error (status, pc + offset); - inst = extract_unsigned_integer (buf, 4); - - /* The alpha has no delay slots. But let's keep the lenient stuff, - we might need it for something else in the future. */ - if (lenient && 0) - continue; - - if ((inst & 0xffff0000) == 0x27bb0000) /* ldah $gp,n($t12) */ - continue; - if ((inst & 0xffff0000) == 0x23bd0000) /* lda $gp,n($gp) */ - continue; - if ((inst & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ - continue; - if ((inst & 0xffe01fff) == 0x43c0153e) /* subq $sp,n,$sp */ - continue; - - if ((inst & 0xfc1f0000) == 0xb41e0000 - && (inst & 0xffff0000) != 0xb7fe0000) - continue; /* stq reg,n($sp) */ - /* reg != $zero */ - if ((inst & 0xfc1f0000) == 0x9c1e0000 - && (inst & 0xffff0000) != 0x9ffe0000) - continue; /* stt reg,n($sp) */ - /* reg != $zero */ - if (inst == 0x47de040f) /* bis sp,sp,fp */ - continue; - - break; + /* Skip the typical prologue instructions. These are the stack adjustment + instruction and the instructions that save registers on the stack + or in the gcc frame. */ + for (offset = 0; offset < 100; offset += 4) + { + int status; + + status = read_memory_nobpt (pc + offset, buf, 4); + if (status) + memory_error (status, pc + offset); + inst = extract_unsigned_integer (buf, 4); + + /* The alpha has no delay slots. But let's keep the lenient stuff, + we might need it for something else in the future. */ + if (lenient && 0) + continue; + + if ((inst & 0xffff0000) == 0x27bb0000) /* ldah $gp,n($t12) */ + continue; + if ((inst & 0xffff0000) == 0x23bd0000) /* lda $gp,n($gp) */ + continue; + if ((inst & 0xffff0000) == 0x23de0000) /* lda $sp,n($sp) */ + continue; + if ((inst & 0xffe01fff) == 0x43c0153e) /* subq $sp,n,$sp */ + continue; + + if ((inst & 0xfc1f0000) == 0xb41e0000 + && (inst & 0xffff0000) != 0xb7fe0000) + continue; /* stq reg,n($sp) */ + /* reg != $zero */ + if ((inst & 0xfc1f0000) == 0x9c1e0000 + && (inst & 0xffff0000) != 0x9ffe0000) + continue; /* stt reg,n($sp) */ + /* reg != $zero */ + if (inst == 0x47de040f) /* bis sp,sp,fp */ + continue; + + break; } - return pc + offset; + return pc + offset; } #if 0 @@ -1266,16 +1284,16 @@ alpha_in_lenient_prologue (startaddr, pc) /* The alpha needs a conversion between register and memory format if the register is a floating point register and - memory format is float, as the register format must be double + memory format is float, as the register format must be double or - memory format is an integer with 4 bytes or less, as the representation - of integers in floating point registers is different. */ + memory format is an integer with 4 bytes or less, as the representation + of integers in floating point registers is different. */ void alpha_register_convert_to_virtual (regnum, valtype, raw_buffer, virtual_buffer) - int regnum; - struct type *valtype; - char *raw_buffer; - char *virtual_buffer; + int regnum; + struct type *valtype; + char *raw_buffer; + char *virtual_buffer; { if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum)) { @@ -1301,10 +1319,10 @@ alpha_register_convert_to_virtual (regnum, valtype, raw_buffer, virtual_buffer) void alpha_register_convert_to_raw (valtype, regnum, virtual_buffer, raw_buffer) - struct type *valtype; - int regnum; - char *virtual_buffer; - char *raw_buffer; + struct type *valtype; + int regnum; + char *virtual_buffer; + char *raw_buffer; { if (TYPE_LENGTH (valtype) >= REGISTER_RAW_SIZE (regnum)) { @@ -1336,9 +1354,9 @@ alpha_register_convert_to_raw (valtype, regnum, virtual_buffer, raw_buffer) void alpha_extract_return_value (valtype, regbuf, valbuf) - struct type *valtype; - char regbuf[REGISTER_BYTES]; - char *valbuf; + struct type *valtype; + char regbuf[REGISTER_BYTES]; + char *valbuf; { if (TYPE_CODE (valtype) == TYPE_CODE_FLT) alpha_register_convert_to_virtual (FP0_REGNUM, valtype, @@ -1353,13 +1371,13 @@ alpha_extract_return_value (valtype, regbuf, valbuf) void alpha_store_return_value (valtype, valbuf) - struct type *valtype; - char *valbuf; + struct type *valtype; + char *valbuf; { char raw_buffer[MAX_REGISTER_RAW_SIZE]; int regnum = V0_REGNUM; int length = TYPE_LENGTH (valtype); - + if (TYPE_CODE (valtype) == TYPE_CODE_FLT) { regnum = FP0_REGNUM; |