diff -cr2N dist-gdb/Makefile gdb-3.1.2/Makefile *** dist-gdb/Makefile Sun Apr 9 18:30:09 1989 --- gdb-3.1.2/Makefile Sun Apr 9 18:35:09 1989 *************** *** 33,37 **** # -I. for "#include ". Possibly regex.h also. #CFLAGS = -g -I. -O ! CFLAGS = -I. -g #LDFLAGS = -pg -g LDFLAGS = -g --- 33,38 ---- # -I. for "#include ". Possibly regex.h also. #CFLAGS = -g -I. -O ! #CFLAGS = -I. -g ! CFLAGS = -I. -O #LDFLAGS = -pg -g LDFLAGS = -g *************** *** 43,48 **** OBSTACK = obstack.o OBSTACK1 = obstack.o ! REGEX = ! REGEX1 = # --- 44,51 ---- OBSTACK = obstack.o OBSTACK1 = obstack.o ! #REGEX = ! #REGEX1 = ! REGEX = regex.o ! REGEX1 = regex.o # *************** *** 62,65 **** --- 65,69 ---- # for USG #CLIBS= $(OBSTACK) $(REGEX) $(GNU_MALLOC) -lPW + CLIBS= $(OBSTACK) $(REGEX) $(GNU_MALLOC) SFILES = blockframe.c breakpoint.c coffread.c command.c core.c dbxread.c \ diff -cr2N dist-gdb/a.out.encap.h gdb-3.1.2/a.out.encap.h *** dist-gdb/a.out.encap.h Sun Apr 9 18:29:46 1989 --- gdb-3.1.2/a.out.encap.h Sun Apr 9 18:05:51 1989 *************** *** 66,71 **** #define COFF_MAGIC 0514 /* I386MAGIC */ #endif ! #if defined(i386) short __header_offset_temp; #define HEADER_OFFSET(f) \ --- 66,74 ---- #define COFF_MAGIC 0514 /* I386MAGIC */ #endif + #ifdef m68k + #define COFF_MAGIC 0520 /* MC68MAGIC */ + #endif ! #if defined(i386) || defined(m68k) short __header_offset_temp; #define HEADER_OFFSET(f) \ *************** *** 85,89 **** #define HEADER_OFFSET(f) 0 #define HEADER_OFFSET_FD(fd) 0 ! #endif #define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1)) --- 88,92 ---- #define HEADER_OFFSET(f) 0 #define HEADER_OFFSET_FD(fd) 0 ! #endif /* i386 || m68k */ #define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1)) *************** *** 105,109 **** ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ sizeof (struct coffheader) + sizeof (struct exec) : 0) ! #define SEGMENT_SIZE 0x400000 #define N_DATADDR(x) \ --- 108,120 ---- ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ sizeof (struct coffheader) + sizeof (struct exec) : 0) ! /* This is altos 3068-specific, but there isn't any good #define for it */ ! #if defined(m68k) && defined(PORTAR) ! #define SEGMENT_SIZE 0x40000 ! #define N_DATADDR(x) \ ! ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \ ! (((N_TXTADDR(x)+(x).a_text+0x2000) / SEGMENT_SIZE + 1) * SEGMENT_SIZE + \ ! (N_TXTADDR(x)+(x).a_text+0x2000) % 0x2000) : \ ! (N_TXTADDR(x)+(x).a_text)) ! #else #define SEGMENT_SIZE 0x400000 #define N_DATADDR(x) \ *************** *** 111,112 **** --- 122,124 ---- (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))) : \ (N_TXTADDR(x)+(x).a_text)) + #endif /* m68k && PORTAR */ diff -cr2N dist-gdb/altos-dep.c gdb-3.1.2/altos-dep.c *** dist-gdb/altos-dep.c Thu Jan 1 03:00:00 1970 --- gdb-3.1.2/altos-dep.c Sun Apr 9 17:54:00 1989 *************** *** 0 **** --- 1,623 ---- + /* Low level interface to ptrace, for GDB when running under m68k SVR2 Unix + on Altos 3068. + Copyright (C) 1988 Free Software Foundation, Inc. + + GDB is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY. No author or distributor accepts responsibility to anyone + for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. + Refer to the GDB General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GDB, + but only under the conditions described in the GDB General Public + License. A copy of this license is supposed to have been given to you + along with GDB so you can know your rights and responsibilities. It + should be in a file named COPYING. Among other things, the copyright + notice and this notice must be preserved on all copies. + + In other words, go ahead and share GDB, but don't try to stop + anyone else from sharing it farther. Help stamp out software hoarding! + */ + + #include "defs.h" + #include "param.h" + #include "frame.h" + #include "inferior.h" + + #ifdef USG + #include + #include + #endif + + #include + #include + #include + #include + #ifdef USG + #include + #ifdef ALTOS + #include + #include + #endif + #endif + #include + #include + #include + + #ifdef COFF_ENCAPSULATE + #include "a.out.encap.h" + #else + #include + #endif + #ifndef N_SET_MAGIC + #ifdef COFF_FORMAT + #define N_SET_MAGIC(exec, val) ((exec).magic = (val)) + #else + #define N_SET_MAGIC(exec, val) ((exec).a_magic = (val)) + #endif + #endif + + #include + #include + + extern int errno; + + /* This function simply calls ptrace with the given arguments. + It exists so that all calls to ptrace are isolated in this + machine-dependent file. */ + int + call_ptrace (request, pid, arg3, arg4) + int request, pid, arg3, arg4; + { + return ptrace (request, pid, arg3, arg4); + } + + kill_inferior () + { + if (remote_debugging) + return; + if (inferior_pid == 0) + return; + ptrace (8, inferior_pid, 0, 0); + wait (0); + inferior_died (); + } + + /* This is used when GDB is exiting. It gives less chance of error.*/ + + kill_inferior_fast () + { + if (remote_debugging) + return; + if (inferior_pid == 0) + return; + ptrace (8, inferior_pid, 0, 0); + wait (0); + } + + /* Resume execution of the inferior process. + If STEP is nonzero, single-step it. + If SIGNAL is nonzero, give it that signal. */ + + void + resume (step, signal) + int step; + int signal; + { + errno = 0; + if (remote_debugging) + remote_resume (step, signal); + else + { + ptrace (step ? 9 : 7, inferior_pid, 1, signal); + if (errno) + perror_with_name ("ptrace"); + } + } + + void + fetch_inferior_registers () + { + register int regno; + register unsigned int regaddr; + char buf[MAX_REGISTER_RAW_SIZE]; + register int i; + + struct user u; + #ifdef ALTOS + unsigned int offset = (char *) &u.u_state - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + #else + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + #endif + + for (regno = 0; regno < NUM_REGS; regno++) + { + regaddr = register_addr (regno, offset); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) + { + *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0); + regaddr += sizeof (int); + } + supply_register (regno, buf); + } + } + + /* Store our register values back into the inferior. + If REGNO is -1, do this for all registers. + Otherwise, REGNO specifies which register (so we can save time). */ + + store_inferior_registers (regno) + int regno; + { + register unsigned int regaddr; + char buf[80]; + + struct user u; + #ifdef ALTOS + unsigned int offset = (char *) &u.u_state - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + #else + unsigned int offset = (char *) &u.u_ar0 - (char *) &u; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; + #endif + + if (regno >= 0) + { + regaddr = register_addr (regno, offset); + errno = 0; + ptrace (6, inferior_pid, regaddr, read_register (regno)); + if (errno != 0) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } + else for (regno = 0; regno < NUM_REGS; regno++) + { + regaddr = register_addr (regno, offset); + errno = 0; + ptrace (6, inferior_pid, regaddr, read_register (regno)); + if (errno != 0) + { + sprintf (buf, "writing register number %d", regno); + perror_with_name (buf); + } + } + } + + /* Copy LEN bytes from inferior's memory starting at MEMADDR + to debugger memory starting at MYADDR. + On failure (cannot read from inferior, usually because address is out + of bounds) returns the value of errno. */ + + int + read_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; + { + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Read all the longwords */ + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + if (remote_debugging) + buffer[i] = remote_fetch_word (addr); + else + buffer[i] = ptrace (1, inferior_pid, addr, 0); + if (errno) + return errno; + } + + /* Copy appropriate bytes out of the buffer. */ + bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); + return 0; + } + + /* Copy LEN bytes of data from debugger memory at MYADDR + to inferior's memory at MEMADDR. + On failure (cannot write the inferior) + returns the value of errno. */ + + int + write_inferior_memory (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; + { + register int i; + /* Round starting address down to longword boundary. */ + register CORE_ADDR addr = memaddr & - sizeof (int); + /* Round ending address up; get number of longwords that makes. */ + register int count + = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); + /* Allocate buffer of that many longwords. */ + register int *buffer = (int *) alloca (count * sizeof (int)); + extern int errno; + + /* Fill start and end extra bytes of buffer with existing memory data. */ + + if (remote_debugging) + buffer[0] = remote_fetch_word (addr); + else + buffer[0] = ptrace (1, inferior_pid, addr, 0); + + if (count > 1) + { + if (remote_debugging) + buffer[count - 1] + = remote_fetch_word (addr + (count - 1) * sizeof (int)); + else + buffer[count - 1] + = ptrace (1, inferior_pid, + addr + (count - 1) * sizeof (int), 0); + } + + /* Copy data to be written over corresponding part of buffer */ + + bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len); + + /* Write the entire buffer. */ + + for (i = 0; i < count; i++, addr += sizeof (int)) + { + errno = 0; + if (remote_debugging) + remote_store_word (addr, buffer[i]); + else + ptrace (4, inferior_pid, addr, buffer[i]); + if (errno) + return errno; + } + + return 0; + } + + /* Work with core dump and executable files, for GDB. + This code would be in core.c if it weren't machine-dependent. */ + + /* Recognize COFF format systems because a.out.h defines AOUTHDR. */ + #ifdef AOUTHDR + #define COFF_FORMAT + #endif + + #ifndef N_TXTADDR + #define N_TXTADDR(hdr) 0 + #endif /* no N_TXTADDR */ + + #ifndef N_DATADDR + #define N_DATADDR(hdr) hdr.a_text + #endif /* no N_DATADDR */ + + /* Make COFF and non-COFF names for things a little more compatible + to reduce conditionals later. */ + + #ifdef COFF_FORMAT + #define a_magic magic + #endif + + #ifndef COFF_FORMAT + #define AOUTHDR struct exec + #endif + + extern char *sys_siglist[]; + + + /* Hook for `exec_file_command' command to call. */ + + extern void (*exec_file_display_hook) (); + + /* File names of core file and executable file. */ + + extern char *corefile; + extern char *execfile; + + /* Descriptors on which core file and executable file are open. + Note that the execchan is closed when an inferior is created + and reopened if the inferior dies or is killed. */ + + extern int corechan; + extern int execchan; + + /* Last modification time of executable file. + Also used in source.c to compare against mtime of a source file. */ + + extern int exec_mtime; + + /* Virtual addresses of bounds of the two areas of memory in the core file. */ + + extern CORE_ADDR data_start; + extern CORE_ADDR data_end; + extern CORE_ADDR stack_start; + extern CORE_ADDR stack_end; + + /* Virtual addresses of bounds of two areas of memory in the exec file. + Note that the data area in the exec file is used only when there is no core file. */ + + extern CORE_ADDR text_start; + extern CORE_ADDR text_end; + + extern CORE_ADDR exec_data_start; + extern CORE_ADDR exec_data_end; + + /* Address in executable file of start of text area data. */ + + extern int text_offset; + + /* Address in executable file of start of data area data. */ + + extern int exec_data_offset; + + /* Address in core file of start of data area data. */ + + extern int data_offset; + + /* Address in core file of start of stack area data. */ + + extern int stack_offset; + + #ifdef COFF_FORMAT + /* various coff data structures */ + + extern FILHDR file_hdr; + extern SCNHDR text_hdr; + extern SCNHDR data_hdr; + + #endif /* not COFF_FORMAT */ + + /* a.out header saved in core file. */ + + extern AOUTHDR core_aouthdr; + + /* a.out header of exec file. */ + + extern AOUTHDR exec_aouthdr; + + extern void validate_files (); + + core_file_command (filename, from_tty) + char *filename; + int from_tty; + { + int val; + extern char registers[]; + + /* Discard all vestiges of any previous core file + and mark data and stack spaces as empty. */ + + if (corefile) + free (corefile); + corefile = 0; + + if (corechan >= 0) + close (corechan); + corechan = -1; + + data_start = 0; + data_end = 0; + stack_start = STACK_END_ADDR; + stack_end = STACK_END_ADDR; + + /* Now, if a new core file was specified, open it and digest it. */ + + if (filename) + { + if (have_inferior_p ()) + error ("To look at a core file, you must kill the inferior with \"kill\"."); + corechan = open (filename, O_RDONLY, 0); + if (corechan < 0) + perror_with_name (filename); + /* 4.2-style (and perhaps also sysV-style) core dump file. */ + { + struct user u; + + int reg_offset; + + val = myread (corechan, &u, sizeof u); + if (val < 0) + perror_with_name (filename); + data_start = exec_data_start; + + #ifdef ALTOS + #define NBPG NBPP + #define UPAGES USIZE + /* data_end = data_start + u.u_dsize; + stack_start = stack_end - u.u_ssize; + data_offset = sizeof u; + stack_offset = data_offset + u.u_dsize; + printf ("u.u_dsize: %x, u.u_ssize: %x\n", u.u_dsize, u.u_ssize); + #else*/ + #endif + data_end = data_start + NBPG * u.u_dsize; + stack_start = stack_end - NBPG * u.u_ssize; + #ifdef ALTOS + data_offset = NBPG * UPAGES + exec_data_start % NBPG /* Not sure about this //jkp */; + #else + data_offset = NBPG * UPAGES; + #endif + stack_offset = NBPG * (UPAGES + u.u_dsize); + #ifdef ALTOS + reg_offset = (int) u.u_state - KERNEL_U_ADDR; + #else + reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR; + #endif + bcopy (&u.u_exdata, &core_aouthdr, sizeof (AOUTHDR)); + printf ("Core file is from \"%s\".\n", u.u_comm); + #if 0 + if (u.u_signal > 0) + printf ("Program terminated with signal %d, %s.\n", + u.u_signal, + u.u_signal < NSIG + ? sys_siglist[u.u_signal] + : "(undocumented)"); + #endif + + /* I don't know where to find this info. + So, for now, mark it as not available. */ + N_SET_MAGIC (core_aouthdr, 0); + + /* Read the register values out of the core file and store + them where `read_register' will find them. */ + + { + register int regno; + + for (regno = 0; regno < NUM_REGS; regno++) + { + char buf[MAX_REGISTER_RAW_SIZE]; + + val = lseek (corechan, register_addr (regno, reg_offset), 0); + if (val < 0) + perror_with_name (filename); + + val = myread (corechan, buf, sizeof buf); + if (val < 0) + perror_with_name (filename); + supply_register (regno, buf); + } + } + } + if (filename[0] == '/') + corefile = savestring (filename, strlen (filename)); + else + { + corefile = concat (current_directory, "/", filename); + } + + set_current_frame ( create_new_frame (read_register (FP_REGNUM), + read_pc ())); + select_frame (get_current_frame (), 0); + validate_files (); + } + else if (from_tty) + printf ("No core file now.\n"); + } + + exec_file_command (filename, from_tty) + char *filename; + int from_tty; + { + int val; + + /* Eliminate all traces of old exec file. + Mark text segment as empty. */ + + if (execfile) + free (execfile); + execfile = 0; + data_start = 0; + data_end -= exec_data_start; + text_start = 0; + text_end = 0; + exec_data_start = 0; + exec_data_end = 0; + if (execchan >= 0) + close (execchan); + execchan = -1; + + /* Now open and digest the file the user requested, if any. */ + + if (filename) + { + execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, + &execfile); + if (execchan < 0) + perror_with_name (filename); + + #ifdef COFF_FORMAT + { + int aout_hdrsize; + int num_sections; + + if (read_file_hdr (execchan, &file_hdr) < 0) + error ("\"%s\": not in executable format.", execfile); + + aout_hdrsize = file_hdr.f_opthdr; + num_sections = file_hdr.f_nscns; + + if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0) + error ("\"%s\": can't read optional aouthdr", execfile); + + if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0) + error ("\"%s\": can't read text section header", execfile); + + if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0) + error ("\"%s\": can't read data section header", execfile); + + text_start = exec_aouthdr.text_start; + text_end = text_start + exec_aouthdr.tsize; + text_offset = text_hdr.s_scnptr; + exec_data_start = exec_aouthdr.data_start; + exec_data_end = exec_data_start + exec_aouthdr.dsize; + exec_data_offset = data_hdr.s_scnptr; + data_start = exec_data_start; + data_end += exec_data_start; + exec_mtime = file_hdr.f_timdat; + } + #else /* not COFF_FORMAT */ + { + struct stat st_exec; + + #ifdef HEADER_SEEK_FD + HEADER_SEEK_FD (execchan); + #endif + + val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR)); + + if (val < 0) + perror_with_name (filename); + + text_start = N_TXTADDR (exec_aouthdr); + exec_data_start = N_DATADDR (exec_aouthdr); + + text_offset = N_TXTOFF (exec_aouthdr); + exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; + + text_end = text_start + exec_aouthdr.a_text; + exec_data_end = exec_data_start + exec_aouthdr.a_data; + data_start = exec_data_start; + data_end += exec_data_start; + + fstat (execchan, &st_exec); + exec_mtime = st_exec.st_mtime; + } + #endif /* not COFF_FORMAT */ + + validate_files (); + } + else if (from_tty) + printf ("No exec file now.\n"); + + /* Tell display code (if any) about the changed file name. */ + if (exec_file_display_hook) + (*exec_file_display_hook) (filename); + } + + #ifdef ALTOS + int + dup2 (file, new) + int file,new; + { + int ret; + + close(new); + ret = fcntl(file, F_DUPFD, new); + if (ret != new) { + if (errno == EMFILE && (new < 0 || new > 20)) + errno = EBADF; + return(-1); + } + return(ret); + } + #endif /* ALTOS */ diff -cr2N dist-gdb/coffread.c gdb-3.1.2/coffread.c *** dist-gdb/coffread.c Sun Apr 9 18:29:05 1989 --- gdb-3.1.2/coffread.c Sat Apr 1 08:15:02 1989 *************** *** 30,33 **** --- 30,34 ---- #include #include + int fclose (); #endif *************** *** 1074,1077 **** --- 1075,1081 ---- switch (file_hdr->f_magic) { + #ifdef MC68MAGIC + case MC68MAGIC: + #endif #ifdef NS32GMAGIC case NS32GMAGIC: diff -cr2N dist-gdb/command.c gdb-3.1.2/command.c *** dist-gdb/command.c Sun Apr 9 18:29:05 1989 --- gdb-3.1.2/command.c Sun Apr 9 17:58:51 1989 *************** *** 106,109 **** --- 106,110 ---- #include "command.h" #include "defs.h" + #include "param.h" #include diff -cr2N dist-gdb/config.gdb gdb-3.1.2/config.gdb *** dist-gdb/config.gdb Sun Apr 9 18:30:10 1989 --- gdb-3.1.2/config.gdb Thu Mar 30 16:47:57 1989 *************** *** 55,58 **** --- 55,74 ---- opcodefile=vax-opcode.h ;; + altos) + echo "Do a make clean if you have compiled a version of gdb" + echo "without the coff encapsulation stuff" + pinsnfile=m68k-pinsn.c + opcodefile=m68k-opcode.h + ;; + altosgas) + echo "Do a make clean if you have compiled a version of gdb" + echo "with the coff encapsulation stuff" + echo " " + echo "Use of the coff encapsulation features requires the GNU binutils utilities" + echo "to be ahead of their System V counterparts in your path." + pinsnfile=m68k-pinsn.c + depfile=altos-dep.c + opcodefile=m68k-opcode.h + ;; hp9k320) pinsnfile=m68k-pinsn.c diff -cr2N dist-gdb/core.c gdb-3.1.2/core.c *** dist-gdb/core.c Sun Apr 9 18:29:06 1989 --- gdb-3.1.2/core.c Thu Mar 30 17:09:32 1989 *************** *** 46,49 **** --- 46,55 ---- #include + #ifdef USG + #include + #ifdef ALTOS + #include + #endif + #endif #ifdef UMAX_CORE #include diff -cr2N dist-gdb/inflow.c gdb-3.1.2/inflow.c *** dist-gdb/inflow.c Sun Apr 9 18:29:13 1989 --- gdb-3.1.2/inflow.c Thu Mar 30 17:10:13 1989 *************** *** 36,39 **** --- 36,43 ---- have migrated to *-infdep.c */ #ifdef USG + #include + #ifdef ALTOS + #include + #endif #include #endif diff -cr2N dist-gdb/m-altos.h gdb-3.1.2/m-altos.h *** dist-gdb/m-altos.h Thu Jan 1 03:00:00 1970 --- gdb-3.1.2/m-altos.h Sun Apr 9 17:33:24 1989 *************** *** 0 **** --- 1,791 ---- + /* Definitions to make GDB run on an Altos 3068 (m68k running SVR2) + Copyright (C) 1987,1989 Free Software Foundation, Inc. + + GDB is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY. No author or distributor accepts responsibility to anyone + for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. + Refer to the GDB General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GDB, + but only under the conditions described in the GDB General Public + License. A copy of this license is supposed to have been given to you + along with GDB so you can know your rights and responsibilities. It + should be in a file named COPYING. Among other things, the copyright + notice and this notice must be preserved on all copies. + + In other words, go ahead and share GDB, but don't try to stop + anyone else from sharing it farther. Help stamp out software hoarding! + */ + + #ifndef ALTOS + #define ALTOS + #endif + + #define USG + + /* If compiled with GNU C, use the built-in alloca */ + #ifdef __GNUC__ + #define alloca __builtin_alloca + #endif + + #define HAVE_TERMIO + + #define CBREAK XTABS /* It takes all kinds... */ + + /* + * #define FLOATING_POINT if you have 68881 + * This hasn't been tested + */ + + /*#define FLOATING_POINT*/ + /*#undef FLOATING_POINT*/ + + #ifndef __GNUC__ + #define ALTOS_AND + #undef USE_GAS + #define ALTOS_AS + #else + #define USE_GAS + #endif + + #ifndef R_OK + #define R_OK 4 + #define W_OK 2 + #define X_OK 1 + #define F_OK 0 + #endif + + #ifndef MAXPATHLEN + #define MAXPATHLEN (1024) + #endif + + /* Motorola assembly format */ + #if !defined(USE_GAS) && !defined(ALTOS) + #define MOTOROLA + #endif + + /* Get sys/wait.h ie. from a Sun and edit it a little (mc68000 to m68k) */ + #define HAVE_WAIT_STRUCT + + /* Define this if the C compiler puts an underscore at the front + of external names before giving them to the linker. */ + + #undef NAMES_HAVE_UNDERSCORE + + /* Exec files and symbol tables are in COFF format */ + + #define COFF_FORMAT + #define ALTOS_CORE + #define COFF_NO_LONG_FILE_NAMES + #define vfork fork + + /* Offset from address of function to start of its code. + Zero on most machines. */ + + #define FUNCTION_START_OFFSET 0 + + /* Advance PC across any function entry prologue instructions + to reach some "real" code. */ + + #define SKIP_PROLOGUE(pc) \ + { register int op = read_memory_integer (pc, 2); \ + if (op == 0047126) \ + pc += 4; /* Skip link #word */ \ + else if (op == 0044016) \ + pc += 6; /* Skip link #long */ \ + else if (op == 0060000) \ + pc += 4; /* Skip bra #word */ \ + else if (op == 00600377) \ + pc += 6; /* skip bra #long */ \ + else if ((op & 0177400) == 0060000) \ + pc += 2; /* skip bra #char */ \ + } + + /* Immediately after a function call, return the saved pc. + Can't always go through the frames for this because on some machines + the new frame is not set up until the new function executes + some instructions. */ + + #define SAVED_PC_AFTER_CALL(frame) \ + read_memory_integer (read_register (SP_REGNUM), 4) + + /* This is the amount to subtract from u.u_ar0 + to get the offset in the core file of the register values. */ + + #define KERNEL_U_ADDR 0x1fbf000 + + /* Address of end of stack space. */ + + /*#define STACK_END_ADDR (0xffffff)*/ + #define STACK_END_ADDR (0x1000000) + + /* Stack grows downward. */ + + #define INNER_THAN < + + /* Sequence of bytes for breakpoint instruction. */ + + #define BREAKPOINT {0x4e, 0x4e} + + /* Amount PC must be decremented by after a breakpoint. + This is often the number of bytes in BREAKPOINT + but not always. + On the Altos, the kernel resets the pc to the trap instr */ + + #define DECR_PC_AFTER_BREAK 0 + + /* Nonzero if instruction at PC is a return instruction. */ + + #define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75) + + /* Return 1 if P points to an invalid floating point value. */ + + #define INVALID_FLOAT(p, len) (*((int *) (p)) == -1) /* Just a first guess; not checked */ + + /* Largest integer type */ + #define LONGEST long + + /* Name of the builtin type for the LONGEST type above. */ + #define BUILTIN_TYPE_LONGEST builtin_type_long + + /* Say how long (ordinary) registers are. */ + + #define REGISTER_TYPE long + + /* Say how long (ordinary) registers are. */ + + #define REGISTER_TYPE long + + /* Number of machine registers */ + + #ifdef FLOATING_POINT + #define NUM_REGS 31 + #else + #define NUM_REGS 18 + #endif + + /* Initializer for an array of names of registers. + There should be NUM_REGS strings in this initializer. */ + + #ifdef FLOATING_POINT + #define REGISTER_NAMES \ + {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ + "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \ + "ps", "pc", \ + "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \ + "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" \ + } + #else + #define REGISTER_NAMES \ + {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ + "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \ + "ps", "pc", \ + } + #endif + + /* Register numbers of various important registers. + Note that some of these values are "real" register numbers, + and correspond to the general registers of the machine, + and some are "phony" register numbers which are too large + to be actual register numbers as far as the user is concerned + but do serve to get the desired values when passed to read_register. */ + + #define FP_REGNUM 14 /* Contains address of executing stack frame */ + #define SP_REGNUM 15 /* Contains address of top of stack */ + #define PS_REGNUM 16 /* Contains processor status */ + #define PC_REGNUM 17 /* Contains program counter */ + #define FP0_REGNUM 18 /* Floating point register 0 */ + #define FPC_REGNUM 26 /* 68881 control register */ + + /* Total amount of space needed to store our copies of the machine's + register state, the array `registers'. */ + #define REGISTER_BYTES (16*4+8*12+8+20) + + /* Index within `registers' of the first byte of the space for + register N. */ + + #define REGISTER_BYTE(N) \ + ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \ + : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \ + : (N) * 4) + + /* Number of bytes of storage in the actual machine representation + for register N. On the 68000, all regs are 4 bytes + except the floating point regs which are 12 bytes. */ + + #define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4) + + /* Number of bytes of storage in the program's representation + for register N. On the 68000, all regs are 4 bytes + except the floating point regs which are 8-byte doubles. */ + + #define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4) + + #define REGISTER_U_ADDR(addr, blockend, regno) \ + { if (regno <= SP_REGNUM) \ + addr = blockend + regno * 4; \ + else if (regno == PS_REGNUM) \ + addr = blockend + regno * 4 + 4; \ + else if (regno == PC_REGNUM) \ + addr = blockend + regno * 4 + 2; \ + } + + /* Largest value REGISTER_RAW_SIZE can have. */ + + #define MAX_REGISTER_RAW_SIZE 12 + + /* Largest value REGISTER_VIRTUAL_SIZE can have. */ + + #define MAX_REGISTER_VIRTUAL_SIZE 8 + + /* Nonzero if register N requires conversion + from raw format to virtual format. */ + + #define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8) + + /* Convert data from raw format for register REGNUM + to virtual format for register REGNUM. */ + + #define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ + { if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ + convert_from_68881 ((FROM), (TO)); \ + else \ + bcopy ((FROM), (TO), 4); } + + /* Convert data from virtual format for register REGNUM + to raw format for register REGNUM. */ + + #define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ + { if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ + convert_to_68881 ((FROM), (TO)); \ + else \ + bcopy ((FROM), (TO), 4); } + + /* Return the GDB type object for the "standard" data type + of data in register N. */ + + #define REGISTER_VIRTUAL_TYPE(N) \ + (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int) + + /* Store the address of the place in which to copy the structure the + subroutine will return. This is called from call_function. */ + + #define STORE_STRUCT_RETURN(ADDR, SP) \ + { write_register (9, (ADDR)); } + + /* Extract from an array REGBUF containing the (raw) register state + a function return value of type TYPE, and copy that, in virtual format, + into VALBUF. */ + + #define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ + bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE)) + + /* Write into appropriate registers a function return value + of type TYPE, given in virtual format. */ + + #define STORE_RETURN_VALUE(TYPE,VALBUF) \ + write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)) + + /* Extract from an array REGBUF containing the (raw) register state + the address in which a function should return its structure value, + as a CORE_ADDR (or an expression that can be used as one). */ + + #define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF)) + + #define REGISTER_ADDR(u_ar0, regno) \ + (((regno) < PS_REGNUM) \ + ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)]) \ + : (((regno) == PS_REGNUM) \ + ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS)) \ + : (&((struct exception_stack *) (u_ar0))->e_PC))) + + #define FP_REGISTER_ADDR(u, regno) \ + (((char *) \ + (((regno) < FPC_REGNUM) \ + ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \ + : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))) \ + - ((char *) (& u))) + + /* It is safe to look for symsegs on a Sun, because Sun's ld + does not screw up with random garbage at end of file. + Don't quite know what this means, methinks it's the out-of-date + GNU symbolig infromation (-gg option for gcc) */ + + /*#define READ_GDB_SYMSEGS*/ + + /* Describe the pointer in each stack frame to the previous stack frame + (its caller). */ + + /* FRAME_CHAIN takes a frame's nominal address + and produces the frame's chain-pointer. + + FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address + and produces the nominal address of the caller frame. + + However, if FRAME_CHAIN_VALID returns zero, + it means the given frame is the outermost one and has no caller. + In that case, FRAME_CHAIN_COMBINE is not used. */ + + /* In the case of the Altos, the frame's nominal address + is the address of a 4-byte word containing the calling frame's address. */ + + #define FRAME_CHAIN(thisframe) (read_memory_integer ((thisframe)->frame, 4)) + + #define FRAME_CHAIN_VALID(chain, thisframe) \ + (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end)) + + #define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) + + /* Define other aspects of the stack frame. */ + + #define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4)) + + #define FRAME_ARGS_ADDRESS(fi) ((fi)->frame) + + #define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame) + + /* Set VAL to the number of args passed to frame described by FI. + Can set VAL to -1, meaning no way to tell. */ + + /* Return number of args passed to a frame. + Can return -1, meaning no way to tell. */ + + /* We can't tell how many args there are + now that the (gnu) C compiler delays popping them. + Perhaps we could tell if we use the Altos cc, but I'm not sure + COFF_FORMAT is the right conditional */ + + #ifdef COFF_FORMAT + + #define FRAME_NUM_ARGS(val, fi) (val = -1) + #if 0 + #define FRAME_NUM_ARGS(val, fi) \ + { register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \ + register int insn = 0177777 & read_memory_integer (pc, 2); \ + val = 0; \ + if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \ + val = read_memory_integer (pc + 2, 2); \ + else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \ + || (insn & 0170777) == 0050117) /* addqw */ \ + { val = (insn >> 9) & 7; if (val == 0) val = 8; } \ + else if (insn == 0157774) /* addal #WW, sp */ \ + val = read_memory_integer (pc + 2, 4); \ + val >>= 2; } + #endif + + /* Return number of bytes at start of arglist that are not really args. */ + + #define FRAME_ARGS_SKIP 8 + + /* Put here the code to store, into a struct frame_saved_regs, + the addresses of the saved registers of frame described by FRAME_INFO. + This includes special registers such as pc and fp saved in special + ways in the stack frame. sp is even more special: + the address we return for it IS the sp for the next frame. */ + + #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ + { register int regnum; \ + register int regmask; \ + register CORE_ADDR next_addr; \ + register CORE_ADDR pc; \ + int nextinsn; \ + bzero (&frame_saved_regs, sizeof frame_saved_regs); \ + if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \ + && (frame_info)->pc <= (frame_info)->frame) \ + { next_addr = (frame_info)->frame; \ + pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\ + else \ + { pc = get_pc_function_start ((frame_info)->pc); \ + /* Verify we have a link a6 instruction next; \ + if not we lose. If we win, find the address above the saved \ + regs using the amount of storage from the link instruction. */\ + if (044016 == read_memory_integer (pc, 2)) \ + next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \ + else if (047126 == read_memory_integer (pc, 2)) \ + next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \ + else goto lose; \ + /* If have an addal #-n, sp next, adjust next_addr. */ \ + if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \ + next_addr += read_memory_integer (pc += 2, 4), pc += 4; \ + } \ + /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \ + regmask = read_memory_integer (pc + 2, 2); \ + /* But before that can come an fmovem. Check for it. */ \ + nextinsn = 0xffff & read_memory_integer (pc, 2); \ + if (0xf227 == nextinsn \ + && (regmask & 0xff00) == 0xe000) \ + { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr -= 12); \ + regmask = read_memory_integer (pc + 2, 2); } \ + if (0044327 == read_memory_integer (pc, 2)) \ + { pc += 4; /* Regmask's low bit is for register 0, the first written */ \ + for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \ + else if (0044347 == read_memory_integer (pc, 2)) \ + { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \ + for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ + else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \ + { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \ + (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ + /* fmovemx to index of sp may follow. */ \ + regmask = read_memory_integer (pc + 2, 2); \ + nextinsn = 0xffff & read_memory_integer (pc, 2); \ + if (0xf236 == nextinsn \ + && (regmask & 0xff00) == 0xf000) \ + { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \ + regmask = read_memory_integer (pc + 2, 2); } \ + /* clrw -(sp); movw ccr,-(sp) may follow. */ \ + if (0x426742e7 == read_memory_integer (pc, 4)) \ + (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \ + lose: ; \ + (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8; \ + (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame; \ + (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4; \ + } + + #if 0 + { register int regnum; \ + register int regmask; \ + register CORE_ADDR next_addr; \ + register CORE_ADDR pc; \ + int nextinsn; \ + bzero (&frame_saved_regs, sizeof frame_saved_regs); \ + if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \ + && (frame_info).pc <= (frame_info).frame) \ + { next_addr = (frame_info).frame; \ + pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\ + else \ + { pc = get_pc_function_start ((frame_info).pc); \ + /* Verify we have a link a6 instruction next; \ + if not we lose. If we win, find the address above the saved \ + regs using the amount of storage from the link instruction. */\ + if (044016 == read_memory_integer (pc, 2)) \ + next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \ + else if (047126 == read_memory_integer (pc, 2)) \ + next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \ + else goto lose; \ + /* If have an addal #-n, sp next, adjust next_addr. */ \ + if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \ + next_addr += read_memory_integer (pc += 2, 4), pc += 4; \ + } \ + /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \ + regmask = read_memory_integer (pc + 2, 2); \ + /* But before that can come an fmovem. Check for it. */ \ + nextinsn = 0xffff & read_memory_integer (pc, 2); \ + if (0xf227 == nextinsn \ + && (regmask & 0xff00) == 0xe000) \ + { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr -= 12); \ + regmask = read_memory_integer (pc + 2, 2); } \ + if (0044327 == read_memory_integer (pc, 2)) \ + { pc += 4; /* Regmask's low bit is for register 0, the first written */ \ + for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \ + else if (0044347 == read_memory_integer (pc, 2)) \ + { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \ + for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ + else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \ + { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \ + (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ + /* fmovemx to index of sp may follow. */ \ + regmask = read_memory_integer (pc + 2, 2); \ + nextinsn = 0xffff & read_memory_integer (pc, 2); \ + if (0xf236 == nextinsn \ + && (regmask & 0xff00) == 0xf000) \ + { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \ + regmask = read_memory_integer (pc + 2, 2); } \ + /* clrw -(sp); movw ccr,-(sp) may follow. */ \ + if (0x426742e7 == read_memory_integer (pc, 4)) \ + (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \ + lose: ; \ + (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \ + (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \ + (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \ + } + #endif + #if 0 + #define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ + { register int regnum; \ + register int regmask; \ + register CORE_ADDR next_addr; \ + register CORE_ADDR pc; \ + register int insn; \ + register int offset; \ + bzero (&frame_saved_regs, sizeof frame_saved_regs); \ + if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \ + && (frame_info).pc <= (frame_info).frame) \ + { next_addr = (frame_info).frame; \ + pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\ + else \ + { pc = get_pc_function_start ((frame_info).pc); \ + /* Verify we have a link a6 instruction next, \ + or a branch followed by a link a6 instruction; \ + if not we lose. If we win, find the address above the saved \ + regs using the amount of storage from the link instruction. */\ + retry: \ + insn = read_memory_integer (pc, 2); \ + if (insn == 044016) \ + next_addr = (frame_info).frame - read_memory_integer (pc += 2, 4), pc+=4; \ + else if (insn == 047126) \ + next_addr = (frame_info).frame - read_memory_integer (pc += 2, 2), pc+=2; \ + else if ((insn & 0177400) == 060000) /* bra insn */ \ + { offset = insn & 0377; \ + pc += 2; /* advance past bra */ \ + if (offset == 0) /* bra #word */ \ + offset = read_memory_integer (pc, 2), pc += 2; \ + else if (offset == 0377) /* bra #long */ \ + offset = read_memory_integer (pc, 4), pc += 4; \ + pc += offset; \ + goto retry; \ + } else goto lose; \ + /* If have an addal #-n, sp next, adjust next_addr. */ \ + if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \ + next_addr += read_memory_integer (pc += 2, 4), pc += 4; \ + } \ + /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \ + insn = read_memory_integer (pc, 2), pc += 2; \ + regmask = read_memory_integer (pc, 2); \ + if ((insn & 0177760) == 022700) /* movl rn, (sp) */ \ + (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr; \ + else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */ \ + (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \ + else if (insn == 0044327) /* moveml mask, (sp) */ \ + { pc += 2; \ + /* Regmask's low bit is for register 0, the first written */ \ + next_addr -= 4; \ + for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr += 4); \ + } else if (insn == 0044347) /* moveml mask, -(sp) */ \ + { pc += 2; \ + /* Regmask's low bit is for register 15, the first pushed */ \ + for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \ + if (regmask & 1) \ + (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ + /* clrw -(sp); movw ccr,-(sp) may follow. */ \ + if (read_memory_integer (pc, 2) == 041147 \ + && read_memory_integer (pc+2, 2) == 042347) \ + (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \ + lose: ; \ + (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \ + (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \ + (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \ + } + #endif + #else + #define FRAME_NUM_ARGS(val, fi) (val = -1) + #endif + + /* Things needed for making the inferior call functions. */ + + /* Push an empty stack frame, to record the current PC, etc. */ + + #define PUSH_DUMMY_FRAME \ + { register CORE_ADDR sp = read_register (SP_REGNUM); \ + register int regnum; \ + char raw_buffer[12]; \ + sp = push_word (sp, read_register (PC_REGNUM)); \ + sp = push_word (sp, read_register (FP_REGNUM)); \ + write_register (FP_REGNUM, sp); \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \ + { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \ + sp = push_bytes (sp, raw_buffer, 12); } \ + for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \ + sp = push_word (sp, read_register (regnum)); \ + sp = push_word (sp, read_register (PS_REGNUM)); \ + write_register (SP_REGNUM, sp); } + + /* Discard from the stack the innermost frame, + restoring all saved registers. */ + + #define POP_FRAME \ + { register FRAME frame = get_current_frame (); \ + register CORE_ADDR fp; \ + register int regnum; \ + struct frame_saved_regs fsr; \ + struct frame_info *fi; \ + char raw_buffer[12]; \ + fi = get_frame_info (frame); \ + fp = fi->frame; \ + get_frame_saved_regs (fi, &fsr); \ + for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \ + if (fsr.regs[regnum]) \ + { read_memory (fsr.regs[regnum], raw_buffer, 12); \ + write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\ + for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \ + if (fsr.regs[regnum]) \ + write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \ + if (fsr.regs[PS_REGNUM]) \ + write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \ + write_register (FP_REGNUM, read_memory_integer (fp, 4)); \ + write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \ + write_register (SP_REGNUM, fp + 8); \ + flush_cached_frames (); \ + set_current_frame (create_new_frame (read_register (FP_REGNUM),\ + read_pc ()));} + + /* This sequence of words is the instructions + fmovem 0xff,-(sp) + moveml 0xfffc,-(sp) + clrw -(sp) + movew ccr,-(sp) + /..* The arguments are pushed at this point by GDB; + no code is needed in the dummy for this. + The CALL_DUMMY_START_OFFSET gives the position of + the following jsr instruction. *../ + jsr @#32323232 + addl #69696969,sp + bpt + nop + Note this is 28 bytes. + We actually start executing at the jsr, since the pushing of the + registers is done by PUSH_DUMMY_FRAME. If this were real code, + the arguments for the function called by the jsr would be pushed + between the moveml and the jsr, and we could allow it to execute through. + But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done, + and we cannot allow the moveml to push the registers again lest they be + taken for the arguments. */ + + #define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4e4e71} + + #define CALL_DUMMY_LENGTH 28 + + #define CALL_DUMMY_START_OFFSET 12 + + /* Insert the specified number of args and function address + into a call sequence of the above form stored at DUMMYNAME. */ + + #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \ + { *(int *)((char *) dummyname + 20) = nargs * 4; \ + *(int *)((char *) dummyname + 14) = fun; } + + /* Interface definitions for kernel debugger KDB. */ + + /* Map machine fault codes into signal numbers. + First subtract 0, divide by 4, then index in a table. + Faults for which the entry in this table is 0 + are not handled by KDB; the program's own trap handler + gets to handle then. */ + + #define FAULT_CODE_ORIGIN 0 + #define FAULT_CODE_UNITS 4 + #define FAULT_TABLE \ + { 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \ + 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \ + 0, 0, 0, 0, 0, 0, 0, 0, \ + SIGILL } + + /* Start running with a stack stretching from BEG to END. + BEG and END should be symbols meaningful to the assembler. + This is used only for kdb. */ + + #ifdef MOTOROLA + #define INIT_STACK(beg, end) \ + { asm (".globl end"); \ + asm ("move.l $ end, sp"); \ + asm ("clr.l fp"); } + #else + #ifdef ALTOS_AS + #define INIT_STACK(beg, end) \ + { asm ("global end"); \ + asm ("mov.l &end,%sp"); \ + asm ("clr.l %fp"); } + #else + #define INIT_STACK(beg, end) \ + { asm (".globl end"); \ + asm ("movel $ end, sp"); \ + asm ("clrl fp"); } + #endif + #endif + + /* Push the frame pointer register on the stack. */ + #ifdef MOTOROLA + #define PUSH_FRAME_PTR \ + asm ("move.l fp, -(sp)"); + #else + #ifdef ALTOS_AS + #define PUSH_FRAME_PTR \ + asm ("mov.l %fp, -(%sp)"); + #else + #define PUSH_FRAME_PTR \ + asm ("movel fp, -(sp)"); + #endif + #endif + + /* Copy the top-of-stack to the frame pointer register. */ + #ifdef MOTOROLA + #define POP_FRAME_PTR \ + asm ("move.l (sp), fp"); + #else + #ifdef ALTOS_AS + #define POP_FRAME_PTR \ + asm ("mov.l (%sp), %fp"); + #else + #define POP_FRAME_PTR \ + asm ("movl (sp), fp"); + #endif + #endif + + /* After KDB is entered by a fault, push all registers + that GDB thinks about (all NUM_REGS of them), + so that they appear in order of ascending GDB register number. + The fault code will be on the stack beyond the last register. */ + + #ifdef MOTOROLA + #define PUSH_REGISTERS \ + { asm ("clr.w -(sp)"); \ + asm ("pea (10,sp)"); \ + asm ("movem $ 0xfffe,-(sp)"); } + #else + #ifdef ALTOS_AS + #define PUSH_REGISTERS \ + { asm ("clr.w -(%sp)"); \ + asm ("pea (10,%sp)"); \ + asm ("movm.l &0xfffe,-(%sp)"); } + #else + #define PUSH_REGISTERS \ + { asm ("clrw -(sp)"); \ + asm ("pea 10(sp)"); \ + asm ("movem $ 0xfffe,-(sp)"); } + #endif + #endif + + /* Assuming the registers (including processor status) have been + pushed on the stack in order of ascending GDB register number, + restore them and return to the address in the saved PC register. */ + + #ifdef MOTOROLA + #define POP_REGISTERS \ + { asm ("subi.l $8,28(sp)"); \ + asm ("movem (sp),$ 0xffff"); \ + asm ("rte"); } + #else + #ifdef ALTOS_AS + #define POP_REGISTERS \ + { asm ("sub.l &8,28(%sp)"); \ + asm ("movem (%sp),&0xffff"); \ + asm ("rte"); } + #else + #define POP_REGISTERS \ + { asm ("subil $8,28(sp)"); \ + asm ("movem (sp),$ 0xffff"); \ + asm ("rte"); } + #endif + #endif diff -cr2N dist-gdb/m-altosgas.h gdb-3.1.2/m-altosgas.h *** dist-gdb/m-altosgas.h Thu Jan 1 03:00:00 1970 --- gdb-3.1.2/m-altosgas.h Thu Mar 30 16:48:33 1989 *************** *** 0 **** --- 1,29 ---- + /* + Copyright (C) 1986, 1987 Free Software Foundation, Inc. + + GDB is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY. No author or distributor accepts responsibility to anyone + for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. + Refer to the GDB General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GDB, + but only under the conditions described in the GDB General Public + License. A copy of this license is supposed to have been given to you + along with GDB so you can know your rights and responsibilities. It + should be in a file named COPYING. Among other things, the copyright + notice and this notice must be preserved on all copies. + + In other words, go ahead and share GDB, but don't try to stop + anyone else from sharing it farther. Help stamp out software hoarding! + */ + + #define COFF_ENCAPSULATE + + #include "m-altos.h" + + #undef COFF_FORMAT + #undef COFF_NO_LONG_FILE_NAMES + #define NAMES_HAVE_UNDERSCORE + + #define READ_DBX_FORMAT