diff options
-rw-r--r-- | gdb/29k-share/udi/udip2soc.c | 428 | ||||
-rw-r--r-- | gdb/am29k-pinsn.c | 12 | ||||
-rw-r--r-- | gdb/am29k-tdep.c | 210 | ||||
-rw-r--r-- | gdb/remote-udi.c | 210 | ||||
-rw-r--r-- | gdb/tm-29k.h | 101 |
5 files changed, 592 insertions, 369 deletions
diff --git a/gdb/29k-share/udi/udip2soc.c b/gdb/29k-share/udi/udip2soc.c index a9c9991..d37c496 100644 --- a/gdb/29k-share/udi/udip2soc.c +++ b/gdb/29k-share/udi/udip2soc.c @@ -65,8 +65,6 @@ extern char* getenv(); #define SBUF_SIZE 500 /* size of string buffer */ #define ERRMSG_SIZE 500 /* size of error message buffer */ -#define errmsg_m {int ii; for(ii=0; ii<ERRMSG_SIZE; ii++) dfe_errmsg[ii]=0;} - typedef struct connection_str /* record of connect session */ { int in_use; @@ -114,21 +112,26 @@ LOCAL char config_file[80]; /* path/name for config file */ * soc2cayman AF_INET cayman 7000 <not supported> * soc2tip AF_UNIX astring tip.exe ... */ +UDIError UDIConnect(Config, Session) -char* Config; /* in -- identification string */ -UDISessionId *Session; /* out -- session ID */ + char *Config; /* in -- identification string */ + UDISessionId *Session; /* out -- session ID */ { UDIInt32 service_id = UDIConnect_c; int domain; int cnt=0; - int rcnt, pos, fd, params_pos=0; + int rcnt, pos, params_pos=0; char *tip_main_string; char *env_p; struct hostent *tip_info_p; + FILE *fd; +#if 0 FILE *f_p; +#endif UDIUInt32 TIPIPCId; UDIUInt32 DFEIPCId; +#if 0 /* This is crap. It assumes that udi_soc is executable! */ sprintf(sbuf, "which udi_soc"); f_p = popen(sbuf, "r"); if(f_p) @@ -136,115 +139,102 @@ UDISessionId *Session; /* out -- session ID */ sbuf[cnt-2]=0; } pclose(f_p); - errmsg_m; - for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++) - if(!session[rcnt].in_use) break; - if(rcnt >= MAX_SESSIONS) - { - sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open"); - return UDIErrorIPCLimitation; - } +#endif + + for (rcnt=0; + rcnt < MAX_SESSIONS && session[rcnt].in_use; + rcnt++); + + if (rcnt >= MAX_SESSIONS) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many sessions already open"); + return UDIErrorIPCLimitation; + } + /* One connection can be multiplexed between several sessions. */ - for (cnt=0; cnt < MAX_SESSIONS; cnt++) - if(!soc_con[cnt].in_use) break; - if(cnt >= MAX_SESSIONS) - { - sprintf(dfe_errmsg, "DFE-ipc ERROR: Too many connections already open"); + + for (cnt=0; + cnt < MAX_SESSIONS && soc_con[cnt].in_use; + cnt++); + + if (cnt >= MAX_SESSIONS) + { + sprintf(dfe_errmsg, + "DFE-ipc ERROR: Too many connections already open"); return UDIErrorIPCLimitation; - } + } + *Session = rcnt; session[rcnt].soc_con_p = &soc_con[cnt]; - if(strchr(Config, ' ')) /* test if file entry given */ - { + if (strchr(Config, ' ')) /* test if file entry given */ + { soc_con[cnt].in_use = TRUE; sscanf(Config, "%s %s %s %s %n", - soc_con[cnt].connect_id, - soc_con[cnt].domain_string, - soc_con[cnt].tip_string, - soc_con[cnt].tip_exe, - ¶ms_pos); + soc_con[cnt].connect_id, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + soc_con[cnt].tip_exe, + ¶ms_pos); tip_main_string = Config + params_pos; - } + } else /* here if need to read udi_soc file */ - { - fd = -1; + { + strcpy(config_file, "udi_soc"); env_p = getenv("UDICONF"); - if(env_p) - { sprintf(config_file, "%s", env_p); /* path includes file name */ - fd = open(config_file, O_RDONLY); - } - if(fd == -1) - { fd = open("udi_soc", O_RDONLY); - strcpy(config_file, "udi_soc"); - } - if(fd == -1) - { fd = open(sbuf, O_RDONLY); - strcpy(config_file, sbuf); - } - if(fd == -1) - { sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ", - sys_errlist[errno]); - return UDIErrorCantOpenConfigFile; - } - while(1) - { pos = 0; - while((rcnt = read(fd, &sbuf[pos], 1)) != -1)/* read a line */ - { if (sbuf[pos] == '\n' || rcnt == 0 ) - break; - pos += 1; - } - sbuf[pos] = 0; /* terminate string */ - sscanf(sbuf, "%s %s %s %s %n", - soc_con[cnt].connect_id, - soc_con[cnt].domain_string, - soc_con[cnt].tip_string, - soc_con[cnt].tip_exe, - ¶ms_pos); - if( strcmp(Config, soc_con[cnt].connect_id) - || rcnt == -1 || rcnt == 0) - if(rcnt == -1 || rcnt == 0) - { sprintf(dfe_errmsg, - "UDIConnect, can't find entry in udi_soc file"); - return UDIErrorNoSuchConfiguration; - } - else - continue; - soc_con[cnt].in_use = TRUE; /* here if entry found */ - tip_main_string = sbuf + params_pos; + if (env_p) + strcpy(config_file, env_p); + + fd = fopen(config_file, "r"); + + if (!fd) + { + sprintf(dfe_errmsg, "UDIConnect, can't open udi_soc file:\n%s ", + sys_errlist[errno]); + dfe_errno = UDIErrorCantOpenConfigFile; + goto tip_failure; + } + + while (1) + { + if (fscanf(fd, "%s %s %s %s %[^\n]\n", + soc_con[cnt].connect_id, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + soc_con[cnt].tip_exe, + sbuf) == EOF) + break; + + if (strcmp(Config, soc_con[cnt].connect_id) != 0) + continue; + + soc_con[cnt].in_use = TRUE; /* here if entry found */ + + tip_main_string = sbuf; break; - } - close(fd); - } -/*-------------------------------------------------------------- '*' SOC_ID */ - if( *soc_con[cnt].tip_string == '*' - && *soc_con[cnt+1].tip_string == 0) - { - rcnt = 0; - pos = getpid(); - do - { - sprintf(soc_con[cnt].tip_string,"/tmp/U%d", pos++); - fd = open(soc_con[cnt].tip_string, O_CREAT); - if(rcnt++ > 20) - { sprintf(dfe_errmsg, - "DFE-ipc ERROR, can't create random socket name\n"); - return UDIErrorCantConnect; - } - } while(fd == -1); - close(fd); - unlink(soc_con[cnt].tip_string); - } + } + + fclose(fd); + if (!soc_con[cnt].in_use) + { + sprintf(dfe_errmsg, + "UDIConnect, can't find `%s' entry in udi_soc file", + Config); + dfe_errno = UDIErrorNoSuchConfiguration; + goto tip_failure; + } + } /*----------------------------------------------------------- SELECT DOMAIN */ - if(!strcmp(soc_con[cnt].domain_string, "AF_UNIX")) - domain = AF_UNIX; - else if(!strcmp(soc_con[cnt].domain_string, "AF_INET")) - domain = AF_INET; + if (strcmp(soc_con[cnt].domain_string, "AF_UNIX") == 0) + domain = AF_UNIX; + else if (strcmp(soc_con[cnt].domain_string, "AF_INET") == 0) + domain = AF_INET; else - { errmsg_m; + { sprintf(dfe_errmsg, "DFE-ipc ERROR: socket address family not known"); - return UDIErrorBadConfigFileEntry; - } + dfe_errno = UDIErrorBadConfigFileEntry; + goto tip_failure; + } /*---------------------------------------------------- MULTIPLEXED SOCKET ? */ /* If the requested session requires communication with @@ -254,127 +244,188 @@ UDISessionId *Session; /* out -- session ID */ socket-name/host-name and the domain are the same. */ for (rcnt=0; rcnt < MAX_SESSIONS; rcnt++) - { if( soc_con[rcnt].in_use - && !strcmp(soc_con[cnt].domain_string, soc_con[rcnt].domain_string) - && !strcmp(soc_con[cnt].tip_string, soc_con[rcnt].tip_string) - && rcnt != cnt ) - { + { + if (soc_con[rcnt].in_use + && rcnt != cnt + && strcmp(soc_con[cnt].domain_string, + soc_con[rcnt].domain_string) == 0 + && strcmp(soc_con[cnt].tip_string, + soc_con[rcnt].tip_string) == 0) + { session[*Session].soc_con_p = &soc_con[rcnt]; soc_con[cnt].in_use = FALSE; /* don't need new connect */ goto tip_connect; } - } + } /*------------------------------------------------------------------ SOCKET */ soc_con[cnt].dfe_sd = socket(domain, SOCK_STREAM, 0); - if (soc_con[cnt].dfe_sd == -1 ) - { errmsg_m; + if (soc_con[cnt].dfe_sd == -1) + { sprintf(dfe_errmsg, "DFE-ipc ERROR, socket() call failed %s ", - sys_errlist[errno]); - UDIKill(cnt); - } + sys_errlist[errno]); + dfe_errno = UDIErrorUnknownError; + goto tip_failure; + } /*--------------------------------------------------------- AF_UNIX CONNECT */ - if(domain == AF_UNIX) - { - memset( (char*)&soc_con[cnt].tip_sockaddr, 0, - sizeof(soc_con[cnt].tip_sockaddr)); + if (domain == AF_UNIX) + { + if (strcmp(soc_con[cnt].tip_string, "*") == 0) + { + for (pos = 0; pos < 20; pos++) + { + int f; + + sprintf(soc_con[cnt].tip_string,"/tmp/U%d", getpid() + pos); + f = open(soc_con[cnt].tip_string, O_CREAT); + if (f == -1) + continue; + + close(f); + unlink(soc_con[cnt].tip_string); + break; + } + + if (pos >= 20) + { + sprintf(dfe_errmsg, + "DFE-ipc ERROR, can't create random socket name"); + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } + } + soc_con[cnt].tip_sockaddr.sa_family = domain; bcopy(soc_con[cnt].tip_string, - soc_con[cnt].tip_sockaddr.sa_data, - sizeof(soc_con[cnt].tip_sockaddr.sa_data) ); - if(connect(soc_con[cnt].dfe_sd, - &soc_con[cnt].tip_sockaddr, - sizeof(soc_con[cnt].tip_sockaddr)) == -1) - { /* if connect() fails assume TIP not yet started */ + soc_con[cnt].tip_sockaddr.sa_data, + sizeof(soc_con[cnt].tip_sockaddr.sa_data)); + if (connect(soc_con[cnt].dfe_sd, + &soc_con[cnt].tip_sockaddr, + sizeof(soc_con[cnt].tip_sockaddr))) + { /* if connect() fails assume TIP not yet started */ /*------------------------------------------------------------ AF_UNIX EXEC */ int pid; - union wait statusp; - char* arg0 = strrchr(soc_con[cnt].tip_exe,'/'); + union wait statusp; + char *arg0; + + arg0 = strrchr(soc_con[cnt].tip_exe,'/'); - if(!arg0) arg0 = soc_con[cnt].tip_exe; - else arg0++; + if (arg0) + arg0++; + else + arg0 = soc_con[cnt].tip_exe; - if((pid = fork()) == 0) - { execlp( - soc_con[cnt].tip_exe, - arg0, - soc_con[cnt].domain_string, - soc_con[cnt].tip_string, - NULL); - exit(1); - } - if(wait4(pid, &statusp, WNOHANG, NULL)) - { - sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP\n"); - return UDIErrorCantStartTIP; - } - sleep(2); - /* not TIP is running, try conect() again */ - if(connect(soc_con[cnt].dfe_sd, - &soc_con[cnt].tip_sockaddr, - sizeof(soc_con[cnt].tip_sockaddr)) == -1) - { sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s", + pid = vfork(); + + if (pid == 0) /* Child */ + { + execlp(soc_con[cnt].tip_exe, + arg0, + soc_con[cnt].domain_string, + soc_con[cnt].tip_string, + NULL); + _exit(1); + } + + if (wait4(pid, &statusp, WNOHANG, NULL)) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR: can't exec the TIP"); + dfe_errno = UDIErrorCantStartTIP; + goto tip_failure; + } + + pos = 3; + for (pos = 3; pos > 0; pos--) + { + if (!connect(soc_con[cnt].dfe_sd, + &soc_con[cnt].tip_sockaddr, + sizeof(soc_con[cnt].tip_sockaddr))) + break; + sleep(1); + } + + if (pos == 0) + { + sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed: %s", sys_errlist[errno]); - return UDIErrorCantConnect; - } + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } } - } + } /*--------------------------------------------------------- AF_INET CONNECT */ - if(domain == AF_INET) - { - fprintf(stderr,"DFE-ipc WARNING, need to have first started remote TIP\n"); - memset( (char*)&soc_con[cnt].tip_sockaddr_in, 0, - sizeof(soc_con[cnt].tip_sockaddr_in)); + else if (domain == AF_INET) + { + fprintf(stderr, + "DFE-ipc WARNING, need to have first started remote TIP"); + soc_con[cnt].tip_sockaddr_in.sin_family = domain; soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr = inet_addr(soc_con[cnt].tip_string); - if( soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1) - { + if (soc_con[cnt].tip_sockaddr_in.sin_addr.s_addr == -1) + { tip_info_p = gethostbyname(soc_con[cnt].tip_string); - if( tip_info_p == NULL) - { errmsg_m; - sprintf(dfe_errmsg,"DFE-ipc ERROR, %s not found in /etc/hosts", - soc_con[cnt].tip_string); - return UDIErrorNoSuchConnection; - } + if (tip_info_p == NULL) + { + sprintf(dfe_errmsg,"DFE-ipc ERROR, No such host %s", + soc_con[cnt].tip_string); + dfe_errno = UDIErrorNoSuchConnection; + goto tip_failure; + } bcopy(tip_info_p->h_addr, - (char *)&soc_con[cnt].tip_sockaddr_in.sin_addr, - tip_info_p->h_length); - } - soc_con[cnt].tip_sockaddr_in.sin_port=htons(atoi(soc_con[cnt].tip_exe)); - if(connect(soc_con[cnt].dfe_sd, - &soc_con[cnt].tip_sockaddr_in, - sizeof(soc_con[cnt].tip_sockaddr_in)) == -1) - { errmsg_m; + (char *)&soc_con[cnt].tip_sockaddr_in.sin_addr, + tip_info_p->h_length); + } + soc_con[cnt].tip_sockaddr_in.sin_port + = htons(atoi(soc_con[cnt].tip_exe)); + + if (connect(soc_con[cnt].dfe_sd, + &soc_con[cnt].tip_sockaddr_in, + sizeof(soc_con[cnt].tip_sockaddr_in))) + { sprintf(dfe_errmsg, "DFE-ipc ERROR, connect() call failed %s ", - sys_errlist[errno]); - return UDIErrorCantConnect; - } - } + sys_errlist[errno]); + dfe_errno = UDIErrorCantConnect; + goto tip_failure; + } + } /*------------------------------------------------------------- TIP CONNECT */ - if(cnt ==0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE); + if (cnt == 0) udr_create(udrs, soc_con[cnt].dfe_sd, SOC_BUF_SIZE); + tip_connect: current = cnt; - session[*Session].in_use = TRUE; /* session id is now in use*/ + session[*Session].in_use = TRUE; /* session id is now in use */ udr_errno = 0; udrs->udr_op = UDR_ENCODE; /* send all "in" parameters */ udr_UDIInt32(udrs, &service_id); + DFEIPCId = (company_c << 16) + (product_c << 12) + version_c; udr_UDIUInt32(udrs, &DFEIPCId); + udr_string(udrs, tip_main_string); + udr_sendnow(udrs); udrs->udr_op = UDR_DECODE; /* recv all "out" parameters */ udr_UDIUInt32(udrs, &TIPIPCId); - if ((TIPIPCId & 0xfff) < version_c) { - fprintf(stderr, "DFE-ipc: Obsolete TIP Specified\n"); - return(UDIErrorExecutableNotTIP); - } + if ((TIPIPCId & 0xfff) < version_c) + sprintf(dfe_errmsg, "DFE-ipc: Obsolete TIP Specified"); + udr_UDIInt32(udrs, &soc_con[cnt].tip_pid); + udr_UDISessionId(udrs, &session[*Session].tip_id); + udr_UDIError(udrs, &dfe_errno); - if(dfe_errno > 0) UDIKill(Session, 0); + if (dfe_errno > 0) UDIKill(Session, 0); + + return dfe_errno; + +tip_failure: + + soc_con[cnt].in_use = FALSE; + session[*Session].in_use = FALSE; +/* XXX - Should also close dfe_sd, but not sure what to do if muxed */ return dfe_errno; } @@ -389,7 +440,7 @@ UDIBool Terminate; int cnt; UDIInt32 service_id = UDIDisconnect_c; if(Session < 0 || Session > MAX_SESSIONS) - { errmsg_m; + { sprintf(dfe_errmsg," SessionId not valid (%d)", Session); return UDIErrorNoSuchConfiguration; } @@ -407,7 +458,7 @@ UDIBool Terminate; ) break; if(cnt >= MAX_SESSIONS) /* test if socket not multiplexed */ if(shutdown(session[Session].soc_con_p->dfe_sd, 2)) - { errmsg_m; + { sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed"); return UDIErrorIPCInternal; } @@ -428,7 +479,7 @@ UDIInt32 Signal; int cnt; UDIInt32 service_id = UDIKill_c; if(Session < 0 || Session > MAX_SESSIONS) - { errmsg_m; + { sprintf(dfe_errmsg," SessionId not valid (%d)", Session); return UDIErrorNoSuchConfiguration; } @@ -446,7 +497,7 @@ UDIInt32 Signal; ) break; if(cnt < MAX_SESSIONS) /* test if socket not multiplexed */ if(shutdown(session[Session].soc_con_p->dfe_sd, 2)) - { errmsg_m; + { sprintf(dfe_errmsg, "DFE-ipc WARNING: socket shutdown failed"); return UDIErrorIPCInternal; } @@ -862,10 +913,13 @@ UDIRange range; /* in -- range if StepInRange is TRUE */ */ UDIVoid UDIStop() { - if(!strcmp(session[current].soc_con_p->domain_string, "AF_UNIX")) - kill(session[current].soc_con_p->tip_pid, SIGUSR1); + if (strcmp(session[current].soc_con_p->domain_string, "AF_UNIX") == 0) + kill(session[current].soc_con_p->tip_pid, SIGINT); else - udr_signal(udrs); + udr_signal(udrs); + +/* XXX - should clean up session[] and soc_con[] structs here as well... */ + return; } diff --git a/gdb/am29k-pinsn.c b/gdb/am29k-pinsn.c index c226a3a..bfb2f14 100644 --- a/gdb/am29k-pinsn.c +++ b/gdb/am29k-pinsn.c @@ -18,9 +18,11 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <stdio.h> + #include "defs.h" #include "target.h" -#include "am29k-opcode.h" +#include "opcode/a29k.h" /* Print a symbolic representation of a general-purpose register number NUM on STREAM. @@ -127,7 +129,7 @@ print_insn (memaddr, stream) /* The four bytes of the instruction. */ unsigned char insn24, insn16, insn8, insn0; - struct am29k_opcode *opcode; + struct a29k_opcode *opcode; read_memory (memaddr, &insn[0], 4); @@ -140,11 +142,11 @@ print_insn (memaddr, stream) } /* The opcode is always in insn24. */ - for (opcode = &am29k_opcodes[0]; - opcode < &am29k_opcodes[NUM_OPCODES]; + for (opcode = &a29k_opcodes[0]; + opcode < &a29k_opcodes[num_opcodes]; ++opcode) { - if (insn24 == opcode->opcode) + if ((insn24<<24) == opcode->opcode) { char *s; diff --git a/gdb/am29k-tdep.c b/gdb/am29k-tdep.c index 3c9de829..4d52f99 100644 --- a/gdb/am29k-tdep.c +++ b/gdb/am29k-tdep.c @@ -20,8 +20,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "gdbcore.h" +#include <stdio.h> #include "frame.h" #include "value.h" +/*#include <sys/param.h> */ #include "symtab.h" #include "inferior.h" @@ -136,9 +138,12 @@ examine_prologue (pc, rsize, msize, mfp_used) } p += 4; - /* Next instruction must be asgeu V_SPILL,gr1,rab. */ + /* Next instruction must be asgeu V_SPILL,gr1,rab. + * We don't check the vector number to allow for kernel debugging. The + * kernel will use a different trap number. + */ insn = read_memory_integer (p, 4); - if (insn != 0x5e40017e) + if ((insn & 0xff00ffff) != (0x5e000100|RAB_HW_REGNUM)) { p = pc; goto done; @@ -148,7 +153,10 @@ examine_prologue (pc, rsize, msize, mfp_used) /* Next instruction usually sets the frame pointer (lr1) by adding <size * 4> from gr1. However, this can (and high C does) be deferred until anytime before the first function call. So it is - OK if we don't see anything which sets lr1. */ + OK if we don't see anything which sets lr1. + To allow for alternate register sets (gcc -mkernel-registers) the msp + register number is a compile time constant. */ + /* Normally this is just add lr1,gr1,<size * 4>. */ insn = read_memory_integer (p, 4); if ((insn & 0xffffff00) == 0x15810100) @@ -178,14 +186,16 @@ examine_prologue (pc, rsize, msize, mfp_used) we don't check this rsize against the first instruction, and we don't check that the trace-back tag indicates a memory frame pointer is in use. + To allow for alternate register sets (gcc -mkernel-registers) the msp + register number is a compile time constant. The recommended instruction is actually "sll lr<whatever>,msp,0". We check for that, too. Originally Jim Kingdon's code seemed to be looking for a "sub" instruction here, but the mask was set up to lose all the time. */ insn = read_memory_integer (p, 4); - if (((insn & 0xff80ffff) == 0x15807d00) /* add */ - || ((insn & 0xff80ffff) == 0x81807d00) ) /* sll */ + if (((insn & 0xff80ffff) == (0x15800000|(MSP_HW_REGNUM<<8))) /* add */ + || ((insn & 0xff80ffff) == (0x81800000|(MSP_HW_REGNUM<<8)))) /* sll */ { p += 4; if (mfp_used != NULL) @@ -196,14 +206,18 @@ examine_prologue (pc, rsize, msize, mfp_used) but only if a memory frame is being used. We don't check msize against the trace-back tag. + To allow for alternate register sets (gcc -mkernel-registers) the msp + register number is a compile time constant. + Normally this is just sub msp,msp,<msize> */ insn = read_memory_integer (p, 4); - if ((insn & 0xffffff00) == 0x257d7d00) + if ((insn & 0xffffff00) == + (0x25000000|(MSP_HW_REGNUM<<16)|(MSP_HW_REGNUM<<8))) { p += 4; - if (msize != NULL) + if (msize != NULL) *msize = insn & 0xff; } else @@ -235,7 +249,8 @@ examine_prologue (pc, rsize, msize, mfp_used) insn = read_memory_integer (q, 4); } /* Check for sub msp,msp,<reg>. */ - if ((insn & 0xffffff00) == 0x247d7d00 + if ((insn & 0xffffff00) == + (0x24000000|(MSP_HW_REGNUM<<16)|(MSP_HW_REGNUM<<8)) && (insn & 0xff) == reg) { p = q + 4; @@ -288,6 +303,47 @@ skip_prologue (pc) return examine_prologue (pc, (unsigned *)NULL, (unsigned *)NULL, (int *)NULL); } +/* + * Examine the one or two word tag at the beginning of a function. + * The tag word is expect to be at 'p', if it is not there, we fail + * by returning 0. The documentation for the tag word was taken from + * page 7-15 of the 29050 User's Manual. We are assuming that the + * m bit is in bit 22 of the tag word, which seems to be the agreed upon + * convention today (1/15/92). + * msize is return in bytes. + */ +static int /* 0/1 - failure/success of finding the tag word */ +examine_tag(p, is_trans, argcount, msize, mfp_used) + CORE_ADDR p; + int *is_trans; + int *argcount; + unsigned *msize; + int *mfp_used; +{ + unsigned int tag1, tag2; + + tag1 = read_memory_integer (p, 4); + if ((tag1 & 0xff000000) != 0) /* Not a tag word */ + return 0; + if (tag1 & (1<<23)) /* A two word tag */ + { + tag2 = read_memory_integer (p+4, 4); + if (msize) + *msize = tag2; + } + else /* A one word tag */ + { + if (msize) + *msize = tag1 & 0x7ff; + } + if (is_trans) + *is_trans = ((tag1 & (1<<21)) ? 1 : 0); + if (argcount) + *argcount = (tag1 >> 16) & 0x1f; + if (mfp_used) + *mfp_used = ((tag1 & (1<<22)) ? 1 : 0); + return(1); +} /* Initialize the frame. In addition to setting "extra" frame info, we also set ->frame because we use it in a nonstandard way, and ->pc @@ -302,7 +358,7 @@ init_frame_info (innermost_frame, fci) long insn; unsigned rsize; unsigned msize; - int mfp_used; + int mfp_used, trans; struct symbol *func; p = fci->pc; @@ -325,6 +381,7 @@ init_frame_info (innermost_frame, fci) /* Dummy frames always use a memory frame pointer. */ fci->saved_msp = read_register_stack_integer (fci->frame + DUMMY_FRAME_RSIZE - 4, 4); + fci->flags |= (TRANSPARENT|MFP_USED); return; } @@ -347,6 +404,7 @@ init_frame_info (innermost_frame, fci) fci->saved_msp = 0; fci->rsize = 0; fci->msize = 0; + fci->flags = TRANSPARENT; return; } else @@ -354,13 +412,25 @@ init_frame_info (innermost_frame, fci) after the trace-back tag. */ p += 4; } - /* We've found the start of the function. Since High C interchanges - the meanings of bits 23 and 22 (as of Jul 90), and we - need to look at the prologue anyway to figure out - what rsize is, ignore the contents of the trace-back tag. */ - examine_prologue (p, &rsize, &msize, &mfp_used); + /* We've found the start of the function. + * Try looking for a tag word that indicates whether there is a + * memory frame pointer and what the memory stack allocation is. + * If one doesn't exist, try using a more exhaustive search of + * the prologue. For now we don't care about the argcount or + * whether or not the routine is transparent. + */ + if (examine_tag(p-4,&trans,NULL,&msize,&mfp_used)) /* Found a good tag */ + examine_prologue (p, &rsize, 0, 0); + else /* No tag try prologue */ + examine_prologue (p, &rsize, &msize, &mfp_used); + fci->rsize = rsize; fci->msize = msize; + fci->flags = 0; + if (mfp_used) + fci->flags |= MFP_USED; + if (trans) + fci->flags |= TRANSPARENT; if (innermost_frame) { fci->saved_msp = read_register (MSP_REGNUM) + msize; @@ -368,10 +438,10 @@ init_frame_info (innermost_frame, fci) else { if (mfp_used) - fci->saved_msp = - read_register_stack_integer (fci->frame + rsize - 1, 4); + fci->saved_msp = + read_register_stack_integer (fci->frame + rsize - 4, 4); else - fci->saved_msp = fci->next->saved_msp + msize; + fci->saved_msp = fci->next->saved_msp + msize; } } @@ -397,7 +467,7 @@ init_frame_pc (fromleaf, fci) { fci->pc = (fromleaf ? SAVED_PC_AFTER_CALL (fci->next) : fci->next ? FRAME_SAVED_PC (fci->next) : read_pc ()); - init_frame_info (0, fci); + init_frame_info (fromleaf, fci); } /* Local variables (i.e. LOC_LOCAL) are on the memory stack, with their @@ -408,9 +478,7 @@ CORE_ADDR frame_locals_address (fi) struct frame_info *fi; { - struct block *b = block_for_pc (fi->pc); - /* If compiled without -g, assume GCC. */ - if (b == NULL || BLOCK_GCC_COMPILED (b)) + if (fi->flags & MFP_USED) return fi->saved_msp; else return fi->saved_msp - fi->msize; @@ -435,6 +503,24 @@ read_register_stack (memaddr, myaddr, actual_mem_addr, lval) { long rfb = read_register (RFB_REGNUM); long rsp = read_register (RSP_REGNUM); + +#ifdef RSTACK_HIGH_ADDR /* Highest allowed address in register stack */ + /* If we don't do this 'info register' stops in the middle. */ + if (memaddr >= RSTACK_HIGH_ADDR) + { + int val=-1; /* a bogus value */ + /* It's in a local register, but off the end of the stack. */ + int regnum = (memaddr - rsp) / 4 + LR0_REGNUM; + if (myaddr != NULL) + *(int*)myaddr = val; /* Provide bogusness */ + supply_register(regnum,&val); /* More bogusness */ + if (lval != NULL) + *lval = lval_register; + if (actual_mem_addr != NULL) + *actual_mem_addr = REGISTER_BYTE (regnum); + } + else +#endif /* RSTACK_HIGH_ADDR */ if (memaddr < rfb) { /* It's in a register. */ @@ -451,8 +537,8 @@ read_register_stack (memaddr, myaddr, actual_mem_addr, lval) else { /* It's in the memory portion of the register stack. */ - if (myaddr != NULL) - read_memory (memaddr, myaddr, 4); + if (myaddr != NULL) + read_memory (memaddr, myaddr, 4); if (lval != NULL) *lval = lval_memory; if (actual_mem_addr != NULL) @@ -484,6 +570,16 @@ write_register_stack (memaddr, myaddr, actual_mem_addr) { long rfb = read_register (RFB_REGNUM); long rsp = read_register (RSP_REGNUM); +#ifdef RSTACK_HIGH_ADDR /* Highest allowed address in register stack */ + /* If we don't do this 'info register' stops in the middle. */ + if (memaddr >= RSTACK_HIGH_ADDR) + { + /* It's in a register, but off the end of the stack. */ + if (actual_mem_addr != NULL) + *actual_mem_addr = NULL; + } + else +#endif /* RSTACK_HIGH_ADDR */ if (memaddr < rfb) { /* It's in a register. */ @@ -493,7 +589,7 @@ write_register_stack (memaddr, myaddr, actual_mem_addr) if (myaddr != NULL) write_register (regnum, *(long *)myaddr); if (actual_mem_addr != NULL) - *actual_mem_addr = 0; + *actual_mem_addr = NULL; } else { @@ -521,10 +617,15 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp) int regnum; enum lval_type *lvalp; { - struct frame_info *fi = get_frame_info (frame); + struct frame_info *fi; CORE_ADDR addr; enum lval_type lval; + if (frame == 0) + return; + + fi = get_frame_info (frame); + /* Once something has a register number, it doesn't get optimized out. */ if (optimized != NULL) *optimized = 0; @@ -583,6 +684,7 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lvalp) *addrp = addr; } + /* Discard from the stack the innermost frame, restoring all saved registers. */ @@ -594,7 +696,6 @@ pop_frame () CORE_ADDR rfb = read_register (RFB_REGNUM); CORE_ADDR gr1 = fi->frame + fi->rsize; CORE_ADDR lr1; - CORE_ADDR ret_addr; int i; /* If popping a dummy frame, need to restore registers. */ @@ -602,14 +703,16 @@ pop_frame () read_register (SP_REGNUM), FRAME_FP (fi))) { + int lrnum = LR0_REGNUM + DUMMY_ARG/4; for (i = 0; i < DUMMY_SAVE_SR128; ++i) - write_register - (SR_REGNUM (i + 128), - read_register (LR0_REGNUM + DUMMY_ARG / 4 + i)); + write_register (SR_REGNUM (i + 128),read_register (lrnum++)); + for (i = 0; i < DUMMY_SAVE_SR160; ++i) + write_register (SR_REGNUM(i+160), read_register (lrnum++)); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) - write_register - (RETURN_REGNUM + i, - read_register (LR0_REGNUM + DUMMY_ARG / 4 + DUMMY_SAVE_SR128 + i)); + write_register (RETURN_REGNUM + i, read_register (lrnum++)); + /* Restore the PCs. */ + write_register(PC_REGNUM, read_register (lrnum++)); + write_register(NPC_REGNUM, read_register (lrnum)); } /* Restore the memory stack pointer. */ @@ -633,9 +736,6 @@ pop_frame () write_register (LR0_REGNUM + ((rfb - gr1) % 0x80) + i / 4, word); } } - ret_addr = read_register (LR0_REGNUM); - write_register (PC_REGNUM, ret_addr); - write_register (NPC_REGNUM, ret_addr + 4); flush_cached_frames (); set_current_frame (create_new_frame (0, read_pc())); } @@ -648,12 +748,10 @@ push_dummy_frame () long w; CORE_ADDR rab, gr1; CORE_ADDR msp = read_register (MSP_REGNUM); - int i; + int lrnum, i, saved_lr0; - /* Save the PC. */ - write_register (LR0_REGNUM, read_register (PC_REGNUM)); - /* Allocate the new frame. */ + /* Allocate the new frame. */ gr1 = read_register (GR1_REGNUM) - DUMMY_FRAME_RSIZE; write_register (GR1_REGNUM, gr1); @@ -671,8 +769,8 @@ push_dummy_frame () for (i = 0; i < num_bytes; i += 4) { /* Note: word is in target byte order. */ - read_register_gen (LR0_REGNUM + i / 4, (char *)&word); - write_memory (rfb - num_bytes + i, (char *)&word, 4); + read_register_gen (LR0_REGNUM + i / 4, &word, 4); + write_memory (rfb - num_bytes + i, &word, 4); } } @@ -687,10 +785,32 @@ push_dummy_frame () write_register (MSP_REGNUM, msp - 16 * 4); /* Save registers. */ + lrnum = LR0_REGNUM + DUMMY_ARG/4; for (i = 0; i < DUMMY_SAVE_SR128; ++i) - write_register (LR0_REGNUM + DUMMY_ARG / 4 + i, - read_register (SR_REGNUM (i + 128))); + write_register (lrnum++, read_register (SR_REGNUM (i + 128))); + for (i = 0; i < DUMMY_SAVE_SR160; ++i) + write_register (lrnum++, read_register (SR_REGNUM (i + 160))); for (i = 0; i < DUMMY_SAVE_GREGS; ++i) - write_register (LR0_REGNUM + DUMMY_ARG / 4 + DUMMY_SAVE_SR128 + i, - read_register (RETURN_REGNUM + i)); + write_register (lrnum++, read_register (RETURN_REGNUM + i)); + /* Save the PCs. */ + write_register (lrnum++, read_register (PC_REGNUM)); + write_register (lrnum, read_register (NPC_REGNUM)); +} + +reginv_com (args, fromtty) + char *args; + int fromtty; +{ + registers_changed(); + if (fromtty) + printf_filtered("Gdb's register cache invalidated.\n"); } + +/* We use this mostly for debugging gdb */ +void +_initialize_29k() +{ + add_com ("reginv ", class_obscure, reginv_com, + "Invalidate gdb's internal register cache."); +} + diff --git a/gdb/remote-udi.c b/gdb/remote-udi.c index 95613ed..0030047 100644 --- a/gdb/remote-udi.c +++ b/gdb/remote-udi.c @@ -184,6 +184,8 @@ udi_create_inferior (execfile, args, env) return; } + inferior_pid = 40000; + #if defined(ULTRA3) && defined(KERNEL_DEBUGGING) /* On ultra3 (NYU) we assume the kernel is already running so there is * no file to download @@ -221,6 +223,8 @@ udi_mourn() '<udi_udi_config_id> [progname]' for example. */ +/* XXX - need cleanups for udiconnect for various failures!!! */ + static char *udi_config_id; static void udi_open (name, from_tty) @@ -239,6 +243,8 @@ udi_open (name, from_tty) DENTER("udi_open()"); + target_preopen(from_tty); + /* Find the first whitespace character, it separates udi_config_id from prog_name. */ if(!name) goto erroid; @@ -248,6 +254,7 @@ udi_open (name, from_tty) if (*p == '\0') erroid: error("Usage: target udi config_id progname, where config_id appears in udi_soc file"); + udi_config_id = (char*)malloc (p - name + 1); strncpy (udi_config_id, name, p - name); udi_config_id[p - name] = '\0'; @@ -260,11 +267,9 @@ erroid: free (prog_name); prog_name = savestring (p, strlen (p)); - if (udi_session_id >= 0) - close (udi_session_id); + if (UDIConnect(udi_config_id, &udi_session_id)) + error("UDIConnect() failed: %s\n", dfe_errmsg); - if(UDIConnect(udi_config_id, &udi_session_id)) - fprintf(stderr, "UDIConnect() failed: %s\n", dfe_errmsg); push_target (&udi_ops); #ifndef HAVE_TERMIO @@ -272,18 +277,18 @@ erroid: /* Cause SIGALRM's to make reads fail with EINTR instead of resuming the read. */ if (siginterrupt (SIGALRM, 1) != 0) - perror ("udi_open: error in siginterrupt"); + error ("udi_open: siginterrupt() %s", safe_strerror(errno)); #endif /* Set up read timeout timer. */ if ((void (*)) signal (SIGALRM, udi_timer) == (void (*)) -1) - perror ("udi_open: error in signal"); + error ("udi_open: signal() %s", safe_strerror(errno)); #endif #if defined (LOG_FILE) log_file = fopen (LOG_FILE, "w"); if (log_file == NULL) - perror (LOG_FILE); + error ("udi_open: fopen(%s) %s", LOG_FILE, safe_strerror(errno)); #endif /* ** Initialize target configuration structure (global) @@ -386,6 +391,7 @@ udi_close (quitting) /*FIXME: how is quitting used */ /* Do not try to close udi_session_id again, later in the program. */ udi_session_id = -1; + inferior_pid = 0; #if defined (LOG_FILE) if (ferror (log_file)) @@ -394,7 +400,7 @@ udi_close (quitting) /*FIXME: how is quitting used */ printf ("Error closing log file.\n"); #endif - printf ("Ending remote debugging\n"); + printf_filtered (" Ending remote debugging\n"); DEXIT("udi_close()"); } @@ -633,89 +639,99 @@ int regno; int i; if (regno >= 0) { - fetch_register(regno); - return; + fetch_register(regno); + return; } - DENTER("udi_fetch_registers()"); /* Gr1/rsp */ + From.Space = UDI29KGlobalRegs; From.Offset = 1; - To = (UDIUInt32*)®isters[4 * GR1_REGNUM]; + To = (UDIUInt32 *)®isters[4 * GR1_REGNUM]; Count = 1; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else register_valid[4 * GR1_REGNUM] = 1; + + register_valid[GR1_REGNUM] = 1; #if defined(GR64_REGNUM) /* Read gr64-127 */ + /* Global Registers gr64-gr95 */ + From.Space = UDI29KGlobalRegs; From.Offset = 64; - To = ®isters[4 * GR64_REGNUM]; + To = (UDIUInt32 *)®isters[4 * GR64_REGNUM]; Count = 32; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else for(i = 4 * GR64_REGNUM; i < 4*GR64_REGNUM + 32; i++) + + for (i = GR64_REGNUM; i < GR64_REGNUM + 32; i++) + register_valid[i] = 1; + #endif /* GR64_REGNUM */ /* Global Registers gr96-gr127 */ + From.Space = UDI29KGlobalRegs; - From.Offset = 64; - To = (UDIUInt32*)®isters[4 * GR96_REGNUM]; + From.Offset = 96; + To = (UDIUInt32 *)®isters[4 * GR96_REGNUM]; Count = 32; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else for(i = 4 * GR96_REGNUM; i < 4*GR96_REGNUM + 32; i++) - register_valid[i] = 1; -/* Local Registers */ + for (i = GR96_REGNUM; i < GR96_REGNUM + 32; i++) + register_valid[i] = 1; + +/* Local Registers */ + From.Space = UDI29KLocalRegs; From.Offset = 0; - To = (UDIUInt32*)®isters[4 * LR0_REGNUM]; + To = (UDIUInt32 *)®isters[4 * LR0_REGNUM]; Count = 128; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else for(i = 4 * LR0_REGNUM; i < 4*LR0_REGNUM + 128; i++) - register_valid[i] = 1; -/* Protected Special Registers */ + for (i = LR0_REGNUM; i < LR0_REGNUM + 128; i++) + register_valid[i] = 1; + +/* Protected Special Registers */ + From.Space = UDI29KSpecialRegs; From.Offset = 0; - To = (UDIUInt32*)®isters[4 * SR_REGNUM(0)]; + To = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)]; Count = 15; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else for(i = 4 * SR_REGNUM(0); i < 4*SR_REGNUM(0) + 15; i++) - register_valid[i] = 1; + + for (i = SR_REGNUM(0); i < SR_REGNUM(0) + 15; i++) + register_valid[i] = 1; if (USE_SHADOW_PC) { /* Let regno_to_srnum() handle the register number */ - fetch_register(NPC_REGNUM); - fetch_register(PC_REGNUM); - fetch_register(PC2_REGNUM); - } + fetch_register(NPC_REGNUM); + fetch_register(PC_REGNUM); + fetch_register(PC2_REGNUM); -/* Unprotected Special Registers sr128-sr135*/ - if (USE_SHADOW_PC) /* Let regno_to_srnum() handle the register number */ - { From.Space = UDI29KSpecialRegs; +/* Unprotected Special Registers sr128-sr135 */ + + From.Space = UDI29KSpecialRegs; From.Offset = 128; - To = (UDIUInt32*)®isters[4 * SR_REGNUM(128)]; - Count = 135-128 +1; - if(UDIRead(From, To, Count, Size, &CountDone, HostEndian)) + To = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)]; + Count = 135-128 + 1; + if (UDIRead(From, To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - else for(i = 4 * SR_REGNUM(128); i < 4*SR_REGNUM(128) + 135-128+1; i++) - register_valid[i] = 1; + + for (i = SR_REGNUM(128); i < SR_REGNUM(128) + 135-128+1; i++) + register_valid[i] = 1; } /* There doesn't seem to be any way to get these. */ { int val = -1; supply_register (FPE_REGNUM, (char *) &val); - supply_register (INT_REGNUM, (char *) &val); + supply_register (INTE_REGNUM, (char *) &val); supply_register (FPS_REGNUM, (char *) &val); supply_register (EXO_REGNUM, (char *) &val); } - - DEXIT("udi_fetch_registerS()"); } @@ -741,10 +757,9 @@ int regno; return; } - DENTER("udi_store_registers()"); - /* Gr1/rsp */ - From = (UDIUInt32*)®isters[4 * GR1_REGNUM]; + + From = (UDIUInt32 *)®isters[4 * GR1_REGNUM]; To.Space = UDI29KGlobalRegs; To.Offset = 1; Count = 1; @@ -752,17 +767,21 @@ int regno; error("UDIWrite() failed in udi_store_regisetrs"); #if defined(GR64_REGNUM) + /* Global registers gr64-gr95 */ - From = (UDIUInt32*)®isters[4 * GR64_REGNUM]; + + From = (UDIUInt32 *)®isters[4 * GR64_REGNUM]; To.Space = UDI29KGlobalRegs; To.Offset = 64; Count = 32; if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian)) error("UDIWrite() failed in udi_store_regisetrs"); + #endif /* GR64_REGNUM */ /* Global registers gr96-gr127 */ - From = (UDIUInt32*)®isters[4 * GR96_REGNUM]; + + From = (UDIUInt32 *)®isters[4 * GR96_REGNUM]; To.Space = UDI29KGlobalRegs; To.Offset = 96; Count = 32; @@ -770,7 +789,8 @@ int regno; error("UDIWrite() failed in udi_store_regisetrs"); /* Local Registers */ - From = (UDIUInt32*)®isters[4 * LR0_REGNUM]; + + From = (UDIUInt32 *)®isters[4 * LR0_REGNUM]; To.Space = UDI29KLocalRegs; To.Offset = 0; Count = 128; @@ -779,15 +799,17 @@ int regno; /* Protected Special Registers */ /* VAB through TMR */ - From = (UDIUInt32*)®isters[4 * SR_REGNUM(0)]; + + From = (UDIUInt32 *)®isters[4 * SR_REGNUM(0)]; To.Space = UDI29KSpecialRegs; To.Offset = 0; Count = 10; if(UDIWrite(From, To, Count, Size, &CountDone, HostEndian)) error("UDIWrite() failed in udi_store_regisetrs"); - /* PC0, PC1, PC2 possibly as shadow registers */ - From = (UDIUInt32*)®isters[4 * SR_REGNUM(10)]; +/* PC0, PC1, PC2 possibly as shadow registers */ + + From = (UDIUInt32 *)®isters[4 * SR_REGNUM(10)]; To.Space = UDI29KSpecialRegs; Count = 3; if (USE_SHADOW_PC) @@ -798,7 +820,8 @@ int regno; error("UDIWrite() failed in udi_store_regisetrs"); /* LRU and MMU */ - From = (UDIUInt32*)®isters[4 * SR_REGNUM(13)]; + + From = (UDIUInt32 *)®isters[4 * SR_REGNUM(13)]; To.Space = UDI29KSpecialRegs; To.Offset = 13; Count = 2; @@ -806,7 +829,8 @@ int regno; error("UDIWrite() failed in udi_store_regisetrs"); /* Unprotected Special Registers */ - From = (UDIUInt32*)®isters[4 * SR_REGNUM(128)]; + + From = (UDIUInt32 *)®isters[4 * SR_REGNUM(128)]; To.Space = UDI29KSpecialRegs; To.Offset = 128; Count = 135-128 +1; @@ -814,7 +838,6 @@ int regno; error("UDIWrite() failed in udi_store_regisetrs"); registers_changed (); - DEXIT("udi_store_registers() failed in udi_store_regisetrs"); } /****************************************************** UDI_PREPARE_TO_STORE */ @@ -944,11 +967,12 @@ int from_tty; #if defined(ULTRA3) && defined(KERNEL_DEBUGGING) /* We don't ever kill the kernel */ if (from_tty) { - printf("Kernel not killed, but left in current state.\n"); - printf("Use detach to leave kernel running.\n"); + printf_filtered("Kernel not killed, but left in current state.\n"); + printf_filtered("Use detach to leave kernel running.\n"); } #else UDIStop(); + inferior_pid = 0; if (from_tty) { printf("Target has been stopped."); } @@ -1113,45 +1137,47 @@ fetch_register (regno) UDIBool HostEndian = 0; int result; - DENTER("udi_fetch_register()"); - if (regno == GR1_REGNUM) - { From.Space = UDI29KGlobalRegs; - From.Offset = 1; - result = UDIRead(From, &To, Count, Size, &CountDone, HostEndian); - } + { + From.Space = UDI29KGlobalRegs; + From.Offset = 1; + } else if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32) - { From.Space = UDI29KGlobalRegs; - From.Offset = (regno - GR96_REGNUM) + 96;; - result = UDIRead(From, &To, Count, Size, &CountDone, HostEndian); - } + { + From.Space = UDI29KGlobalRegs; + From.Offset = (regno - GR96_REGNUM) + 96;; + } + #if defined(GR64_REGNUM) + else if (regno >= GR64_REGNUM && regno < GR64_REGNUM + 32 ) - { From.Space = UDI29KGlobalRegs; - From.Offset = (regno - GR64_REGNUM) + 64; - result = UDIRead(From, &To, Count, Size, &CountDone, HostEndian); - } + { + From.Space = UDI29KGlobalRegs; + From.Offset = (regno - GR64_REGNUM) + 64; + } + #endif /* GR64_REGNUM */ + else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128) - { From.Space = UDI29KLocalRegs; - From.Offset = (regno - LR0_REGNUM); - result = UDIRead(From, &To, Count, Size, &CountDone, HostEndian); - } + { + From.Space = UDI29KLocalRegs; + From.Offset = (regno - LR0_REGNUM); + } else if (regno>=FPE_REGNUM && regno<=EXO_REGNUM) - { int val = -1; - supply_register(160 + (regno - FPE_REGNUM),(char *) &val); - return 0; /* Pretend Success */ - } + { + int val = -1; + supply_register(160 + (regno - FPE_REGNUM),(char *) &val); + return 0; /* Pretend Success */ + } else - { From.Space = UDI29KSpecialRegs; - From.Offset = regnum_to_srnum(regno); - result = UDIRead(From, &To, Count, Size, &CountDone, HostEndian); - } - DEXIT("udi_fetch_register()"); - if(result) - { result = -1; + { + From.Space = UDI29KSpecialRegs; + From.Offset = regnum_to_srnum(regno); + } + + if (UDIRead(From, &To, Count, Size, &CountDone, HostEndian)) error("UDIRead() failed in udi_fetch_registers"); - } + supply_register(regno, (char *) &To); return result; } @@ -1253,7 +1279,7 @@ int regno; case FC_REGNUM: return(134); case CR_REGNUM: return(135); case FPE_REGNUM: return(160); - case INT_REGNUM: return(161); + case INTE_REGNUM: return(161); case FPS_REGNUM: return(162); case EXO_REGNUM:return(164); default: diff --git a/gdb/tm-29k.h b/gdb/tm-29k.h index 2718061..72e4d98 100644 --- a/gdb/tm-29k.h +++ b/gdb/tm-29k.h @@ -147,9 +147,18 @@ CORE_ADDR skip_prologue (); "AI10", "AI11", "AI12", "AI13", "AI14", "AI15", "FP", \ "bp", "fc", "cr", "q", \ "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr", \ - "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "int", "fps", "exo", "gr1", \ + "pc0", "pc1", "pc2", "mmu", "lru", "fpe", "inte", "fps", "exo", "gr1", \ "alu", "ipc", "ipa", "ipb" } +/* + * Provide the processor register numbers of some registers that are + * expected/written in instructions that might change under different + * register sets. Namely, gcc can compile (-mkernel-registers) so that + * it uses gr64-gr95 in stead of gr96-gr127. + */ +#define MSP_HW_REGNUM 125 /* gr125 */ +#define RAB_HW_REGNUM 126 /* gr126 */ + /* Convert Processor Special register #x to REGISTER_NAMES register # */ #define SR_REGNUM(x) \ ((x) < 15 ? VAB_REGNUM + (x) \ @@ -202,7 +211,7 @@ CORE_ADDR skip_prologue (); #define MMU_REGNUM (VAB_REGNUM + 13) #define LRU_REGNUM (VAB_REGNUM + 14) #define FPE_REGNUM (VAB_REGNUM + 15) -#define INT_REGNUM (VAB_REGNUM + 16) +#define INTE_REGNUM (VAB_REGNUM + 16) #define FPS_REGNUM (VAB_REGNUM + 17) #define EXO_REGNUM (VAB_REGNUM + 18) /* gr1 is defined above as 200 = VAB_REGNUM + 19 */ @@ -422,17 +431,22 @@ long read_register_stack_integer (); #define EXTRA_FRAME_INFO \ CORE_ADDR saved_msp; \ unsigned int rsize; \ - unsigned int msize; + unsigned int msize; \ + unsigned char flags; + +/* Bits for flags in EXTRA_FRAME_INFO */ +#define TRANSPARENT 0x1 /* This is a transparent frame */ +#define MFP_USED 0x2 /* A memory frame pointer is used */ /* Because INIT_FRAME_PC gets passed fromleaf, that's where we init not only ->pc and ->frame, but all the extra stuff, when called from get_prev_frame_info, that is. */ -#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) \ - init_extra_frame_info(fci); +#define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci) void init_extra_frame_info (); -#define INIT_FRAME_PC(fromleaf, fci) \ - init_frame_pc(fromleaf, fci); + +#define INIT_FRAME_PC(fromleaf, fci) init_frame_pc(fromleaf, fci) void init_frame_pc (); + /* FRAME_CHAIN takes a FRAME and produces the frame's chain-pointer. @@ -451,15 +465,16 @@ void init_frame_pc (); /* These are mostly dummies for the 29k because INIT_FRAME_PC sets prev->frame instead. */ -#define FRAME_CHAIN(thisframe) (0) +#define FRAME_CHAIN(thisframe) ((thisframe)->frame + (thisframe)->rsize) + +/* Determine if the frame has a 'previous' and back-traceable frame. */ +#define FRAME_IS_UNCHAINED(frame) ((frame)->flags & TRANSPARENT) -/* Not sure how to figure out where the bottom frame is. There is - no frame for start. In my tests so far the - pc has been outside the text segment, though, so check for that. - FIXME!!! - However, allow a pc in a call dummy. */ -#define FRAME_CHAIN_VALID(chain, thisframe) \ - (!inside_entry_file (FRAME_SAVED_PC (thisframe))) +/* Find the previous frame of a transparent routine. + * For now lets not try and trace through a transparent routine (we might + * have to assume that all transparent routines are traps). + */ +#define FIND_PREV_UNCHAINED_FRAME(frame) 0 /* Define other aspects of the stack frame. */ @@ -517,20 +532,20 @@ extern CORE_ADDR frame_locals_address (); | | We must not disturb | args_out_sproc | it. memory stack |________________| - |____lr1_sproc___| - | | |__retaddr_sproc_| <- gr1 (at start) - |____________|<-msp 0 <-----------mfp_dummy_____| - | | (at start) | | - | arg_slop | | saved regs | - | (16 words) | | gr96-gr124 | - |____________|<-msp 1--after | sr128-sr135 | - | | PUSH_DUMMY_FRAME| | - | struct ret | |________________| - | 17+ | | | - |____________|<- lrp | args_out_dummy | - | struct ret | | (16 words) | - | 16 | |________________| - | (16 words) | |____lr1_dummy___| + |____lr1_sproc___|<-+ + | | |__retaddr_sproc_| | <-- gr1 (at start) + |____________|<-msp 0 <-----------mfp_dummy_____| | + | | (at start) | save regs | | + | arg_slop | | pc0,pc1 | | + | (16 words) | | gr96-gr124 | | + |____________|<-msp 1--after | sr160-sr162 | | + | | PUSH_DUMMY_FRAME| sr128-sr135 | | + | struct ret | |________________| | + | 17+ | | | | + |____________|<- lrp | args_out_dummy | | + | struct ret | | (16 words) | | + | 16 | |________________| | + | (16 words) | |____lr1_dummy___|--+ |____________|<- msp 2--after |_retaddr_dummy__|<- gr1 after | | struct ret | | PUSH_DUMMY_FRAME | margs17+ | area allocated | locals_inf | @@ -562,25 +577,29 @@ extern CORE_ADDR frame_locals_address (); /* Number of special registers (sr128-) to save. */ #define DUMMY_SAVE_SR128 8 +/* Number of special registers (sr160-) to save. */ +#define DUMMY_SAVE_SR160 3 /* Number of general (gr96- or gr64-) registers to save. */ #define DUMMY_SAVE_GREGS 29 #define DUMMY_FRAME_RSIZE \ -(4 /* mfp_dummy */ \ - + DUMMY_SAVE_GREGS * 4 \ - + DUMMY_SAVE_SR128 * 4 \ - + DUMMY_ARG \ +(4 /* mfp_dummy */ \ + + 2 * 4 /* pc0, pc1 */ \ + + DUMMY_SAVE_GREGS * 4 \ + + DUMMY_SAVE_SR160 * 4 \ + + DUMMY_SAVE_SR128 * 4 \ + + DUMMY_ARG \ ) /* Push an empty stack frame, to record the current PC, etc. */ -#define PUSH_DUMMY_FRAME push_dummy_frame(); +#define PUSH_DUMMY_FRAME push_dummy_frame() extern void push_dummy_frame (); /* Discard from the stack the innermost frame, restoring all saved registers. */ -#define POP_FRAME pop_frame (); +#define POP_FRAME pop_frame() extern void pop_frame (); /* This sequence of words is the instructions @@ -588,9 +607,9 @@ extern void pop_frame (); loadm 0, 0, lr2, msp ; load first 16 words of arguments into registers add msp, msp, 16 * 4 ; point to the remaining arguments CONST_INSN: - const gr96,inf - consth gr96,inf - calli lr0, gr96 + const lr0,inf + consth lr0,inf + calli lr0, lr0 aseq 0x40,gr1,gr1 ; nop asneq 0x50,gr1,gr1 ; breakpoint */ @@ -598,8 +617,10 @@ extern void pop_frame (); /* Position of the "const" instruction within CALL_DUMMY in bytes. */ #define CONST_INSN (3 * 4) #if TARGET_BYTE_ORDER == HOST_BYTE_ORDER -#define CALL_DUMMY {0x0400870f, 0x3600827d, 0x157d7d40, 0x03ff60ff, \ - 0x02ff60ff, 0xc8008060, 0x70400101, 0x72500101} +#define CALL_DUMMY {0x0400870f,\ + 0x36008200|(MSP_HW_REGNUM), \ + 0x15000040|(MSP_HW_REGNUM<<8)|(MSP_HW_REGNUM<<16), \ + 0x03ff80ff, 0x02ff80ff, 0xc8008080, 0x70400101, 0x72500101} #else /* Byte order differs. */ you lose #endif /* Byte order differs. */ |