This file was not part of the GDB 5.2.1 import and should have been

deleted from the vendor branch.
This commit is contained in:
Marcel Moolenaar 2004-06-20 01:55:44 +00:00
parent fdedc45ff6
commit 4d359ceaf0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/gdb/dist/; revision=130758
362 changed files with 0 additions and 166798 deletions

View File

@ -1,16 +0,0 @@
echo Setting up the environment for debugging gdb.\n
set complaints 1
b fatal
b info_command
commands
silent
return
end
dir ../mmalloc
dir ../libiberty
dir ../bfd
set prompt (top-gdb)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
/* OBSOLETE .text */
/* OBSOLETE .global _convert_from_extended */
/* OBSOLETE */
/* OBSOLETE _convert_from_extended: */
/* OBSOLETE */
/* OBSOLETE ldfe f0,[a1] */
/* OBSOLETE stfd f0,[a2] */
/* OBSOLETE movs pc,lr */
/* OBSOLETE */
/* OBSOLETE .global _convert_to_extended */
/* OBSOLETE */
/* OBSOLETE _convert_to_extended: */
/* OBSOLETE */
/* OBSOLETE ldfd f0,[a1] */
/* OBSOLETE stfe f0,[a2] */
/* OBSOLETE movs pc,lr */

View File

@ -1,575 +0,0 @@
/* OBSOLETE /* Acorn Risc Machine host machine support. */
/* OBSOLETE Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc. */
/* OBSOLETE */
/* OBSOLETE This file is part of GDB. */
/* OBSOLETE */
/* OBSOLETE This program is free software; you can redistribute it and/or modify */
/* OBSOLETE it under the terms of the GNU General Public License as published by */
/* OBSOLETE the Free Software Foundation; either version 2 of the License, or */
/* OBSOLETE (at your option) any later version. */
/* OBSOLETE */
/* OBSOLETE This program is distributed in the hope that it will be useful, */
/* OBSOLETE but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* OBSOLETE MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* OBSOLETE GNU General Public License for more details. */
/* OBSOLETE */
/* OBSOLETE You should have received a copy of the GNU General Public License */
/* OBSOLETE along with this program; if not, write to the Free Software */
/* OBSOLETE Foundation, Inc., 59 Temple Place - Suite 330, */
/* OBSOLETE Boston, MA 02111-1307, USA. *x/ */
/* OBSOLETE */
/* OBSOLETE #include "defs.h" */
/* OBSOLETE #include "frame.h" */
/* OBSOLETE #include "inferior.h" */
/* OBSOLETE #include "opcode/arm.h" */
/* OBSOLETE */
/* OBSOLETE #include <sys/param.h> */
/* OBSOLETE #include <sys/dir.h> */
/* OBSOLETE #include <signal.h> */
/* OBSOLETE #include <sys/ioctl.h> */
/* OBSOLETE #include <sys/ptrace.h> */
/* OBSOLETE #include <machine/reg.h> */
/* OBSOLETE */
/* OBSOLETE #define N_TXTADDR(hdr) 0x8000 */
/* OBSOLETE #define N_DATADDR(hdr) (hdr.a_text + 0x8000) */
/* OBSOLETE */
/* OBSOLETE #include "gdbcore.h" */
/* OBSOLETE */
/* OBSOLETE #include <sys/user.h> /* After a.out.h *x/ */
/* OBSOLETE #include <sys/file.h> */
/* OBSOLETE #include "gdb_stat.h" */
/* OBSOLETE */
/* OBSOLETE #include <errno.h> */
/* OBSOLETE */
/* OBSOLETE void */
/* OBSOLETE fetch_inferior_registers (regno) */
/* OBSOLETE int regno; /* Original value discarded *x/ */
/* OBSOLETE { */
/* OBSOLETE register unsigned int regaddr; */
/* OBSOLETE char buf[MAX_REGISTER_RAW_SIZE]; */
/* OBSOLETE register int i; */
/* OBSOLETE */
/* OBSOLETE struct user u; */
/* OBSOLETE unsigned int offset = (char *) &u.u_ar0 - (char *) &u; */
/* OBSOLETE offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) */
/* OBSOLETE - KERNEL_U_ADDR; */
/* OBSOLETE */
/* OBSOLETE registers_fetched (); */
/* OBSOLETE */
/* OBSOLETE for (regno = 0; regno < 16; regno++) */
/* OBSOLETE { */
/* OBSOLETE regaddr = offset + regno * 4; */
/* OBSOLETE *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid, */
/* OBSOLETE (PTRACE_ARG3_TYPE) regaddr, 0); */
/* OBSOLETE if (regno == PC_REGNUM) */
/* OBSOLETE *(int *) &buf[0] = GET_PC_PART (*(int *) &buf[0]); */
/* OBSOLETE supply_register (regno, buf); */
/* OBSOLETE } */
/* OBSOLETE *(int *) &buf[0] = ptrace (PT_READ_U, inferior_pid, */
/* OBSOLETE (PTRACE_ARG3_TYPE) (offset + PC * 4), 0); */
/* OBSOLETE supply_register (PS_REGNUM, buf); /* set virtual register ps same as pc *x/ */
/* OBSOLETE */
/* OBSOLETE /* read the floating point registers *x/ */
/* OBSOLETE offset = (char *) &u.u_fp_regs - (char *) &u; */
/* OBSOLETE *(int *) buf = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0); */
/* OBSOLETE supply_register (FPS_REGNUM, buf); */
/* OBSOLETE for (regno = 16; regno < 24; regno++) */
/* OBSOLETE { */
/* OBSOLETE regaddr = offset + 4 + 12 * (regno - 16); */
/* OBSOLETE for (i = 0; i < 12; i += sizeof (int)) */
/* OBSOLETE *(int *) &buf[i] = ptrace (PT_READ_U, inferior_pid, */
/* OBSOLETE (PTRACE_ARG3_TYPE) (regaddr + i), 0); */
/* OBSOLETE supply_register (regno, buf); */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE /* Store our register values back into the inferior. */
/* OBSOLETE If REGNO is -1, do this for all registers. */
/* OBSOLETE Otherwise, REGNO specifies which register (so we can save time). *x/ */
/* OBSOLETE */
/* OBSOLETE void */
/* OBSOLETE store_inferior_registers (regno) */
/* OBSOLETE int regno; */
/* OBSOLETE { */
/* OBSOLETE register unsigned int regaddr; */
/* OBSOLETE char buf[80]; */
/* OBSOLETE */
/* OBSOLETE struct user u; */
/* OBSOLETE unsigned long value; */
/* OBSOLETE unsigned int offset = (char *) &u.u_ar0 - (char *) &u; */
/* OBSOLETE offset = ptrace (PT_READ_U, inferior_pid, (PTRACE_ARG3_TYPE) offset, 0) */
/* OBSOLETE - KERNEL_U_ADDR; */
/* OBSOLETE */
/* OBSOLETE if (regno >= 0) */
/* OBSOLETE { */
/* OBSOLETE if (regno >= 16) */
/* OBSOLETE return; */
/* OBSOLETE regaddr = offset + 4 * regno; */
/* OBSOLETE errno = 0; */
/* OBSOLETE value = read_register (regno); */
/* OBSOLETE if (regno == PC_REGNUM) */
/* OBSOLETE value = SET_PC_PART (read_register (PS_REGNUM), value); */
/* OBSOLETE ptrace (PT_WRITE_U, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value); */
/* OBSOLETE if (errno != 0) */
/* OBSOLETE { */
/* OBSOLETE sprintf (buf, "writing register number %d", regno); */
/* OBSOLETE perror_with_name (buf); */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE for (regno = 0; regno < 15; regno++) */
/* OBSOLETE { */
/* OBSOLETE regaddr = offset + regno * 4; */
/* OBSOLETE errno = 0; */
/* OBSOLETE value = read_register (regno); */
/* OBSOLETE if (regno == PC_REGNUM) */
/* OBSOLETE value = SET_PC_PART (read_register (PS_REGNUM), value); */
/* OBSOLETE ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, value); */
/* OBSOLETE if (errno != 0) */
/* OBSOLETE { */
/* OBSOLETE sprintf (buf, "writing all regs, number %d", regno); */
/* OBSOLETE perror_with_name (buf); */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE /* Work with core dump and executable files, for GDB. */
/* OBSOLETE This code would be in corefile.c if it weren't machine-dependent. *x/ */
/* OBSOLETE */
/* OBSOLETE /* Structure to describe the chain of shared libraries used */
/* OBSOLETE by the execfile. */
/* OBSOLETE e.g. prog shares Xt which shares X11 which shares c. *x/ */
/* OBSOLETE */
/* OBSOLETE struct shared_library */
/* OBSOLETE { */
/* OBSOLETE struct exec_header header; */
/* OBSOLETE char name[SHLIBLEN]; */
/* OBSOLETE CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file *x/ */
/* OBSOLETE long data_offset; /* offset of data section in file *x/ */
/* OBSOLETE int chan; /* file descriptor for the file *x/ */
/* OBSOLETE struct shared_library *shares; /* library this one shares *x/ */
/* OBSOLETE }; */
/* OBSOLETE static struct shared_library *shlib = 0; */
/* OBSOLETE */
/* OBSOLETE /* Hook for `exec_file_command' command to call. *x/ */
/* OBSOLETE */
/* OBSOLETE extern void (*exec_file_display_hook) (); */
/* OBSOLETE */
/* OBSOLETE static CORE_ADDR unshared_text_start; */
/* OBSOLETE */
/* OBSOLETE /* extended header from exec file (for shared library info) *x/ */
/* OBSOLETE */
/* OBSOLETE static struct exec_header exec_header; */
/* OBSOLETE */
/* OBSOLETE void */
/* OBSOLETE core_file_command (filename, from_tty) */
/* OBSOLETE char *filename; */
/* OBSOLETE int from_tty; */
/* OBSOLETE { */
/* OBSOLETE int val; */
/* OBSOLETE */
/* OBSOLETE /* Discard all vestiges of any previous core file */
/* OBSOLETE and mark data and stack spaces as empty. *x/ */
/* OBSOLETE */
/* OBSOLETE if (corefile) */
/* OBSOLETE free (corefile); */
/* OBSOLETE corefile = 0; */
/* OBSOLETE */
/* OBSOLETE if (corechan >= 0) */
/* OBSOLETE close (corechan); */
/* OBSOLETE corechan = -1; */
/* OBSOLETE */
/* OBSOLETE data_start = 0; */
/* OBSOLETE data_end = 0; */
/* OBSOLETE stack_start = STACK_END_ADDR; */
/* OBSOLETE stack_end = STACK_END_ADDR; */
/* OBSOLETE */
/* OBSOLETE /* Now, if a new core file was specified, open it and digest it. *x/ */
/* OBSOLETE */
/* OBSOLETE if (filename) */
/* OBSOLETE { */
/* OBSOLETE filename = tilde_expand (filename); */
/* OBSOLETE make_cleanup (free, filename); */
/* OBSOLETE */
/* OBSOLETE if (have_inferior_p ()) */
/* OBSOLETE error ("To look at a core file, you must kill the program with \"kill\"."); */
/* OBSOLETE corechan = open (filename, O_RDONLY, 0); */
/* OBSOLETE if (corechan < 0) */
/* OBSOLETE perror_with_name (filename); */
/* OBSOLETE /* 4.2-style (and perhaps also sysV-style) core dump file. *x/ */
/* OBSOLETE { */
/* OBSOLETE struct user u; */
/* OBSOLETE */
/* OBSOLETE unsigned int reg_offset, fp_reg_offset; */
/* OBSOLETE */
/* OBSOLETE val = myread (corechan, &u, sizeof u); */
/* OBSOLETE if (val < 0) */
/* OBSOLETE perror_with_name ("Not a core file: reading upage"); */
/* OBSOLETE if (val != sizeof u) */
/* OBSOLETE error ("Not a core file: could only read %d bytes", val); */
/* OBSOLETE */
/* OBSOLETE /* We are depending on exec_file_command having been called */
/* OBSOLETE previously to set exec_data_start. Since the executable */
/* OBSOLETE and the core file share the same text segment, the address */
/* OBSOLETE of the data segment will be the same in both. *x/ */
/* OBSOLETE data_start = exec_data_start; */
/* OBSOLETE */
/* OBSOLETE data_end = data_start + NBPG * u.u_dsize; */
/* OBSOLETE stack_start = stack_end - NBPG * u.u_ssize; */
/* OBSOLETE data_offset = NBPG * UPAGES; */
/* OBSOLETE stack_offset = NBPG * (UPAGES + u.u_dsize); */
/* OBSOLETE */
/* OBSOLETE /* Some machines put an absolute address in here and some put */
/* OBSOLETE the offset in the upage of the regs. *x/ */
/* OBSOLETE reg_offset = (int) u.u_ar0; */
/* OBSOLETE if (reg_offset > NBPG * UPAGES) */
/* OBSOLETE reg_offset -= KERNEL_U_ADDR; */
/* OBSOLETE fp_reg_offset = (char *) &u.u_fp_regs - (char *) &u; */
/* OBSOLETE */
/* OBSOLETE /* I don't know where to find this info. */
/* OBSOLETE So, for now, mark it as not available. *x/ */
/* OBSOLETE N_SET_MAGIC (core_aouthdr, 0); */
/* OBSOLETE */
/* OBSOLETE /* Read the register values out of the core file and store */
/* OBSOLETE them where `read_register' will find them. *x/ */
/* OBSOLETE */
/* OBSOLETE { */
/* OBSOLETE register int regno; */
/* OBSOLETE */
/* OBSOLETE for (regno = 0; regno < NUM_REGS; regno++) */
/* OBSOLETE { */
/* OBSOLETE char buf[MAX_REGISTER_RAW_SIZE]; */
/* OBSOLETE */
/* OBSOLETE if (regno < 16) */
/* OBSOLETE val = lseek (corechan, reg_offset + 4 * regno, 0); */
/* OBSOLETE else if (regno < 24) */
/* OBSOLETE val = lseek (corechan, fp_reg_offset + 4 + 12 * (regno - 24), 0); */
/* OBSOLETE else if (regno == 24) */
/* OBSOLETE val = lseek (corechan, fp_reg_offset, 0); */
/* OBSOLETE else if (regno == 25) */
/* OBSOLETE val = lseek (corechan, reg_offset + 4 * PC, 0); */
/* OBSOLETE if (val < 0 */
/* OBSOLETE || (val = myread (corechan, buf, sizeof buf)) < 0) */
/* OBSOLETE { */
/* OBSOLETE char *buffer = (char *) alloca (strlen (REGISTER_NAME (regno)) */
/* OBSOLETE + 30); */
/* OBSOLETE strcpy (buffer, "Reading register "); */
/* OBSOLETE strcat (buffer, REGISTER_NAME (regno)); */
/* OBSOLETE */
/* OBSOLETE perror_with_name (buffer); */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE if (regno == PC_REGNUM) */
/* OBSOLETE *(int *) buf = GET_PC_PART (*(int *) buf); */
/* OBSOLETE supply_register (regno, buf); */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE if (filename[0] == '/') */
/* OBSOLETE corefile = savestring (filename, strlen (filename)); */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE corefile = concat (current_directory, "/", filename, NULL); */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE flush_cached_frames (); */
/* OBSOLETE select_frame (get_current_frame (), 0); */
/* OBSOLETE validate_files (); */
/* OBSOLETE } */
/* OBSOLETE else if (from_tty) */
/* OBSOLETE printf ("No core file now.\n"); */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE #if 0 */
/* OBSOLETE /* Work with core dump and executable files, for GDB. */
/* OBSOLETE This code would be in corefile.c if it weren't machine-dependent. *x/ */
/* OBSOLETE */
/* OBSOLETE /* Structure to describe the chain of shared libraries used */
/* OBSOLETE by the execfile. */
/* OBSOLETE e.g. prog shares Xt which shares X11 which shares c. *x/ */
/* OBSOLETE */
/* OBSOLETE struct shared_library */
/* OBSOLETE { */
/* OBSOLETE struct exec_header header; */
/* OBSOLETE char name[SHLIBLEN]; */
/* OBSOLETE CORE_ADDR text_start; /* CORE_ADDR of 1st byte of text, this file *x/ */
/* OBSOLETE long data_offset; /* offset of data section in file *x/ */
/* OBSOLETE int chan; /* file descriptor for the file *x/ */
/* OBSOLETE struct shared_library *shares; /* library this one shares *x/ */
/* OBSOLETE }; */
/* OBSOLETE static struct shared_library *shlib = 0; */
/* OBSOLETE */
/* OBSOLETE /* Hook for `exec_file_command' command to call. *x/ */
/* OBSOLETE */
/* OBSOLETE extern void (*exec_file_display_hook) (); */
/* OBSOLETE */
/* OBSOLETE static CORE_ADDR unshared_text_start; */
/* OBSOLETE */
/* OBSOLETE /* extended header from exec file (for shared library info) *x/ */
/* OBSOLETE */
/* OBSOLETE static struct exec_header exec_header; */
/* OBSOLETE */
/* OBSOLETE void */
/* OBSOLETE exec_file_command (filename, from_tty) */
/* OBSOLETE char *filename; */
/* OBSOLETE int from_tty; */
/* OBSOLETE { */
/* OBSOLETE int val; */
/* OBSOLETE */
/* OBSOLETE /* Eliminate all traces of old exec file. */
/* OBSOLETE Mark text segment as empty. *x/ */
/* OBSOLETE */
/* OBSOLETE if (execfile) */
/* OBSOLETE free (execfile); */
/* OBSOLETE execfile = 0; */
/* OBSOLETE data_start = 0; */
/* OBSOLETE data_end -= exec_data_start; */
/* OBSOLETE text_start = 0; */
/* OBSOLETE unshared_text_start = 0; */
/* OBSOLETE text_end = 0; */
/* OBSOLETE exec_data_start = 0; */
/* OBSOLETE exec_data_end = 0; */
/* OBSOLETE if (execchan >= 0) */
/* OBSOLETE close (execchan); */
/* OBSOLETE execchan = -1; */
/* OBSOLETE if (shlib) */
/* OBSOLETE { */
/* OBSOLETE close_shared_library (shlib); */
/* OBSOLETE shlib = 0; */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE /* Now open and digest the file the user requested, if any. *x/ */
/* OBSOLETE */
/* OBSOLETE if (filename) */
/* OBSOLETE { */
/* OBSOLETE filename = tilde_expand (filename); */
/* OBSOLETE make_cleanup (free, filename); */
/* OBSOLETE */
/* OBSOLETE execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, */
/* OBSOLETE &execfile); */
/* OBSOLETE if (execchan < 0) */
/* OBSOLETE perror_with_name (filename); */
/* OBSOLETE */
/* OBSOLETE { */
/* OBSOLETE struct stat st_exec; */
/* OBSOLETE */
/* OBSOLETE #ifdef HEADER_SEEK_FD */
/* OBSOLETE HEADER_SEEK_FD (execchan); */
/* OBSOLETE #endif */
/* OBSOLETE */
/* OBSOLETE val = myread (execchan, &exec_header, sizeof exec_header); */
/* OBSOLETE exec_aouthdr = exec_header.a_exec; */
/* OBSOLETE */
/* OBSOLETE if (val < 0) */
/* OBSOLETE perror_with_name (filename); */
/* OBSOLETE */
/* OBSOLETE text_start = 0x8000; */
/* OBSOLETE */
/* OBSOLETE /* Look for shared library if needed *x/ */
/* OBSOLETE if (exec_header.a_exec.a_magic & MF_USES_SL) */
/* OBSOLETE shlib = open_shared_library (exec_header.a_shlibname, text_start); */
/* OBSOLETE */
/* OBSOLETE text_offset = N_TXTOFF (exec_aouthdr); */
/* OBSOLETE exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; */
/* OBSOLETE */
/* OBSOLETE if (shlib) */
/* OBSOLETE { */
/* OBSOLETE unshared_text_start = shared_text_end (shlib) & ~0x7fff; */
/* OBSOLETE stack_start = shlib->header.a_exec.a_sldatabase; */
/* OBSOLETE stack_end = STACK_END_ADDR; */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE unshared_text_start = 0x8000; */
/* OBSOLETE text_end = unshared_text_start + exec_aouthdr.a_text; */
/* OBSOLETE */
/* OBSOLETE exec_data_start = unshared_text_start + exec_aouthdr.a_text; */
/* OBSOLETE exec_data_end = exec_data_start + exec_aouthdr.a_data; */
/* OBSOLETE */
/* OBSOLETE data_start = exec_data_start; */
/* OBSOLETE data_end += exec_data_start; */
/* OBSOLETE */
/* OBSOLETE fstat (execchan, &st_exec); */
/* OBSOLETE exec_mtime = st_exec.st_mtime; */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE validate_files (); */
/* OBSOLETE } */
/* OBSOLETE else if (from_tty) */
/* OBSOLETE printf ("No executable file now.\n"); */
/* OBSOLETE */
/* OBSOLETE /* Tell display code (if any) about the changed file name. *x/ */
/* OBSOLETE if (exec_file_display_hook) */
/* OBSOLETE (*exec_file_display_hook) (filename); */
/* OBSOLETE } */
/* OBSOLETE #endif */
/* OBSOLETE */
/* OBSOLETE #if 0 */
/* OBSOLETE /* Read from the program's memory (except for inferior processes). */
/* OBSOLETE This function is misnamed, since it only reads, never writes; and */
/* OBSOLETE since it will use the core file and/or executable file as necessary. */
/* OBSOLETE */
/* OBSOLETE It should be extended to write as well as read, FIXME, for patching files. */
/* OBSOLETE */
/* OBSOLETE Return 0 if address could be read, EIO if addresss out of bounds. *x/ */
/* OBSOLETE */
/* OBSOLETE int */
/* OBSOLETE xfer_core_file (memaddr, myaddr, len) */
/* OBSOLETE CORE_ADDR memaddr; */
/* OBSOLETE char *myaddr; */
/* OBSOLETE int len; */
/* OBSOLETE { */
/* OBSOLETE register int i; */
/* OBSOLETE register int val; */
/* OBSOLETE int xferchan; */
/* OBSOLETE char **xferfile; */
/* OBSOLETE int fileptr; */
/* OBSOLETE int returnval = 0; */
/* OBSOLETE */
/* OBSOLETE while (len > 0) */
/* OBSOLETE { */
/* OBSOLETE xferfile = 0; */
/* OBSOLETE xferchan = 0; */
/* OBSOLETE */
/* OBSOLETE /* Determine which file the next bunch of addresses reside in, */
/* OBSOLETE and where in the file. Set the file's read/write pointer */
/* OBSOLETE to point at the proper place for the desired address */
/* OBSOLETE and set xferfile and xferchan for the correct file. */
/* OBSOLETE */
/* OBSOLETE If desired address is nonexistent, leave them zero. */
/* OBSOLETE */
/* OBSOLETE i is set to the number of bytes that can be handled */
/* OBSOLETE along with the next address. */
/* OBSOLETE */
/* OBSOLETE We put the most likely tests first for efficiency. *x/ */
/* OBSOLETE */
/* OBSOLETE /* Note that if there is no core file */
/* OBSOLETE data_start and data_end are equal. *x/ */
/* OBSOLETE if (memaddr >= data_start && memaddr < data_end) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, data_end - memaddr); */
/* OBSOLETE fileptr = memaddr - data_start + data_offset; */
/* OBSOLETE xferfile = &corefile; */
/* OBSOLETE xferchan = corechan; */
/* OBSOLETE } */
/* OBSOLETE /* Note that if there is no core file */
/* OBSOLETE stack_start and stack_end define the shared library data. *x/ */
/* OBSOLETE else if (memaddr >= stack_start && memaddr < stack_end) */
/* OBSOLETE { */
/* OBSOLETE if (corechan < 0) */
/* OBSOLETE { */
/* OBSOLETE struct shared_library *lib; */
/* OBSOLETE for (lib = shlib; lib; lib = lib->shares) */
/* OBSOLETE if (memaddr >= lib->header.a_exec.a_sldatabase && */
/* OBSOLETE memaddr < lib->header.a_exec.a_sldatabase + */
/* OBSOLETE lib->header.a_exec.a_data) */
/* OBSOLETE break; */
/* OBSOLETE if (lib) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, lib->header.a_exec.a_sldatabase + */
/* OBSOLETE lib->header.a_exec.a_data - memaddr); */
/* OBSOLETE fileptr = lib->data_offset + memaddr - */
/* OBSOLETE lib->header.a_exec.a_sldatabase; */
/* OBSOLETE xferfile = execfile; */
/* OBSOLETE xferchan = lib->chan; */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE i = min (len, stack_end - memaddr); */
/* OBSOLETE fileptr = memaddr - stack_start + stack_offset; */
/* OBSOLETE xferfile = &corefile; */
/* OBSOLETE xferchan = corechan; */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE else if (corechan < 0 */
/* OBSOLETE && memaddr >= exec_data_start && memaddr < exec_data_end) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, exec_data_end - memaddr); */
/* OBSOLETE fileptr = memaddr - exec_data_start + exec_data_offset; */
/* OBSOLETE xferfile = &execfile; */
/* OBSOLETE xferchan = execchan; */
/* OBSOLETE } */
/* OBSOLETE else if (memaddr >= text_start && memaddr < text_end) */
/* OBSOLETE { */
/* OBSOLETE struct shared_library *lib; */
/* OBSOLETE for (lib = shlib; lib; lib = lib->shares) */
/* OBSOLETE if (memaddr >= lib->text_start && */
/* OBSOLETE memaddr < lib->text_start + lib->header.a_exec.a_text) */
/* OBSOLETE break; */
/* OBSOLETE if (lib) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, lib->header.a_exec.a_text + */
/* OBSOLETE lib->text_start - memaddr); */
/* OBSOLETE fileptr = memaddr - lib->text_start + text_offset; */
/* OBSOLETE xferfile = &execfile; */
/* OBSOLETE xferchan = lib->chan; */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE i = min (len, text_end - memaddr); */
/* OBSOLETE fileptr = memaddr - unshared_text_start + text_offset; */
/* OBSOLETE xferfile = &execfile; */
/* OBSOLETE xferchan = execchan; */
/* OBSOLETE } */
/* OBSOLETE } */
/* OBSOLETE else if (memaddr < text_start) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, text_start - memaddr); */
/* OBSOLETE } */
/* OBSOLETE else if (memaddr >= text_end */
/* OBSOLETE && memaddr < (corechan >= 0 ? data_start : exec_data_start)) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, data_start - memaddr); */
/* OBSOLETE } */
/* OBSOLETE else if (corechan >= 0 */
/* OBSOLETE && memaddr >= data_end && memaddr < stack_start) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, stack_start - memaddr); */
/* OBSOLETE } */
/* OBSOLETE else if (corechan < 0 && memaddr >= exec_data_end) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, -memaddr); */
/* OBSOLETE } */
/* OBSOLETE else if (memaddr >= stack_end && stack_end != 0) */
/* OBSOLETE { */
/* OBSOLETE i = min (len, -memaddr); */
/* OBSOLETE } */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE /* Address did not classify into one of the known ranges. */
/* OBSOLETE This shouldn't happen; we catch the endpoints. *x/ */
/* OBSOLETE internal_error ("Bad case logic in xfer_core_file."); */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE /* Now we know which file to use. */
/* OBSOLETE Set up its pointer and transfer the data. *x/ */
/* OBSOLETE if (xferfile) */
/* OBSOLETE { */
/* OBSOLETE if (*xferfile == 0) */
/* OBSOLETE if (xferfile == &execfile) */
/* OBSOLETE error ("No program file to examine."); */
/* OBSOLETE else */
/* OBSOLETE error ("No core dump file or running program to examine."); */
/* OBSOLETE val = lseek (xferchan, fileptr, 0); */
/* OBSOLETE if (val < 0) */
/* OBSOLETE perror_with_name (*xferfile); */
/* OBSOLETE val = myread (xferchan, myaddr, i); */
/* OBSOLETE if (val < 0) */
/* OBSOLETE perror_with_name (*xferfile); */
/* OBSOLETE } */
/* OBSOLETE /* If this address is for nonexistent memory, */
/* OBSOLETE read zeros if reading, or do nothing if writing. */
/* OBSOLETE Actually, we never right. *x/ */
/* OBSOLETE else */
/* OBSOLETE { */
/* OBSOLETE memset (myaddr, '\0', i); */
/* OBSOLETE returnval = EIO; */
/* OBSOLETE } */
/* OBSOLETE */
/* OBSOLETE memaddr += i; */
/* OBSOLETE myaddr += i; */
/* OBSOLETE len -= i; */
/* OBSOLETE } */
/* OBSOLETE return returnval; */
/* OBSOLETE } */
/* OBSOLETE #endif */

File diff suppressed because it is too large Load Diff

View File

@ -1,349 +0,0 @@
/* Host callback routines for GDB.
Copyright 1995 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* This file provides a standard way for targets to talk to the host OS
level.
This interface will probably need a bit more banging to make it
smooth. Currently the simulator uses this file to provide the
callbacks for itself when it's built standalone, which is rather
ugly. */
#ifndef INSIDE_SIMULATOR
#include "defs.h"
#endif
#include "ansidecl.h"
#include "callback.h"
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
/* Set the callback copy of errno from what we see now. */
static int
wrap (p, val)
host_callback *p;
int val;
{
p->last_errno = errno;
return val;
}
/* Make sure the FD provided is ok. If not, return non-zero
and set errno. */
static int
fdbad (p, fd)
host_callback *p;
int fd;
{
if (fd < 0 || fd > MAX_CALLBACK_FDS || !p->fdopen[fd])
{
p->last_errno = EINVAL;
return -1;
}
return 0;
}
static int
fdmap (p, fd)
host_callback *p;
int fd;
{
return p->fdmap[fd];
}
int
os_close (p, fd)
host_callback *p;
int fd;
{
int result;
result = fdbad (p, fd);
if (result)
return result;
result = wrap (p, close (fdmap (p, fd)));
return result;
}
int
os_get_errno (p)
host_callback *p;
{
/* !!! fixme, translate from host to taget errno value */
return p->last_errno;
}
int
os_isatty (p, fd)
host_callback *p;
int fd;
{
int result;
result = fdbad (p, fd);
if (result)
return result;
result = wrap (p, isatty (fdmap (fd)));
return result;
}
int
os_lseek (p, fd, off, way)
host_callback *p;
int fd;
long off;
int way;
{
int result;
result = fdbad (p, fd);
if (result)
return result;
result = lseek (fdmap (p, fd), off, way);
return result;
}
int
os_open (p, name, flags)
host_callback *p;
const char *name;
int flags;
{
int i;
for (i = 0; i < MAX_CALLBACK_FDS; i++)
{
if (!p->fdopen[i])
{
int f = open (name, flags);
if (f < 0)
{
p->last_errno = errno;
return f;
}
p->fdopen[i] = 1;
p->fdmap[i] = f;
return i;
}
}
p->last_errno = EMFILE;
return -1;
}
int
os_read (p, fd, buf, len)
host_callback *p;
int fd;
char *buf;
int len;
{
int result;
result = fdbad (p, fd);
if (result)
return result;
result = wrap (p, read (fdmap (p, fd), buf, len));
return result;
}
int
os_read_stdin (p, buf, len)
host_callback *p;
char *buf;
int len;
{
return wrap (p, read (0, buf, len));
}
int
os_write (p, fd, buf, len)
host_callback *p;
int fd;
const char *buf;
int len;
{
int result;
result = fdbad (p, fd);
if (result)
return result;
result = wrap (p, write (fdmap (p, fd), buf, len));
return result;
}
/* ignore the grossness of INSIDE_SIMULATOR, it will go away one day. */
int
os_write_stdout (p, buf, len)
host_callback *p;
const char *buf;
int len;
{
#ifdef INSIDE_SIMULATOR
return os_write (p, 1, buf, len);
#else
int i;
char b[2];
for (i = 0; i< len; i++)
{
b[0] = buf[i];
b[1] = 0;
if (target_output_hook)
target_output_hook (b);
else
fputs_filtered (b, gdb_stdout);
}
return len;
#endif
}
int
os_rename (p, f1, f2)
host_callback *p;
const char *f1;
const char *f2;
{
return wrap (p, rename (f1, f2));
}
int
os_system (p, s)
host_callback *p;
const char *s;
{
return wrap (p, system (s));
}
long
os_time (p, t)
host_callback *p;
long *t;
{
return wrap (p, time (t));
}
int
os_unlink (p, f1)
host_callback *p;
const char *f1;
{
return wrap (p, unlink (f1));
}
int
os_shutdown (p)
host_callback *p;
{
int i;
for (i = 0; i < MAX_CALLBACK_FDS; i++)
{
if (p->fdopen[i] && !p->alwaysopen[i]) {
close (p->fdmap[i]);
p->fdopen[i] = 0;
}
}
return 1;
}
int os_init(p)
host_callback *p;
{
int i;
os_shutdown (p);
for (i= 0; i < 3; i++)
{
p->fdmap[i] = i;
p->fdopen[i] = 1;
p->alwaysopen[i] = 1;
}
return 1;
}
/* !!fixme!!
This bit is ugly. When the interface has settled down I'll
move the whole file into sim/common and remove this bit. */
/* VARARGS */
void
#ifdef ANSI_PROTOTYPES
os_printf_filtered (host_callback *p, const char *format, ...)
#else
os_printf_filtered (p, va_alist)
host_callback *p;
va_dcl
#endif
{
va_list args;
#ifdef ANSI_PROTOTYPES
va_start (args, format);
#else
char *format;
va_start (args);
format = va_arg (args, char *);
#endif
#ifdef INSIDE_SIMULATOR
vprintf (format, args);
#else
vfprintf_filtered (stdout, format, args);
#endif
va_end (args);
}
host_callback default_callback =
{
os_close,
os_get_errno,
os_isatty,
os_lseek,
os_open,
os_read,
os_read_stdin,
os_rename,
os_system,
os_time,
os_unlink,
os_write,
os_write_stdout,
os_shutdown,
os_init,
os_printf_filtered,
0, /* last errno */
};

View File

@ -1,41 +0,0 @@
#ifndef CALLBACK_H
#define CALLBACK_H
typedef struct host_callback_struct host_callback;
#define MAX_CALLBACK_FDS 10
struct host_callback_struct
{
int (*close) PARAMS ((host_callback *,int));
int (*get_errno) PARAMS ((host_callback *));
int (*isatty) PARAMS ((host_callback *, int));
int (*lseek) PARAMS ((host_callback *, int, long , int));
int (*open) PARAMS ((host_callback *, const char*, int mode));
int (*read) PARAMS ((host_callback *,int, char *, int));
int (*read_stdin) PARAMS (( host_callback *, char *, int));
int (*rename) PARAMS ((host_callback *, const char *, const char *));
int (*system) PARAMS ((host_callback *, const char *));
long (*time) PARAMS ((host_callback *, long *));
int (*unlink) PARAMS ((host_callback *, const char *));
int (*write) PARAMS ((host_callback *,int, const char *, int));
int (*write_stdout) PARAMS ((host_callback *, const char *, int));
/* Used when the target has gone away, so we can close open
handles and free memory etc etc. */
int (*shutdown) PARAMS ((host_callback *));
int (*init) PARAMS ((host_callback *));
/* Talk to the user on a console. */
void (*printf_filtered) PARAMS ((host_callback *, const char *, ...));
int last_errno; /* host format */
int fdmap[MAX_CALLBACK_FDS];
char fdopen[MAX_CALLBACK_FDS];
char alwaysopen[MAX_CALLBACK_FDS];
};
#endif
extern host_callback default_callback;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +0,0 @@
MH_CFLAGS=
XM_FILE=xm-cygwin32.h
TERMCAP=
NATDEPFILES=win32-nat.o
XM_CLIBS=-lkernel32

View File

@ -1,6 +0,0 @@
# Target: Intel 386 run win32
TDEPFILES= i386-tdep.o i387-tdep.o
TM_FILE= tm-cygwin32.h

View File

@ -1,27 +0,0 @@
/* Native support for Sun 386i, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH
/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
#define FETCH_INFERIOR_REGISTERS
#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)

View File

@ -1,5 +0,0 @@
# Host: Sun 386i
XDEPFILES=
XM_FILE= xm-sun386.h
NAT_FILE= nm-sun386.h
NATDEPFILES= infptrace.o inftarg.o fork-child.o sun386-nat.o

View File

@ -1,3 +0,0 @@
# Target: Sun 386i target configuration file.
TDEPFILES= i386-tdep.o solib.o
TM_FILE= tm-sun386.h

View File

@ -1,125 +0,0 @@
/* Macro definitions for i386 running under the win32 API Unix.
Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "i386/tm-i386v.h"
#undef MAX_REGISTER_RAW_SIZE
#undef MAX_REGISTER_VIRTUAL_SIZE
#undef NUM_REGS
#undef REGISTER_BYTE
#undef REGISTER_BYTES
#undef REGISTER_CONVERTIBLE
#undef REGISTER_CONVERT_TO_RAW
#undef REGISTER_CONVERT_TO_VIRTUAL
#undef REGISTER_NAMES
#undef REGISTER_RAW_SIZE
#undef REGISTER_VIRTUAL_SIZE
#undef REGISTER_VIRTUAL_TYPE
/* Number of machine registers */
#define NUM_REGS 24
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
/* the order of the first 8 registers must match the compiler's
* numbering scheme (which is the same as the 386 scheme)
* also, this table must match regmap in i386-pinsn.c.
*/
#define REGISTER_NAMES { "eax", "ecx", "edx", "ebx", \
"esp", "ebp", "esi", "edi", \
"eip", "ps", "cs", "ss", \
"ds", "es", "fs", "gs", \
"st", "st(1)","st(2)","st(3)",\
"st(4)","st(5)","st(6)","st(7)",}
#define FP0_REGNUM 16
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (16 * 4 + 8 * 10)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) (((N) < 16) ? (N) * 4 : (((N) - 16) * 10) + (16 * 4))
/* Number of bytes of storage in the actual machine representation
for register N. */
#define REGISTER_RAW_SIZE(N) (((N) < 16) ? 4 : 10)
/* Number of bytes of storage in the program's representation
for register N. */
#define REGISTER_VIRTUAL_SIZE(N) (((N) < 16) ? 4 : 10)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 10
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 10
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) \
((N < FP0_REGNUM) ? 0 : 1)
/* Convert data from raw format for register REGNUM in buffer FROM
to virtual format with type TYPE in buffer TO. */
extern void
i387_to_double PARAMS ((char *, char *));
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
{ \
double val; \
i387_to_double ((FROM), (char *)&val); \
store_floating ((TO), TYPE_LENGTH (TYPE), val); \
}
extern void
double_to_i387 PARAMS ((char *, char *));
#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
{ \
double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
double_to_i387((char *)&val, (TO)); \
}
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
((N < FP0_REGNUM) ? builtin_type_int : \
builtin_type_double)
#define NAMES_HAVE_UNDERSCORE
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) skip_trampoline_code (pc, name)
#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, 0)
extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR pc, char *name));

View File

@ -1,205 +0,0 @@
/* Parameters for a Sun 386i target machine, for GDB, the GNU debugger.
Copyright 1986, 1987, 1991, 1992, 1993 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#if !defined (TM_SUN386_H)
#define TM_SUN386_H 1
#include "i386/tm-i386.h"
#ifndef sun386
#define sun386
#endif
#define GDB_TARGET_IS_SUN386 1
#define SUNOS4
#define USE_MACHINE_REG_H
/* Perhaps some day this will work even without the following #define */
#define COFF_ENCAPSULATE
#ifdef COFF_ENCAPSULATE
/* Avoid conflicts between our include files and <sys/exec.h>
(maybe not needed anymore). */
#define _EXEC_
#endif
/* sun386 ptrace seems unable to change the frame pointer */
#define PTRACE_FP_BUG
/* Address of end of stack space. */
#define STACK_END_ADDR 0xfc000000
/* Number of machine registers */
#undef NUM_REGS
#define NUM_REGS 35
/* Initializer for an array of names of registers. There should be NUM_REGS
strings in this initializer. The order of the first 8 registers must match
the compiler's numbering scheme (which is the same as the 386 scheme) also,
this table must match regmap in i386-pinsn.c. */
#undef REGISTER_NAMES
#define REGISTER_NAMES { "gs", "fs", "es", "ds", \
"edi", "esi", "ebp", "esp", \
"ebx", "edx", "ecx", "eax", \
"retaddr", "trapnum", "errcode", "ip", \
"cs", "ps", "sp", "ss", \
"fst0", "fst1", "fst2", "fst3", \
"fst4", "fst5", "fst6", "fst7", \
"fctrl", "fstat", "ftag", "fip", \
"fcs", "fopoff", "fopsel" \
}
/* 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. */
#undef FP_REGNUM
#define FP_REGNUM 6 /* (ebp) Contains address of executing stack frame */
#undef SP_REGNUM
#define SP_REGNUM 18 /* (usp) Contains address of top of stack */
#undef PS_REGNUM
#define PS_REGNUM 17 /* (ps) Contains processor status */
#undef PC_REGNUM
#define PC_REGNUM 15 /* (eip) Contains program counter */
#undef FP0_REGNUM
#define FP0_REGNUM 20 /* Floating point register 0 */
#undef FPC_REGNUM
#define FPC_REGNUM 28 /* 80387 control register */
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#undef REGISTER_BYTES
#define REGISTER_BYTES (20*4+8*10+7*4)
/* Index within `registers' of the first byte of the space for
register N. */
#undef REGISTER_BYTE
#define REGISTER_BYTE(N) \
((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 160 \
: (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 10) + 80 \
: (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. */
#undef REGISTER_RAW_SIZE
#define REGISTER_RAW_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 10 : 4)
/* Number of bytes of storage in the program's representation
for register N. */
#undef REGISTER_VIRTUAL_SIZE
#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)((N) - FP0_REGNUM)) < 8 ? 8 : 4)
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#undef REGISTER_CONVERTIBLE
#define REGISTER_CONVERTIBLE(N) (((unsigned)((N) - FP0_REGNUM)) < 8)
/* Convert data from raw format for register REGNUM in buffer FROM
to virtual format with type TYPE in buffer TO. */
#undef REGISTER_CONVERT_TO_VIRTUAL
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,TYPE,FROM,TO) \
{ \
double val; \
i387_to_double ((FROM), (char *)&val); \
store_floating ((TO), TYPE_LENGTH (TYPE), val); \
}
extern void
i387_to_double PARAMS ((char *, char *));
/* Convert data from virtual format with type TYPE in buffer FROM
to raw format for register REGNUM in buffer TO. */
#undef REGISTER_CONVERT_TO_RAW
#define REGISTER_CONVERT_TO_RAW(TYPE,REGNUM,FROM,TO) \
{ \
double val = extract_floating ((FROM), TYPE_LENGTH (TYPE)); \
double_to_i387((char *)&val, (TO)); \
}
extern void
double_to_i387 PARAMS ((char *, char *));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#undef REGISTER_VIRTUAL_TYPE
#define REGISTER_VIRTUAL_TYPE(N) \
(((unsigned)((N) - FP0_REGNUM)) < 8 ? builtin_type_double : builtin_type_int)
/* 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. */
#undef EXTRACT_RETURN_VALUE
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
memcpy (VALBUF, REGBUF + REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#undef STORE_RETURN_VALUE
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 11), VALBUF, TYPE_LENGTH (TYPE))
/* 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. */
#undef FRAME_CHAIN
#define FRAME_CHAIN(thisframe) \
(!inside_entry_file ((thisframe)->pc) ? \
read_memory_integer ((thisframe)->frame, 4) :\
0)
/* Define other aspects of the stack frame. */
/* A macro that tells us whether the function invocation represented
by FI does not have a frame on the stack associated with it. If it
does not, FRAMELESS is set to 1, else 0. */
#undef FRAMELESS_FUNCTION_INVOCATION
#define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \
{ (FRAMELESS) = frameless_look_for_prologue (FI); }
#undef FRAME_SAVED_PC
#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#undef FIX_CALL_DUMMY
#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, gcc_p) \
{ \
*(int *)((char *)(dummyname) + 1) = (int)(fun) - (pc) - 5; \
}
#endif /* !defined (TM_SUN386_H) */

View File

@ -1,17 +0,0 @@
# gdbwin.o and ser-win32s.c have to be named because they have
# _initialize functions that need to be found by init.c
# gui.ores has to be named, or else msvc won't link it in.
XDEPFILES = \
mswin/gdbwin.o \
mswin/ser-win32s.o \
mswin/gui.ores \
mswin/libwingdb.a
$(XDEPFILES):
rootme=`pwd` ; export rootme ; \
( cd mswin ; \
$(MAKE) $(FLAGS_TO_PASS) all )
XM_FILE=xm-windows.h
MMALLOC=
SER_HARDWIRE =

View File

@ -1,41 +0,0 @@
/* Definitions for hosting on WIN32, for GDB.
Copyright 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
#include "fopen-bin.h"
#define GDBINIT_FILENAME "gdb.ini"
#define SLASH_P(X) ((X)=='\\' || (X) == '/')
#define ROOTED_P(X) ((SLASH_P((X)[0]))|| ((X)[1] ==':'))
#define SLASH_CHAR '/'
#define SLASH_STRING "/"
/* If we longjmp out of the signal handler we never get another one.
So disable immediate_quit inside request_quit */
#define REQUEST_QUIT

View File

@ -1,24 +0,0 @@
/* Host-dependent definitions for Intel 386 running LynxOS.
Copyright 1993 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN
/* Get generic LynxOS host definitions. */
#include "xm-lynx.h"

View File

@ -1,36 +0,0 @@
/* Native support for GNU/Linux, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef XM_LINUX_H
#define XM_LINUX_H
#define HOST_BYTE_ORDER LITTLE_ENDIAN
#define HAVE_TERMIOS
/* 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 0x0
#define NEED_POSIX_SETPGID
/* Need R_OK etc, but USG isn't defined. */
#include <unistd.h>
#endif /* #ifndef XM_LINUX_H */

View File

@ -1,20 +0,0 @@
/* Host support for Sun 386i, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define HOST_BYTE_ORDER LITTLE_ENDIAN

View File

@ -1,35 +0,0 @@
/* Definitions for hosting on WIN32, built with Microsoft Visual C/C++, for GDB.
Copyright 1996, 1998 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "i386/xm-cygwin.h"
#undef PRINTF_HAS_LONG_LONG
#undef HAVE_UNISTD_H
#undef HAVE_TERMIO_H
#undef HAVE_TERMIOS_H
#undef HAVE_SGTTY_H
#undef HAVE_SBRK
#define CANT_FORK
#define MALLOC_INCOMPATIBLE
#include <malloc.h>
#define SIGQUIT 3
#define SIGTRAP 5

View File

@ -1,2 +0,0 @@
/* This is just a dummy file to symlink to when GDB is configured as a
cross-only debugger. */

View File

@ -1,43 +0,0 @@
/* Common declarations for the GNU Hurd
Copyright 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
The GNU Hurd is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
The GNU Hurd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef __NM_GNU_H__
#define __NM_GNU_H__
#include <unistd.h>
#include <mach.h>
#include <mach/exception.h>
#include "regcache.h"
extern char *gnu_target_pid_to_str (int pid);
/* Before storing, we need to read all the registers. */
#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
/* Don't do wait_for_inferior on attach. */
#define ATTACH_NO_WAIT
/* Use SVR4 style shared library support */
#define SVR4_SHARED_LIBS
#include "solib.h"
#define NO_CORE_OPS
#endif /* __NM_GNU_H__ */

View File

@ -1,85 +0,0 @@
/* Native-dependent definitions for LynxOS.
Copyright 1993, 1994, 1995, 1996, 1999, 2000
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef NM_LYNX_H
#define NM_LYNX_H
#include <sys/conf.h>
#include <sys/kernel.h>
/* sys/kernel.h should define this, but doesn't always, sigh. */
#ifndef __LYNXOS
#define __LYNXOS
#endif
#include <sys/mem.h>
#include <sys/signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/itimer.h>
#include <sys/file.h>
#include <sys/proc.h>
#include "gdbthread.h"
/* 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 USRSTACK
#undef FLOAT_INFO /* No float info yet */
/* As of LynxOS 2.2.2 (beta 8/15/94), this is int. Previous versions seem to
have had no prototype, so I'm not sure why GDB used to define this to
char *. */
#define PTRACE_ARG3_TYPE int
/* Override copies of {fetch,store}_inferior_registers in infptrace.c. */
#define FETCH_INFERIOR_REGISTERS
/* Thread ID of stopped thread. */
#define WIFTID(x) (((union wait *)&x)->w_tid)
/* Override child_wait in inftarg.c */
#define CHILD_WAIT
/* Override child_resume in infptrace.c */
#define CHILD_RESUME
/* Override child_thread_alive in intarg.c */
#define CHILD_THREAD_ALIVE
#include "target.h"
extern ptid_t child_wait (ptid_t ptid,
struct target_waitstatus *status);
/* Lynx needs a special definition of this so that we can
print out the pid and thread number seperately. */
/* override child_pid_to_str in inftarg.c */
#define CHILD_PID_TO_STR
extern char *lynx_pid_to_str (ptid_t ptid);
#endif /* NM_LYNX_H */

View File

@ -1,126 +0,0 @@
/* Mach 3.0 common definitions and global vars.
Copyright 1992, 1993, 1994, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef NM_M3_H
#define NM_M3_H
#include <mach.h>
#include "regcache.h"
/* Mach3 doesn't declare errno in <errno.h>. */
extern int errno;
/* Task port of our debugged inferior. */
extern task_t inferior_task;
/* Thread port of the current thread in the inferior. */
extern thread_t current_thread;
/* If nonzero, we must suspend/abort && resume threads
* when setting or getting the state.
*/
extern int must_suspend_thread;
#define PREPARE_TO_PROCEED(select_it) mach3_prepare_to_proceed(select_it)
/* Try to get the privileged host port for authentication to machid
* If you can get this, you may debug anything on this host.
*
* If you can't, gdb gives it's own task port as the
* authentication port
*/
#define mach_privileged_host_port() task_by_pid(-1)
/*
* This is the MIG ID number of the emulator/server bsd_execve() RPC call.
*
* It SHOULD never change, but if it does, gdb `run'
* command won't work until you fix this define.
*
*/
#define MIG_EXEC_SYSCALL_ID 101000
/* If our_message_port gets a msg with this ID,
* GDB suspends it's inferior and enters command level.
* (Useful at least if ^C does not work)
*/
#define GDB_MESSAGE_ID_STOP 0x41151
/* wait3 WNOHANG is defined in <sys/wait.h> but
* for some reason gdb does not want to include
* that file.
*
* If your system defines WNOHANG differently, this has to be changed.
*/
#define WNOHANG 1
/* Before storing, we need to read all the registers. */
#define CHILD_PREPARE_TO_STORE() read_register_bytes (0, NULL, REGISTER_BYTES)
/* Check if the inferior exists */
#define MACH_ERROR_NO_INFERIOR \
do if (!MACH_PORT_VALID (inferior_task)) \
error ("Inferior task does not exist."); while(0)
/* Error handler for mach calls */
#define CHK(str,ret) \
do if (ret != KERN_SUCCESS) \
error ("Gdb %s [%d] %s : %s\n",__FILE__,__LINE__,str, \
mach_error_string(ret)); while(0)
/* This is from POE9 emulator/emul_stack.h
*/
/*
* Top of emulator stack holds link and reply port.
*/
struct emul_stack_top
{
struct emul_stack_top *link;
mach_port_t reply_port;
};
#define EMULATOR_STACK_SIZE (4096*4)
#define THREAD_ALLOWED_TO_BREAK(mid) mach_thread_for_breakpoint (mid)
#define THREAD_PARSE_ID(arg) mach_thread_parse_id (arg)
#define THREAD_OUTPUT_ID(mid) mach_thread_output_id (mid)
#define ATTACH_TO_THREAD attach_to_thread
/* Don't do wait_for_inferior on attach. */
#define ATTACH_NO_WAIT
/* Do Mach 3 dependent operations when ^C or a STOP is requested */
#define DO_QUIT() mach3_quit ()
#if 0
/* This is bogus. It is NOT OK to quit out of target_wait. */
/* If in mach_msg() and ^C is typed set immediate_quit */
#define REQUEST_QUIT() mach3_request_quit ()
#endif
#endif /* NM_M3_H */

View File

@ -1,87 +0,0 @@
/* Native-dependent definitions for NetBSD.
Copyright 1994, 1996, 1999 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#define PTRACE_ARG3_TYPE char*
#define FETCH_INFERIOR_REGISTERS
#define ATTACH_DETACH
#include "solib.h" /* Support for shared libraries. */
#if defined (SVR4_SHARED_LIBS)
#include "elf/common.h" /* Additional ELF shared library info. */
#endif
#if !defined (SVR4_SHARED_LIBS)
/* make structure definitions match up with those expected in solib.c */
#define link_object sod
#define lo_name sod_name
#define lo_library sod_library
#define lo_unused sod_reserved
#define lo_major sod_major
#define lo_minor sod_minor
#define lo_next sod_next
#define link_map so_map
#define lm_addr som_addr
#define lm_name som_path
#define lm_next som_next
#define lm_lop som_sod
#define lm_lob som_sodbase
#define lm_rwt som_write
#define lm_ld som_dynamic
#define lm_lpd som_spd
#define link_dynamic_2 section_dispatch_table
#define ld_loaded sdt_loaded
#define ld_need sdt_sods
#define ld_rules sdt_filler1
#define ld_got sdt_got
#define ld_plt sdt_plt
#define ld_rel sdt_rel
#define ld_hash sdt_hash
#define ld_stab sdt_nzlist
#define ld_stab_hash sdt_filler2
#define ld_buckets sdt_buckets
#define ld_symbols sdt_strings
#define ld_symb_size sdt_str_sz
#define ld_text sdt_text_sz
#define ld_plt_sz sdt_plt_sz
#define rtc_symb rt_symbol
#define rtc_sp rt_sp
#define rtc_next rt_next
#define ld_debug so_debug
#define ldd_version dd_version
#define ldd_in_debugger dd_in_debugger
#define ldd_sym_loaded dd_sym_loaded
#define ldd_bp_addr dd_bpt_addr
#define ldd_bp_inst dd_bpt_shadow
#define ldd_cp dd_cc
#define link_dynamic _dynamic
#define ld_version d_version
#define ldd d_debug
#define ld_un d_un
#define ld_2 d_sdt
#endif

View File

@ -1,34 +0,0 @@
/* Definitions for running gdb on a host machine running any flavor of SVR4.
Copyright 1991, 1992, 1993, 1998 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Use SVR4 style shared library support */
#define SVR4_SHARED_LIBS
#include "solib.h"
/* SVR4 has /proc support, so use it instead of ptrace. */
#define USE_PROC_FS
/* SVR4 machines can easily do attach and detach via /proc (procfs.c)
support */
#define ATTACH_DETACH

View File

@ -1,35 +0,0 @@
/* Macro definitions for LynxOS targets.
Copyright 1993, 1995 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef TM_LYNX_H
#define TM_LYNX_H
/* Override number of expected traps from sysv. */
#define START_INFERIOR_TRAPS_EXPECTED 2
#include "coff-solib.h" /* COFF shared library support */
/* Lynx's signal.h doesn't seem to have any macros for what signal numbers
the real-time events are. */
#define REALTIME_LO 33
/* One more than the last one. */
#define REALTIME_HI 64
#endif /* TM_LYNX_H */

View File

@ -1,29 +0,0 @@
/* Target machine sub-description for NetBSD.
This is included by other tm-*.h files to specify NetBSD-specific stuff.
Copyright 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef SVR4_SHARED_LIBS
/* Return non-zero if we are in a shared library trampoline code stub. */
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
(name && !strcmp(name, "_DYNAMIC"))
#endif /* !SVR4_SHARED_LIBS */

View File

@ -1,32 +0,0 @@
/* Target machine sub-description for SunOS version 4.
This is included by other tm-*.h files to specify SunOS-specific stuff.
Copyright 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "solib.h" /* Support for shared libraries. */
/* Return non-zero if we are in a shared library trampoline code stub. */
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
lookup_solib_trampoline_symbol_by_pc (pc)
/* If PC is in a shared library trampoline code, return the PC
where the function itself actually starts. If not, return 0. */
#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)

View File

@ -1,47 +0,0 @@
/* Macro definitions for GDB on all SVR4 target systems.
Copyright 1991, 1992, 1993, 1994, 1996, 1997, 2000
Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* For SVR4 shared libraries, each call to a library routine goes through
a small piece of trampoline code in the ".plt" section.
The horribly ugly wait_for_inferior() routine uses this macro to detect
when we have stepped into one of these fragments.
We do not use lookup_solib_trampoline_symbol_by_pc, because
we cannot always find the shared library trampoline symbols
(e.g. on Irix5). */
#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) in_plt_section((pc), (name))
extern int in_plt_section (CORE_ADDR, char *);
/* If PC is in a shared library trampoline code, return the PC
where the function itself actually starts. If not, return 0. */
#define SKIP_TRAMPOLINE_CODE(pc) find_solib_trampoline_target (pc)
/* It is unknown which, if any, SVR4 assemblers do not accept dollar signs
in identifiers. The default in G++ is to use dots instead, for all SVR4
systems, so we make that our default also. FIXME: There should be some
way to get G++ to tell us what CPLUS_MARKER it is using, perhaps by
stashing it in the debugging information as part of the name of an
invented symbol ("gcc_cplus_marker$" for example). */
#undef CPLUS_MARKER
#define CPLUS_MARKER '.'

View File

@ -1,91 +0,0 @@
/* Parameters for hosting on an PowerPC, for GDB, the GNU debugger.
Copyright 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Contributed by Cygnus Corporation.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* The following text is taken from config/rs6000.mh:
* # The IBM version of /usr/include/rpc/rpc.h has a bug -- it says
* # `extern fd_set svc_fdset;' without ever defining the type fd_set.
* # Unfortunately this occurs in the vx-share code, which is not configured
* # like the rest of GDB (e.g. it doesn't include "defs.h").
* # We circumvent this bug by #define-ing fd_set here, but undefining it in
* # the xm-rs6000.h file before ordinary modules try to use it. FIXME, IBM!
* MH_CFLAGS='-Dfd_set=int'
* So, here we do the undefine...which has to occur before we include
* <sys/select.h> below.
*/
#undef fd_set
#include <sys/select.h>
/* At least as of AIX 3.2, we have termios. */
#define HAVE_TERMIOS 1
/* #define HAVE_TERMIO 1 */
#define USG 1
#define FIVE_ARG_PTRACE
/* This system requires that we open a terminal with O_NOCTTY for it to
not become our controlling terminal. */
#define USE_O_NOCTTY
/* Brain death inherited from PC's pervades. */
#undef NULL
#define NULL 0
/* The IBM compiler requires this in order to properly compile alloca(). */
#pragma alloca
/* There is no vfork. */
#define vfork fork
char *termdef ();
/* Signal handler for SIGWINCH `window size changed'. */
#define SIGWINCH_HANDLER aix_resizewindow
extern void aix_resizewindow (int);
/* `lines_per_page' and `chars_per_line' are local to utils.c. Rectify this. */
#define SIGWINCH_HANDLER_BODY \
\
/* Respond to SIGWINCH `window size changed' signal, and reset GDB's \
window settings appropriately. */ \
\
void \
aix_resizewindow (signo) \
int signo; \
{ \
int fd = fileno (stdout); \
if (isatty (fd)) { \
int val; \
\
val = atoi (termdef (fd, 'l')); \
if (val > 0) \
lines_per_page = val; \
val = atoi (termdef (fd, 'c')); \
if (val > 0) \
chars_per_line = val; \
} \
}

View File

@ -1,22 +0,0 @@
/* Host-dependent definitions for any CPU running LynxOS.
Copyright 1993 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* for INT_MIN, to avoid "INT_MIN redefined" warnings from defs.h */
#include <limits.h>

View File

@ -1,81 +0,0 @@
/* Macro definitions for running GDB on Apple Macintoshes.
Copyright (C) 1994, 1995 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "mpw.h"
#include "fopen-bin.h"
#include "spin.h"
#define CANT_FORK
/* Map these standard functions to versions that can do I/O in a console
window. */
#define printf hacked_printf
#define fprintf hacked_fprintf
#define vprintf hacked_vfprintf
#define fputs hacked_fputs
#define fputc hacked_fputc
#undef putc
#define putc hacked_putc
#define fflush hacked_fflush
#define fgetc hacked_fgetc
#define POSIX_UTIME
/* No declaration of strdup in MPW's string.h, oddly enough. */
char *strdup (char *s1);
/* '.' indicates drivers on the Mac, so we need a different filename. */
#define GDBINIT_FILENAME "_gdbinit"
/* Commas are more common to separate dirnames in a path on Macs. */
#define DIRNAME_SEPARATOR ','
/* This is a real crufty hack. */
#define HAVE_TERMIO
/* Addons to the basic MPW-supported signal list. */
#ifndef SIGQUIT
#define SIGQUIT (1<<6)
#endif
#ifndef SIGHUP
#define SIGHUP (1<<7)
#endif
/* If __STDC__ is on, then this definition will be missing. */
#ifndef fileno
#define fileno(p) (p)->_file
#endif
#ifndef R_OK
#define R_OK 4
#endif
extern int StandAlone;
extern int mac_app;

View File

@ -1,26 +0,0 @@
/* Host-dependent definitions for any CPU running NetBSD.
Copyright 1993, 1994, 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Include this to get things like NGROUPS which <limits.h> doesn't
define on some systems. */
#include <sys/param.h>
/* NetBSD has termios facilities. */
#define HAVE_TERMIOS

View File

@ -1,29 +0,0 @@
/* Definitions for running gdb on a host machine running any flavor of SVR4.
Copyright 1991, 1992, 1993, 1995, 1998 Free Software Foundation, Inc.
Written by Fred Fish at Cygnus Support (fnf@cygnus.com).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* SVR4 has termios facilities. */
#undef HAVE_TERMIO
#define HAVE_TERMIOS
/* SVR4 is a derivative of System V Release 3 (USG) */
#define USG

View File

@ -1,165 +0,0 @@
/* Remote debugging interface for CPU32Bug Rom monitor for GDB, the GNU debugger.
Copyright 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Written by Stu Grossman of Cygnus Support
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "regcache.h"
static void cpu32bug_open (char *args, int from_tty);
static void
cpu32bug_supply_register (char *regname, int regnamelen, char *val, int vallen)
{
int regno;
if (regnamelen != 2)
return;
switch (regname[0])
{
case 'S':
if (regname[1] != 'R')
return;
regno = PS_REGNUM;
break;
case 'P':
if (regname[1] != 'C')
return;
regno = PC_REGNUM;
break;
case 'D':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + D0_REGNUM;
break;
case 'A':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + A0_REGNUM;
break;
default:
return;
}
monitor_supply_register (regno, val);
}
/*
* This array of registers needs to match the indexes used by GDB. The
* whole reason this exists is because the various ROM monitors use
* different names than GDB does, and don't support all the
* registers either. So, typing "info reg sp" becomes an "A7".
*/
static char *cpu32bug_regnames[NUM_REGS] =
{
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
"SR", "PC",
};
/*
* Define the monitor command strings. Since these are passed directly
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
static struct target_ops cpu32bug_ops;
static char *cpu32bug_inits[] =
{"\r", NULL};
static struct monitor_ops cpu32bug_cmds;
static void
init_cpu32bug_cmds (void)
{
cpu32bug_cmds.flags = MO_CLR_BREAK_USES_ADDR;
cpu32bug_cmds.init = cpu32bug_inits; /* Init strings */
cpu32bug_cmds.cont = "g\r"; /* continue command */
cpu32bug_cmds.step = "t\r"; /* single step */
cpu32bug_cmds.stop = NULL; /* interrupt command */
cpu32bug_cmds.set_break = "br %x\r"; /* set a breakpoint */
cpu32bug_cmds.clr_break = "nobr %x\r"; /* clear a breakpoint */
cpu32bug_cmds.clr_all_break = "nobr\r"; /* clear all breakpoints */
cpu32bug_cmds.fill = "bf %x:%x %x;b\r"; /* fill (start count val) */
cpu32bug_cmds.setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */
cpu32bug_cmds.setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */
cpu32bug_cmds.setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */
cpu32bug_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
cpu32bug_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
cpu32bug_cmds.setmem.term = NULL; /* setreg.term */
cpu32bug_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
cpu32bug_cmds.getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */
cpu32bug_cmds.getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */
cpu32bug_cmds.getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */
cpu32bug_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
cpu32bug_cmds.getmem.resp_delim = " "; /* getmem.resp_delim */
cpu32bug_cmds.getmem.term = NULL; /* getmem.term */
cpu32bug_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
cpu32bug_cmds.setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */
cpu32bug_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
cpu32bug_cmds.setreg.term = NULL; /* setreg.term */
cpu32bug_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
cpu32bug_cmds.getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */
cpu32bug_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
cpu32bug_cmds.getreg.term = NULL; /* getreg.term */
cpu32bug_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
cpu32bug_cmds.dump_registers = "rd\r"; /* dump_registers */
cpu32bug_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
cpu32bug_cmds.supply_register = cpu32bug_supply_register; /* supply_register */
cpu32bug_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
cpu32bug_cmds.load = "lo\r"; /* download command */
cpu32bug_cmds.loadresp = "\n"; /* load response */
cpu32bug_cmds.prompt = "CPU32Bug>"; /* monitor command prompt */
cpu32bug_cmds.line_term = "\r"; /* end-of-line terminator */
cpu32bug_cmds.cmd_end = NULL; /* optional command terminator */
cpu32bug_cmds.target = &cpu32bug_ops; /* target operations */
cpu32bug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
cpu32bug_cmds.regnames = cpu32bug_regnames; /* registers names */
cpu32bug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
}; /* init_cpu32bug_cmds */
static void
cpu32bug_open (char *args, int from_tty)
{
monitor_open (args, &cpu32bug_cmds, from_tty);
}
void
_initialize_cpu32bug_rom (void)
{
init_cpu32bug_cmds ();
init_monitor_ops (&cpu32bug_ops);
cpu32bug_ops.to_shortname = "cpu32bug";
cpu32bug_ops.to_longname = "CPU32Bug monitor";
cpu32bug_ops.to_doc = "Debug via the CPU32Bug monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
cpu32bug_ops.to_open = cpu32bug_open;
add_target (&cpu32bug_ops);
}

View File

@ -1,537 +0,0 @@
/* Native support for Motorola 88k running Harris CX/UX.
Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000,
2001 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include "gdbcore.h"
#include <sys/user.h>
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
#include "symtab.h"
#include "regcache.h"
#ifndef USER /* added to support BCS ptrace_user */
#define USER ptrace_user
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/file.h>
#include "gdb_stat.h"
#include "symtab.h"
#include "setjmp.h"
#include "value.h"
#include <sys/ptrace.h>
/* CX/UX provides them already, but as word offsets instead of char offsets */
#define SXIP_OFFSET (PT_SXIP * 4)
#define SNIP_OFFSET (PT_SNIP * 4)
#define SFIP_OFFSET (PT_SFIP * 4)
#define PSR_OFFSET (PT_PSR * sizeof(int))
#define FPSR_OFFSET (PT_FPSR * sizeof(int))
#define FPCR_OFFSET (PT_FPCR * sizeof(int))
#define XREGADDR(r) (((char *)&u.pt_x0-(char *)&u) + \
((r)-X0_REGNUM)*sizeof(X_REGISTER_RAW_TYPE))
extern int have_symbol_file_p ();
extern jmp_buf stack_jmp;
extern int errno;
void
fetch_inferior_registers (int regno)
{
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
struct USER u;
unsigned int offset;
offset = (char *) &u.pt_r0 - (char *) &u;
regaddr = offset; /* byte offset to r0; */
/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
for (regno = 0; regno < PC_REGNUM; regno++)
{
/*regaddr = register_addr (regno, offset); */
/* 88k enhancement */
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
*(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (int);
}
supply_register (regno, buf);
}
/* now load up registers 32-37; special pc registers */
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) PSR_OFFSET, 0);
supply_register (PSR_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPSR_OFFSET, 0);
supply_register (FPSR_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPCR_OFFSET, 0);
supply_register (FPCR_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, 0);
supply_register (SXIP_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, 0);
supply_register (SNIP_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, 0);
supply_register (SFIP_REGNUM, buf);
if (target_is_m88110)
{
for (regaddr = XREGADDR (X0_REGNUM), regno = X0_REGNUM;
regno < NUM_REGS;
regno++, regaddr += 16)
{
X_REGISTER_RAW_TYPE xval;
*(int *) &xval.w1 = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, 0);
*(int *) &xval.w2 = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (regaddr + 4), 0);
*(int *) &xval.w3 = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (regaddr + 8), 0);
*(int *) &xval.w4 = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (regaddr + 12), 0);
supply_register (regno, (void *) &xval);
}
}
}
/* 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). */
void
store_inferior_registers (int regno)
{
register unsigned int regaddr;
char buf[80];
struct USER u;
unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
regaddr = offset;
/* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
svr3 doesn't run on an 88110, or the kernel isolates the different (not
completely sure this is true, but seems to be. */
if (regno >= 0)
{
/* regaddr = register_addr (regno, offset); */
if (regno < PC_REGNUM)
{
regaddr = offset + regno * sizeof (int);
errno = 0;
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, read_register (regno));
if (errno != 0)
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
}
}
else if (regno == PSR_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno));
else if (regno == FPSR_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno));
else if (regno == FPCR_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno));
else if (regno == SXIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno));
else if (regno == SNIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno));
else if (regno == SFIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno));
else if (target_is_m88110 && regno < NUM_REGS)
{
X_REGISTER_RAW_TYPE xval;
read_register_bytes (REGISTER_BYTE (regno), (char *) &xval,
sizeof (X_REGISTER_RAW_TYPE));
regaddr = XREGADDR (regno);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 4, xval.w2);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 8, xval.w3);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr + 12, xval.w4);
}
else
printf_unfiltered ("Bad register number for store_inferior routine\n");
}
else
{
for (regno = 0; regno < PC_REGNUM; regno++)
{
/* regaddr = register_addr (regno, offset); */
errno = 0;
regaddr = offset + regno * sizeof (int);
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, read_register (regno));
if (errno != 0)
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
}
}
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) PSR_OFFSET, read_register (regno));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPSR_OFFSET, read_register (regno));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) FPCR_OFFSET, read_register (regno));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM));
if (target_is_m88110)
{
for (regno = X0_REGNUM; regno < NUM_REGS; regno++)
{
X_REGISTER_RAW_TYPE xval;
read_register_bytes (REGISTER_BYTE (regno), (char *) &xval,
sizeof (X_REGISTER_RAW_TYPE));
regaddr = XREGADDR (regno);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, xval.w1);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 4), xval.w2);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 8), xval.w3);
ptrace (6, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (regaddr + 12), xval.w4);
}
}
}
}
/* blockend is the address of the end of the user structure */
m88k_register_u_addr (int blockend, int regnum)
{
struct USER u;
int ustart = blockend - sizeof (struct USER);
if (regnum < PSR_REGNUM)
return (ustart + ((int) &u.pt_r0 - (int) &u) +
REGISTER_SIZE * regnum);
else if (regnum == PSR_REGNUM)
return (ustart + ((int) &u.pt_psr) - (int) &u);
else if (regnum == FPSR_REGNUM)
return (ustart + ((int) &u.pt_fpsr) - (int) &u);
else if (regnum == FPCR_REGNUM)
return (ustart + ((int) &u.pt_fpcr) - (int) &u);
else if (regnum == SXIP_REGNUM)
return (ustart + SXIP_OFFSET);
else if (regnum == SNIP_REGNUM)
return (ustart + SNIP_OFFSET);
else if (regnum == SFIP_REGNUM)
return (ustart + SFIP_OFFSET);
else if (target_is_m88110)
return (ustart + ((int) &u.pt_x0 - (int) &u) + /* Must be X register */
sizeof (u.pt_x0) * (regnum - X0_REGNUM));
else
return (blockend + REGISTER_SIZE * regnum);
}
#ifdef USE_PROC_FS
#include <sys/procfs.h>
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* Given a pointer to a general register set in /proc format (gregset_t *),
unpack the register contents and supply them as gdb's idea of the current
register values. */
void
supply_gregset (gregset_t *gregsetp)
{
register int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi <= SP_REGNUM; regi++)
supply_register (regi, (char *) (regp + regi));
supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
}
void
fill_gregset (gregset_t *gregsetp, int regno)
{
int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi <= R_R31; regi++)
if ((regno == -1) || (regno == regi))
*(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
if ((regno == -1) || (regno == SXIP_REGNUM))
*(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE (SXIP_REGNUM)];
if ((regno == -1) || (regno == SNIP_REGNUM))
*(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE (SNIP_REGNUM)];
if ((regno == -1) || (regno == SFIP_REGNUM))
*(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE (SFIP_REGNUM)];
if ((regno == -1) || (regno == PSR_REGNUM))
*(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE (PSR_REGNUM)];
if ((regno == -1) || (regno == FPSR_REGNUM))
*(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE (FPSR_REGNUM)];
if ((regno == -1) || (regno == FPCR_REGNUM))
*(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE (FPCR_REGNUM)];
}
#endif /* USE_PROC_FS */
/* This support adds the equivalent of adb's % command. When
the `add-shared-symbol-files' command is given, this routine scans
the dynamic linker's link map and reads the minimal symbols
from each shared object file listed in the map. */
struct link_map
{
unsigned long l_addr; /* address at which object is mapped */
char *l_name; /* full name of loaded object */
void *l_ld; /* dynamic structure of object */
struct link_map *l_next; /* next link object */
struct link_map *l_prev; /* previous link object */
};
#define LINKS_MAP_POINTER "_ld_tail"
#define LIBC_FILE "/usr/lib/libc.so.1"
#define SHARED_OFFSET 0xf0001000
#ifndef PATH_MAX
#define PATH_MAX 1023 /* maximum size of path name on OS */
#endif
void
add_shared_symbol_files (void)
{
void *desc;
struct link_map *ld_map, *lm, lms;
struct minimal_symbol *minsym;
struct objfile *objfile;
char *path_name;
if (ptid_equal (inferior_ptid, null_ptid))
{
warning ("The program has not yet been started.");
return;
}
objfile = symbol_file_add (LIBC_FILE, 0, NULL, 0, OBJF_READNOW);
minsym = lookup_minimal_symbol (LINKS_MAP_POINTER, objfile);
ld_map = (struct link_map *)
read_memory_integer (((int) SYMBOL_VALUE_ADDRESS (minsym) + SHARED_OFFSET), 4);
lm = ld_map;
while (lm)
{
int local_errno = 0;
read_memory ((CORE_ADDR) lm, (char *) &lms, sizeof (struct link_map));
if (lms.l_name)
{
if (target_read_string ((CORE_ADDR) lms.l_name, &path_name,
PATH_MAX, &local_errno))
{
struct section_addr_info section_addrs;
memset (&section_addrs, 0, sizeof (section_addrs));
section_addrs.other[0].addr = lms.l_addr;
section_addrs.other[0].name = ".text";
symbol_file_add (path_name, 1, &section_addrs, 0, 0);
xfree (path_name);
}
}
/* traverse links in reverse order so that we get the
the symbols the user actually gets. */
lm = lms.l_prev;
}
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
}
#if defined(_ES_MP)
#include <sys/regset.h>
unsigned int
m88k_harris_core_register_addr (int regno, int reg_ptr)
{
unsigned int word_offset;
switch (regno)
{
case PSR_REGNUM:
word_offset = R_EPSR;
break;
case FPSR_REGNUM:
word_offset = R_FPSR;
break;
case FPCR_REGNUM:
word_offset = R_FPCR;
break;
case SXIP_REGNUM:
word_offset = R_EXIP;
break;
case SNIP_REGNUM:
word_offset = R_ENIP;
break;
case SFIP_REGNUM:
word_offset = R_EFIP;
break;
default:
if (regno <= FP_REGNUM)
word_offset = regno;
else
word_offset = ((regno - X0_REGNUM) * 4);
}
return (word_offset * 4);
}
#endif /* _ES_MP */
void
_initialize_m88k_nat (void)
{
#ifdef _ES_MP
/* Enable 88110 support, as we don't support the 88100 under ES/MP. */
target_is_m88110 = 1;
#elif defined(_CX_UX)
/* Determine whether we're running on an 88100 or an 88110. */
target_is_m88110 = (sinfo (SYSMACHINE, 0) == SYS5800);
#endif /* _CX_UX */
}
#ifdef _ES_MP
/* Given a pointer to a general register set in /proc format (gregset_t *),
unpack the register contents and supply them as gdb's idea of the current
register values. */
void
supply_gregset (gregset_t *gregsetp)
{
register int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi < R_R31; regi++)
{
supply_register (regi, (char *) (regp + regi));
}
supply_register (PSR_REGNUM, (char *) (regp + R_EPSR));
supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
supply_register (SXIP_REGNUM, (char *) (regp + R_EXIP));
supply_register (SNIP_REGNUM, (char *) (regp + R_ENIP));
supply_register (SFIP_REGNUM, (char *) (regp + R_EFIP));
}
/* Given a pointer to a floating point register set in /proc format
(fpregset_t *), unpack the register contents and supply them as gdb's
idea of the current floating point register values. */
void
supply_fpregset (fpregset_t *fpregsetp)
{
register int regi;
char *from;
for (regi = FP0_REGNUM; regi <= FPLAST_REGNUM; regi++)
{
from = (char *) &((*fpregsetp)[regi - FP0_REGNUM]);
supply_register (regi, from);
}
}
#endif /* _ES_MP */
#ifdef _CX_UX
#include <sys/regset.h>
unsigned int
m88k_harris_core_register_addr (int regno, int reg_ptr)
{
unsigned int word_offset;
switch (regno)
{
case PSR_REGNUM:
word_offset = R_PSR;
break;
case FPSR_REGNUM:
word_offset = R_FPSR;
break;
case FPCR_REGNUM:
word_offset = R_FPCR;
break;
case SXIP_REGNUM:
word_offset = R_XIP;
break;
case SNIP_REGNUM:
word_offset = R_NIP;
break;
case SFIP_REGNUM:
word_offset = R_FIP;
break;
default:
if (regno <= FP_REGNUM)
word_offset = regno;
else
word_offset = ((regno - X0_REGNUM) * 4) + R_X0;
}
return (word_offset * 4);
}
#endif /* _CX_UX */

View File

@ -1,114 +0,0 @@
@c GDB MANUAL configuration file.
@c Copyright (c) 1993 Free Software Foundation, Inc.
@c
@c NOTE: While the GDB manual is configurable (by changing these
@c switches), its configuration is ***NOT*** automatically tied in to
@c source configuration---because the authors expect that, save in
@c unusual cases, the most inclusive form of the manual is appropriate
@c no matter how the program itself is configured.
@c
@c The only automatically-varying variable is the GDB version number,
@c which the Makefile rewrites based on the VERSION variable from
@c `../Makefile.in'.
@c
@c GDB version number is recorded in the variable GDBVN
@include GDBvn.texi
@c
@c ----------------------------------------------------------------------
@c PLATFORM FLAGS:
@clear GENERIC
@c
@c HP PA-RISC target:
@set HPPA
@c
@c Hitachi H8/300 target:
@clear H8
@c Hitachi H8/300 target ONLY:
@clear H8EXCLUSIVE
@c
@c remote MIPS target:
@clear MIPS
@c
@c SPARC target:
@clear SPARC
@c
@c AMD 29000 target:
@clear AMD29K
@c
@c Intel 960 target:
@clear I960
@c
@c Tandem ST2000 (phone switch) target:
@clear ST2000
@c
@c Zilog 8000 target:
@clear Z8K
@c
@c Wind River Systems VxWorks environment:
@clear VXWORKS
@c
@c ----------------------------------------------------------------------
@c DOC FEATURE FLAGS:
@c
@c Bare-board target?
@clear BARETARGET
@c
@c Restrict languages discussed to C?
@c This is backward. As time permits, change this to language-specific
@c switches for what to include.
@clear CONLY
@c Discuss Fortran?
@clear FORTRAN
@c
@c Discuss Modula 2?
@clear MOD2
@c
@c Specifically for host machine running DOS?
@clear DOSHOST
@c
@c Talk about CPU simulator targets?
@clear SIMS
@c
@c Remote serial line settings of interest?
@set SERIAL
@c
@c Discuss features requiring Posix or similar OS environment?
@set POSIX
@c
@c Discuss remote serial debugging stub?
@clear REMOTESTUB
@c
@c Discuss gdbserver?
@set GDBSERVER
@c
@c Discuss gdbserve.nlm?
@set GDBSERVE
@c
@c Refrain from discussing how to configure sw and format doc?
@clear PRECONFIGURED
@c
@c Refrain from referring to unfree publications?
@set FSFDOC
@c
@c ----------------------------------------------------------------------
@c STRINGS:
@c
@c Name of GDB program. Used also for (gdb) prompt string.
@set GDBP gdb
@c
@c Name of GDB product. Used in running text.
@set GDBN GDB
@c
@c Name of target.
@set TARGET HP 9000 Systems
@c
@c Name of host. Should not be used in generic configs, but generic
@c value may catch some flubs.
@set HOST machine specific
@c
@c Name of GCC product
@set NGCC GCC
@c
@c Name of GCC program
@set GCC gcc

View File

@ -1,47 +0,0 @@
@c GDB version number is recorded in the variable GDBVN
@include GDBvn.texi
@c
@set AGGLOMERATION
@clear AMD29K
@set BARETARGET
@clear CONLY
@set DOSHOST
@clear FORTRAN
@clear FSFDOC
@clear GDBSERVER
@clear GENERIC
@set H8
@set H8EXCLUSIVE
@clear HAVE-FLOAT
@clear I960
@clear MOD2
@clear NOVEL
@clear POSIX
@set PRECONFIGURED
@clear REMOTESTUB
@set SIMS
@clear SERIAL
@clear SPARC
@clear ST2000
@clear VXWORKS
@clear Z8K
@c ----------------------------------------------------------------------
@c STRINGS:
@c
@c Name of GDB program. Used also for (gdb) prompt string.
@set GDBP gdb
@c
@c Name of GDB product. Used in running text.
@set GDBN GDB
@c
@c Name of GDB initialization file.
@set GDBINIT .gdbinit
@c
@c Name of target.
@set TARGET Hitachi Microprocessors
@c
@c Name of GCC product
@set NGCC GCC
@c
@c Name of GCC program
@set GCC gcc

View File

@ -1,878 +0,0 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
@setfilename libgdb.info
@settitle Libgdb
@setchapternewpage off
@c %**end of header
@ifinfo
This file documents libgdb, the GNU symbolic debugger in a library.
This is Edition 0.3, Oct 1993, of @cite{Libgdb}.
Copyright 1993 Cygnus Support
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions.
@end ifinfo
@c This title page illustrates only one of the
@c two methods of forming a title page.
@titlepage
@title Libgdb
@subtitle Version 0.3
@subtitle Oct 1993
@author Thomas Lord
@c The following two commands
@c start the copyright page.
@page
@vskip 0pt plus 1filll
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.
Copyright @copyright{} 1993 Cygnus Support
@end titlepage
@ifinfo
@node Top, Overview, (dir), (dir)
This info file documents libgdb: an API for GDB, the GNU symbolic debugger.
@menu
* Overview:: The basics of libgdb and this document.
* Interpreter:: Libgdb is an Interpreter-Based Server.
* Top Level:: You Provide the Top Level for the Libgdb
Command Interpreter .
* I/O:: How the Server's I/O Can be Used.
* Invoking:: Invoking the Interpreter, Executing
Commands.
* Defining Commands:: How New Commands are Created.
* Variables:: How Builtin Variables are Defined.
* Asynchronous:: Scheduling Asynchronous Computations.
* Commands:: Debugger Commands for Libgdb Applications
@end menu
@end ifinfo
@node Overview, Interpreter, top, top
@comment node-name, next, previous, up
@chapter Overview
@cindex overview
@cindex definitions
@heading Function and Purpose
Libgdb is a package which provides an API to the functionality of GDB,
the GNU symbolic debugger. It is specifically intended to support the
development of a symbolic debugger with a graphic interface.
@heading This Document
This document is a specification of the libgdb API. It is written in
the form of a programmer's manual. So the goal of this document is to
explain what functions make up the API, and how they can be used in a
running application.
@heading Terminology
In this document, @dfn{libgdb} refers to a library containing the
functions defined herein, @dfn{application} refers to any program built
with that library.
@heading Dependencies
Programs which are linked with libgdb must be linked with libbfd,
libopcodes, libiberty, and libmmalloc.
@heading Acknowledgments
Essential contributions to this design were made by Stu Grossman, Jim
Kingdon, and Rich Pixley.
@node Interpreter, Top Level, Overview, Top
@comment node-name, next, previous, up
@chapter Libgdb is an Interpreter Based Server
@cindex interpreter
@cindex server
To understand libgdb, it is necessary to understand how the library is
structured. Historically, GDB is written as a small interpreter for a
simple command language. The commands of the language perform useful
debugging functions.
Libgdb is built from GDB by turning the interpreter into a debugging
server. The server reads debugging commands from any source and
interprets them, directing the output arbitrarily.
In addition to changing GDB from a tty-based program to a server, a
number of new GDB commands have been added to make the server more
useful for a program with a graphic interface.
Finally, libgdb includes provisions for asynchronous processing within
the application.
Most operations that can be carried out with libgdb involve the GDB
command interpreter. The usual mode of operation is that the operation
is expressed as a string of GDB commands, which the interpreter is then
invoked to carry out. The output from commands executed in this manner
can be redirected in a variety of useful ways for further processing by
the application.
The command interpreter provides an extensive system of hooks so an
application can monitor any aspect of the debugging library's state. An
application can set its own breakpoints and attach commands and
conditions to those. It is possible to attach hooks to any debugger
command; the hooks are invoked whenever that command is about to be
invoked. By means of these, the displays of a graphical interface can
be kept fully up to date at all times.
We show you how to define new primitives in the command language. By
defining new primitives and using them in breakpoint scripts and command
hooks, an application can schedule the execution of arbitrary C-code at
almost any point of interest in the operation of libgdb.
We show you how to define new GDB convenience variables for which your
code computes a value on demand. Referring to such variables in a
breakpoint condition is a convenient way to conditionalize breakpoints
in novel ways.
To summarize: in libgdb, the gdb command language is turned into a
debugging server. The server takes commands as input, and the server's
output is redirectable. An application uses libgdb by formatting
debugging commands and invoking the interpreter. The application might
maintain breakpoints, watchpoints and many kinds of hooks. An application
can define new primitives for the interpreter.
@node Top Level, I/O, Interpreter, Top
@chapter You Provide the Top Level for the Libgdb Command Interpreter
@cindex {top level}
When you use libgdb, your code is providing a @dfn{top level} for the
command language interpreter. The top level is significant because it
provides commands for the the interpreter to execute. In addition, the
top level is responsible for handling some kinds of errors, and
performing certain cleanup operations on behalf of the interpreter.
@heading Initialization
Before calling any other libgdb functions, call this:
@deftypefun void gdb_init (void)
Perform one-time initialization for libgdb.
@end deftypefun
An application may wish to evaluate specific gdb commands as part of its
own initialization. The details of how this can be accomplished are
explained below.
@heading The Top-Level Loop
There is a strong presumption in libgdb that the application has
the form of a loop. Here is what such a loop might look like:
@example
while (gdb_still_going ())
@{
if (!GDB_TOP_LEVEL ())
@{
char * command;
gdb_start_top_loop ();
command = process_events ();
gdb_execute_command (command);
gdb_finish_top_loop ();
@}
@}
@end example
The function @code{gdb_still_going} returns 1 until the gdb command
`quit' is run.
The macro @code{GDB_TOP_LEVEL} invokes setjmp to set the top level error
handler. When a command results in an error, the interpreter exits with
a longjmp. There is nothing special libgdb requires of the top level
error handler other than it be present and that it restart the top level
loop. Errors are explained in detail in a later chapter.
Each time through the top level loop two important things happen: a
debugger command is constructed on the basis of user input, and the
interpreter is invoked to execute that command. In the sample code, the
call to the imaginary function @code{process_events} represents the
point at which a graphical interface should read input events until
ready to execute a debugger command. The call to
@code{gdb_execute_command} invokes the command interpreter (what happens
to the output from the command will be explained later).
Libgdb manages some resources using the top-level loop. The primary
reason for this is error-handling: even if a command terminates with an
error, it may already have allocated resources which need to be freed.
The freeing of such resources takes place at the top-level, regardless
of how the the command exits. The calls to @code{gdb_start_top_loop}
and @code{gdb_finish_top_loop} let libgdb know when it is safe to
perform operations associated with these resources.
@heading Breakpoint Commands
Breakpoint commands are scripts of GDB operations associated with
particular breakpoints. When a breakpoint is reached, its associated
commands are executed.
Breakpoint commands are invoked by the libgdb function
@code{gdb_finish_top_loop}.
Notice that if control returns to the top-level error handler, the
execution of breakpoint commands is bypassed. This can happen as a
result of errors during either @code{gdb_execute_command} or
@code{gdb_finish_top_loop}.
@heading Application Initialization
Sometimes it is inconvenient to execute commands via a command loop for
example, the commands an application uses to initialize itself. An
alternative to @code{execute_command} is @code{execute_catching_errors}.
When @code{execute_catching_errors} is used, no top level error handler
need be in effect, and it is not necessary to call
@code{gdb_start_top_loop} or @code{gdb_finish_top_loop}.
@heading Cleanup
The debugger command ``quit'' performs all necessary cleanup for libgdb.
After it has done so, it changes the return value of
@code{gdb_still_going} to 0 and returns to the top level error handler.
@node I/O, Invoking, Top Level, Top
@comment node-name, next, previous, up
@chapter How the Server's I/O Can be Used
@cindex I/O
In the last chapter it was pointed out that a libgdb application is
responsible for providing commands for the interpreter to execute.
However some commands require further input (for example, the ``quit''
command might ask for confirmation). Almost all commands produce output
of some kind. The purpose of this section is to explain how libgdb
performs its I/O, and how an application can take advantage of
this.
@heading I/O Vectors
Libgdb has no fixed strategy for I/O. Instead, all operations are
performed by functions called via structures of function pointers.
Applications supply theses structures and can change them at any
time.
@deftp Type {struct gdb_input_vector}
@deftpx Type {struct gdb_output_vector}
These structures contain a set of function pointers. Each function
determines how a particular type of i/o is performed. The details of
these strucutres are explained below.
The application allocates these structures, initializes them to all bits
zero, fills in the function pointers, and then registers names for them
them with libgdb.
@end deftp
@deftypefun void gdb_name_input_vector (@var{name}, @var{vec})
@deftypefunx void gdb_remove_input_vector (@var{name}, @var{vec})
@deftypefunx void gdb_name_output_vector (@var{name}, @var{vec})
@deftypefunx void gdb_remove_input_vector (@var{name}, @var{vec})
@example
char * @var{name};
struct gdb_output_vector * @var{vec};
@end example
These functions are used to give and remove names to i/o vectors. Note
that if a name is used twice, the most recent definition applies.
@end deftypefun
@subheading Output
An output vector is a structure with at least these fields:
@example
struct gdb_output_vector
@{
/* output */
void (*put_string) (struct gdb_output_vector *, char * str);
@}
@end example
Use the function @code{memset} or something equivalent to initialize an
output vector to all bits zero. Then fill in the function pointer with
your function.
A debugger command can produce three kinds of output: error messages
(such as when trying to delete a non-existent breakpoint), informational
messages (such as the notification printed when a breakpoint is hit),
and the output specifically requested by a command (for example, the
value printed by the ``print'' command). At any given time, then,
libgdb has three output vectors. These are called the @dfn{error},
@dfn{info}, @dfn{value} vector respectively.
@subheading Input
@example
struct gdb_input_vector
@{
int (*query) (struct gdb_input_vector *,
char * prompt,
int quit_allowed);
int * (*selection) (struct gdb_input_vector *,
char * prompt,
char ** choices);
char * (*read_string) (struct gdb_input_vector *,
char * prompt);
char ** (*read_strings) (struct gdb_input_vector *,
char * prompt);
@}
@end example
Use the function @code{memset} or something equivalent to initialize an
input vector to all bits zero. Then fill in the function pointers with
your functions.
There are four kinds of input requests explicitly made by libgdb.
A @dfn{query} is a yes or no question. The user can respond to a query
with an affirmative or negative answer, or by telling gdb to abort the
command (in some cases an abort is not permitted). Query should return
'y' or 'n' or 0 to abort.
A @dfn{selection} is a list of options from which the user selects a subset.
Selections should return a NULL terminated array of integers, which are
indexes into the array of choices. It can return NULL instead to abort
the command. The array returned by this function will be passed to
@code{free} by libgdb.
A @dfn{read_string} asks the user to supply an arbitrary string. It may
return NULL to abort the command. The string returned by @code{read_string}
should be allocated by @code{malloc}; it will be freed by libgdb.
A @dfn{read_strings} asks the user to supply multiple lines of input
(for example, the body of a command created using `define'). It, too,
may return NULL to abort. The array and the strings returned by this
function will be freed by libgdb.
@heading I/O Redirection from the Application Top-Level
@deftypefun struct gdb_io_vecs gdb_set_io (struct gdb_io_vecs *)
@example
struct gdb_io_vecs
@{
struct gdb_input_vector * input;
struct gdb_output_vector * error;
struct gdb_output_vector * info;
struct gdb_output_vector * value;
@}
@end example
This establishes a new set of i/o vectors, and returns the old setting.
Any of the pointers in this structure may be NULL, indicating that the
current value should be used.
This function is useful for setting up i/o vectors before any libgdb
commands have been invoked (hence before any input or output has taken
place).
@end deftypefun
It is explained in a later chapter how to redirect output temporarily.
(@xref{Invoking}.)
@heading I/O Redirection in Debugger Commands
A libgdb application creates input and output vectors and assigns them names.
Which input and output vectors are used by libgdb is established by
executing these debugger commands:
@defun {set input-vector} name
@defunx {set error-output-vector} name
@defunx {set info-output-vector} name
@defunx {set value-output-vector} name
Choose an I/O vector by name.
@end defun
A few debugger commands are for use only within commands defined using
the debugger command `define' (they have no effect at other times).
These commands exist so that an application can maintain hooks which
redirect output without affecting the global I/O vectors.
@defun with-input-vector name
@defunx with-error-output-vector name
@defunx with-info-output-vector name
@defunx with-value-output-vector name
Set an I/O vector, but only temporarily. The setting has effect only
within the command definition in which it occurs.
@end defun
@heading Initial Conditions
When libgdb is initialized, a set of default I/O vectors is put in
place. The default vectors are called @code{default-input-vector},
@code{default-output-vector}, &c.
The default query function always returns `y'. Other input functions
always abort. The default output functions discard output silently.
@node Invoking, Defining Commands, I/O, Top
@chapter Invoking the Interpreter, Executing Commands
@cindex {executing commands}
@cindex {invoking the interpreter}
This section introduces the libgdb functions which invoke the command
interpreter.
@deftypefun void gdb_execute_command (@var{command})
@example
char * @var{command};
@end example
Interpret the argument debugger command. An error handler must be set
when this function is called. (@xref{Top Level}.)
@end deftypefun
It is possible to override the current I/O vectors for the duration of a
single command:
@deftypefun void gdb_execute_with_io (@var{command}, @var{vecs})
@example
char * @var{command};
struct gdb_io_vecs * @var{vecs};
struct gdb_io_vecs
@{
struct gdb_input_vector * input;
struct gdb_output_vector * error;
struct gdb_output_vector * info;
struct gdb_output_vector * value;
@}
@end example
Execute @var{command}, temporarily using the i/o vectors in @var{vecs}.
Any of the vectors may be NULL, indicating that the current value should
be used. An error handler must be in place when this function is used.
@end deftypefun
@deftypefun {struct gdb_str_output} gdb_execute_for_strings (@var{cmd})
@example
char * cmd;
@end example
@deftypefunx {struct gdb_str_output} gdb_execute_for_strings2 (@var{cmd}, @var{input})
@example
char * cmd;
struct gdb_input_vector * input;
@end example
@page
@example
struct gdb_str_output
@{
char * error;
char * info;
char * value;
@};
@end example
Execute @var{cmd}, collecting its output as strings. If no error
occurs, all three strings will be present in the structure, the
empty-string rather than NULL standing for no output of a particular
kind.
If the command aborts with an error, then the @code{value} field will be
NULL, though the other two strings will be present.
In all cases, the strings returned are allocated by malloc and should be
freed by the caller.
The first form listed uses the current input vector, but overrides the
current output vector. The second form additionally allows the input
vector to be overridden.
This function does not require that an error handler be installed.
@end deftypefun
@deftypefun void execute_catching_errors (@var{command})
@example
char * @var{command};
@end example
Like @code{execute_command} except that no error handler is required.
@end deftypefun
@deftypefun void execute_with_text (@var{command}, @var{text})
@example
char * @var{command};
char ** @var{text};
@end example
Like @code{execute_catching_errors}, except that the input vector is
overridden. The new input vector handles only calls to @code{query} (by
returning 'y') and calls to @code{read_strings} by returning a copy of
@var{text} and the strings it points to.
This form of execute_command is useful for commands like @code{define},
@code{document}, and @code{commands}.
@end deftypefun
@node Defining Commands, Variables, Invoking, Top
@comment node-name, next, previous, up
@chapter How New Commands are Created
@cindex {commands, defining}
Applications are, of course, free to take advantage of the existing GDB
macro definition capability (the @code{define} and @code{document}
functions).
In addition, an application can add new primitives to the GDB command
language.
@deftypefun void gdb_define_app_command (@var{name}, @var{fn}, @var{doc})
@example
char * @var{name};
gdb_cmd_fn @var{fn};
char * @var{doc};
typedef void (*gdb_cmd_fn) (char * args);
@end example
Create a new command call @var{name}. The new command is in the
@code{application} help class. When invoked, the command-line arguments
to the command are passed as a single string.
Calling this function twice with the same name replaces an earlier
definition, but application commands can not replace builtin commands of
the same name.
The documentation string of the command is set to a copy the string
@var{doc}.
@end deftypefun
@node Variables, Asynchronous, Defining Commands, Top
@comment node-name, next, previous, up
@chapter How Builtin Variables are Defined
@cindex {variables, defining}
Convenience variables provide a way for values maintained by libgdb to
be referenced in expressions (e.g. @code{$bpnum}). Libgdb includes a
means by which the application can define new, integer valued
convenience variables:
@page
@deftypefun void gdb_define_int_var (@var{name}, @var{fn}, @var{fn_arg})
@example
char * @var{name};
int (*@var{fn}) (void *);
void * @var{fn_arg};
@end example
This function defines (or undefines) a convenience variable called @var{name}.
If @var{fn} is NULL, the variable becomes undefined. Otherwise,
@var{fn} is a function which, when passed @var{fn_arg} returns the value
of the newly defined variable.
No libgdb functions should be called by @var{fn}.
@end deftypefun
One use for this function is to create breakpoint conditions computed in
novel ways. This is done by defining a convenience variable and
referring to that variable in a breakpoint condition expression.
@node Asynchronous, Commands, Variables, Top
@chapter Scheduling Asynchronous Computations
@cindex asynchronous
A running libgdb function can take a long time. Libgdb includes a hook
so that an application can run intermittently during long debugger
operations.
@deftypefun void gdb_set_poll_fn (@var{fn}, @var{fn_arg})
@example
void (*@var{fn})(void * fn_arg, int (*gdb_poll)());
void * @var{fn_arg};
@end example
Arrange to call @var{fn} periodically during lengthy debugger operations.
If @var{fn} is NULL, polling is turned off. @var{fn} should take two
arguments: an opaque pointer passed as @var{fn_arg} to
@code{gdb_set_poll_fn}, and a function pointer. The function pointer
passed to @var{fn} is provided by libgdb and points to a function that
returns 0 when the poll function should return. That is, when
@code{(*gdb_poll)()} returns 0, libgdb is ready to continue @var{fn}
should return quickly.
It is possible that @code{(*gdb_poll)()} will return 0 the first time it
is called, so it is reasonable for an application to do minimal processing
before checking whether to return.
No libgdb functions should be called from an application's poll function,
with one exception: @code{gdb_request_quit}.
@end deftypefun
@deftypefun void gdb_request_quit (void)
This function, if called from a poll function, requests that the
currently executing libgdb command be interrupted as soon as possible,
and that control be returned to the top-level via an error.
The quit is not immediate. It will not occur until at least after the
application's poll function returns.
@end deftypefun
@node Commands, Top, Asynchronous, Top
@comment node-name, next, previous, up
@chapter Debugger Commands for Libgdb Applications
The debugger commands available to libgdb applications are the same commands
available interactively via GDB. This section is an overview of the
commands newly created as part of libgdb.
This section is not by any means a complete reference to the GDB command
language. See the GDB manual for such a reference.
@menu
* Command Hooks:: Setting Hooks to Execute With Debugger Commands.
* View Commands:: View Commands Mirror Show Commands
* Breakpoints:: The Application Can Have Its Own Breakpoints
@end menu
@node Command Hooks, View Commands, Commands, Commands
@comment node-name, next, previous, up
@section Setting Hooks to Execute With Debugger Commands.
Debugger commands support hooks. A command hook is executed just before
the interpreter invokes the hooked command.
There are two hooks allowed for every command. By convention, one hook
is for use by users, the other is for use by the application.
A user hook is created for a command XYZZY by using
@code{define-command} to create a command called @code{hook-XYZZY}.
An application hook is created for a command XYZZY by using
@code{define-command} to create a command called @code{apphook-XYZZY}.
Application hooks are useful for interfaces which wish to continuously
monitor certain aspects of debugger state. The application can set a
hook on all commands that might modify the watched state. When the hook
is executed, it can use i/o redirection to notify parts of the
application that previous data may be out of date. After the top-level loop
resumes, the application can recompute any values that may have changed.
(@xref{I/O}.)
@node View Commands, Breakpoints, Command Hooks, Commands
@comment node-name, next, previous, up
@section View Commands Mirror Show Commands
The GDB command language contains many @code{set} and @code{show}
commands. These commands are used to modify or examine parameters to
the debugger.
It is difficult to get the current state of a parameter from the
@code{show} command because @code{show} is very verbose.
@example
(gdb) show check type
Type checking is "auto; currently off".
(gdb) show width
Number of characters gdb thinks are in a line is 80.
@end example
For every @code{show} command, libgdb includes a @code{view} command.
@code{view} is like @code{show} without the verbose commentary:
@example
(gdb) view check type
auto; currently off
(gdb) view width
80
@end example
(The precise format of the ouput from @code{view} is subject to change.
In particular, @code{view} may one-day print values which can be used as
arguments to the corresponding @code{set} command.)
@node Breakpoints, Structured Output, View Commands, Commands
@comment node-name, next, previous, up
@section The Application Can Have Its Own Breakpoints
The GDB breakpoint commands were written with a strong presumption that
all breakpoints are managed by a human user. Therefore, the command
language contains commands like `delete' which affect all breakpoints
without discrimination.
In libgdb, there is added support for breakpoints and watchpoints which
are set by the application and which should not be affected by ordinary,
indiscriminate commands. These are called @dfn{protected} breakpoints.
@deffn {Debugger Command} break-protected ...
@deffnx {Debugger Command} watch-protected ...
These work like @code{break} and @code{watch} except that the resulting
breakpoint is given a negative number. Negative numbered breakpoints do
not appear in the output of @code{info breakpoints} but do in that of
@code{info all-breakpoints}. Negative numbered breakpoints are not
affected by commands which ordinarily affect `all' breakpoints (e.g.
@code{delete} with no arguments).
Note that libgdb itself creates protected breakpoints, so programs
should not rely on being able to allocate particular protected
breakpoint numbers for themselves.
@end deffn
More than one breakpoint may be set at a given location. Libgdb adds
the concept of @dfn{priority} to breakpoints. A priority is an integer,
assigned to each breakpoint. When a breakpoint is reached, the
conditions of all breakpoints at the same location are evaluated in
order of ascending priority. When breakpoint commands are executed,
they are also executed in ascending priority (until all have been
executed, an error occurs, or one set of commands continues the
target).
@deffn {Debugger Command} priority n bplist
Set the priority for breakpoints @var{bplist} to @var{n}.
By default, breakpoints are assigned a priority of zero.
@end deffn
@node Structured Output, Commands, Breakpoints, Commands
@comment node-name, next, previous, up
@section Structured Output, The @code{Explain} Command
(This section may be subject to considerable revision.)
When GDB prints a the value of an expression, the printed representation
contains information that can be usefully fed back into future commands
and expressions. For example,
@example
(gdb) print foo
$16 = @{v = 0x38ae0, v_length = 40@}
@end example
On the basis of this output, a user knows, for example, that
@code{$16.v} refers to a pointer valued @code{0x38ae0}
A new output command helps to make information like this available to
the application.
@deffn {Debugger Command} explain expression
@deffnx {Debugger Command} explain /format expression
Print the value of @var{expression} in the manner of the @code{print}
command, but embed that output in a list syntax containing information
about the structure of the output.
@end deffn
As an example, @code{explain argv} might produce this output:
@example
(exp-attribute
((expression "$19")
(type "char **")
(address "48560")
(deref-expression "*$19"))
"$19 = 0x3800\n")
@end example
The syntax of output from @code{explain} is:
@example
<explanation> := <quoted-string>
| (exp-concat <explanation> <explanation>*)
| (exp-attribute <property-list> <explanation>)
<property-list> := ( <property-pair>* )
<property-pair> := ( <property-name> <quoted-string> )
@end example
The string-concatenation of all of the @code{<quoted-string>} (except
those in property lists) yields the output generated by the equivalent
@code{print} command. Quoted strings may contain quotes and backslashes
if they are escaped by backslash. "\n" in a quoted string stands for
newline; unescaped newlines do not occur within the strings output by
@code{explain}.
Property names are made up of alphabetic characters, dashes, and
underscores.
The set of properties is open-ended. As GDB acquires support for new
source languages and other new capabilities, new property types may be
added to the output of this command. Future commands may offer
applications some selectivity concerning which properties are reported.
The initial set of properties defined includes:
@itemize @bullet
@item @code{expression}
This is an expression, such as @code{$42} or @code{$42.x}. The
expression can be used to refer to the value printed in the attributed
part of the string.
@item @code{type}
This is a user-readable name for the type of the attributed value.
@item @code{address}
If the value is stored in a target register, this is a register number.
If the value is stored in a GDB convenience variable, this is an integer
that is unique among all the convenience variables. Otherwise, this is
the address in the target where the value is stored.
@item @code{deref-expression}
If the attributed value is a pointer type, this is an expression that
refers to the dereferenced value.
@end itemize
Here is a larger example, using the same object passed to @code{print}
in an earlier example of this section.
@example
(gdb) explain foo
(exp-attribute
( (expression "$16")
(type "struct bytecode_vector")
(address 14336) )
(exp-concat
"$16 = @{"
(exp-attribute
( (expression "$16.v")
(type "char *")
(address 14336)
(deref-expression "*$16.v") )
"v = 0x38ae0")
(exp-attribute
( (expression "$16.v_length")
(type "int")
(address 14340) )
", v_length = 40")
"@}\n"))
@end example
It is undefined how libgdb will indent these lines of output or
where newlines will be included.
@bye

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,451 +0,0 @@
/* Low level interface to ptrace, for the remote server for GDB.
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <sys/wait.h>
#include "frame.h"
#include "inferior.h"
#include <stdio.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <signal.h>
#include <sys/ioctl.h>
#if 0
#include <sgtty.h>
#endif
#include <fcntl.h>
/***************Begin MY defs*********************/
int quit_flag = 0;
char registers[REGISTER_BYTES];
/* Index within `registers' of the first byte of the space for
register N. */
char buf2[MAX_REGISTER_RAW_SIZE];
/***************End MY defs*********************/
#include <sys/ptrace.h>
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
#include <sys/reg.h>
#endif
extern char **environ;
extern int errno;
extern int inferior_pid;
void quit (), perror_with_name ();
int query ();
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args.
ENV is the environment vector to pass. */
int
create_inferior (program, allargs)
char *program;
char **allargs;
{
int pid;
pid = fork ();
if (pid < 0)
perror_with_name ("fork");
if (pid == 0)
{
ptrace (PTRACE_TRACEME, 0, 0, 0);
execv (program, allargs);
fprintf (stderr, "Cannot exec %s: %s.\n", program,
errno < sys_nerr ? sys_errlist[errno] : "unknown error");
fflush (stderr);
_exit (0177);
}
return pid;
}
/* Kill the inferior process. Make us have no inferior. */
void
kill_inferior ()
{
if (inferior_pid == 0)
return;
ptrace (PTRACE_KILL, inferior_pid, 0, 0);
wait (0);
/*************inferior_died ();****VK**************/
}
/* Return nonzero if the given thread is still alive. */
int
mythread_alive (pid)
int pid;
{
return 1;
}
/* Wait for process, returns status */
unsigned char
mywait (status)
char *status;
{
int pid;
union wait w;
pid = wait (&w);
if (pid != inferior_pid)
perror_with_name ("wait");
if (WIFEXITED (w))
{
fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
*status = 'W';
return ((unsigned char) WEXITSTATUS (w));
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
*status = 'X';
return ((unsigned char) WTERMSIG (w));
}
fetch_inferior_registers (0);
*status = 'T';
return ((unsigned char) WSTOPSIG (w));
}
/* Resume execution of the inferior process.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
myresume (step, signal)
int step;
int signal;
{
errno = 0;
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
if (errno)
perror_with_name ("ptrace");
}
#if !defined (offsetof)
#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
#endif
/* U_REGS_OFFSET is the offset of the registers within the u area. */
#if !defined (U_REGS_OFFSET)
#define U_REGS_OFFSET \
ptrace (PT_READ_U, inferior_pid, \
(PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \
- KERNEL_U_ADDR
#endif
#ifndef TARGET_M68K
/* this table must line up with REGISTER_NAMES in tm-i386v.h */
/* symbols like 'EAX' come from <sys/reg.h> */
static int regmap[] =
{
EAX, ECX, EDX, EBX,
UESP, EBP, ESI, EDI,
EIP, EFL, CS, SS,
DS, ES, FS, GS,
};
int
i386_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
#if 0
/* this will be needed if fp registers are reinstated */
/* for now, you can look at them with 'info float'
* sys5 wont let you change them with ptrace anyway
*/
if (regnum >= FP0_REGNUM && regnum <= FP7_REGNUM)
{
int ubase, fpstate;
struct user u;
ubase = blockend + 4 * (SS + 1) - KSTKSZ;
fpstate = ubase + ((char *)&u.u_fpstate - (char *)&u);
return (fpstate + 0x1c + 10 * (regnum - FP0_REGNUM));
}
else
#endif
return (blockend + 4 * regmap[regnum]);
}
#else /* TARGET_M68K */
/* This table must line up with REGISTER_NAMES in tm-m68k.h */
static int regmap[] =
{
#ifdef PT_D0
PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
PT_SR, PT_PC,
#else
14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15,
17, 18,
#endif
#ifdef PT_FP0
PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
PT_FPCR, PT_FPSR, PT_FPIAR
#else
21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47
#endif
};
/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
is stored. */
int
m68k_linux_register_u_addr (blockend, regnum)
int blockend;
int regnum;
{
return (blockend + 4 * regmap[regnum]);
}
#endif
CORE_ADDR
register_addr (regno, blockend)
int regno;
CORE_ADDR blockend;
{
CORE_ADDR addr;
if (regno < 0 || regno >= ARCH_NUM_REGS)
error ("Invalid register number %d.", regno);
REGISTER_U_ADDR (addr, blockend, regno);
return addr;
}
/* Fetch one register. */
static void
fetch_register (regno)
int regno;
{
register unsigned int regaddr;
register int i;
/* Offset of registers within the u area. */
unsigned int offset;
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
errno = 0;
*(int *) &registers[ regno * 4 + i] = ptrace (PTRACE_PEEKUSR, inferior_pid,
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (int);
if (errno != 0)
{
/* Warning, not error, in case we are attached; sometimes the
kernel doesn't let us at the registers. */
char *err = strerror (errno);
char *msg = alloca (strlen (err) + 128);
sprintf (msg, "reading register %d: %s", regno, err);
error (msg);
goto error_exit;
}
}
error_exit:;
}
/* Fetch all registers, or just one, from the child process. */
void
fetch_inferior_registers (regno)
int regno;
{
if (regno == -1 || regno == 0)
for (regno = 0; regno < NUM_REGS-NUM_FREGS; regno++)
fetch_register (regno);
else
fetch_register (regno);
}
/* 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). */
void
store_inferior_registers (regno)
int regno;
{
register unsigned int regaddr;
register int i;
unsigned int offset = U_REGS_OFFSET;
if (regno >= 0)
{
#if 0
if (CANNOT_STORE_REGISTER (regno))
return;
#endif
regaddr = register_addr (regno, offset);
errno = 0;
#if 0
if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM)
{
scratch = *(int *) &registers[REGISTER_BYTE (regno)] | 0x3;
ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
scratch, 0);
if (errno != 0)
{
/* Error, even if attached. Failing to write these two
registers is pretty serious. */
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
}
}
else
#endif
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
{
errno = 0;
ptrace (PTRACE_POKEUSR, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
*(int *) &registers[REGISTER_BYTE (regno) + i]);
if (errno != 0)
{
/* Warning, not error, in case we are attached; sometimes the
kernel doesn't let us at the registers. */
char *err = strerror (errno);
char *msg = alloca (strlen (err) + 128);
sprintf (msg, "writing register %d: %s",
regno, err);
error (msg);
return;
}
regaddr += sizeof(int);
}
}
else
for (regno = 0; regno < NUM_REGS-NUM_FREGS; regno++)
store_inferior_registers (regno);
}
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
in the NEW_SUN_PTRACE case.
It ought to be straightforward. But it appears that writing did
not write the data that I specified. I cannot understand where
it got the data that it actually did write. */
/* Copy LEN bytes from inferior's memory starting at MEMADDR
to debugger memory starting at MYADDR. */
void
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));
/* Read all the longwords */
for (i = 0; i < count; i++, addr += sizeof (int))
{
buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
}
/* Copy appropriate bytes out of the buffer. */
memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
}
/* 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. */
buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
if (count > 1)
{
buffer[count - 1]
= ptrace (PTRACE_PEEKTEXT, inferior_pid,
addr + (count - 1) * sizeof (int), 0);
}
/* Copy data to be written over corresponding part of buffer */
memcpy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
/* Write the entire buffer. */
for (i = 0; i < count; i++, addr += sizeof (int))
{
errno = 0;
ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
if (errno)
return errno;
}
return 0;
}
void
initialize ()
{
inferior_pid = 0;
}
int
have_inferior_p ()
{
return inferior_pid != 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,101 +0,0 @@
/* Common things used by the various *gnu-nat.c files
Copyright 1995, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
Written by Miles Bader <miles@gnu.ai.mit.edu>
The GNU Hurd is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2, or (at
your option) any later version.
The GNU Hurd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef __GNU_NAT_H__
#define __GNU_NAT_H__
#include <unistd.h>
#include <mach.h>
struct inf;
extern struct inf *current_inferior;
/* Converts a GDB pid to a struct proc. */
struct proc *inf_tid_to_thread (struct inf *inf, int tid);
/* Makes sure that INF's thread list is synced with the actual process. */
int inf_update_procs (struct inf *inf);
/* A proc is either a thread, or the task (there can only be one task proc
because it always has the same TID, PROC_TID_TASK). */
struct proc
{
thread_t port; /* The task or thread port. */
int tid; /* The GDB pid (actually a thread id). */
int num; /* An id number for threads, to print. */
mach_port_t saved_exc_port; /* The task/thread's real exception port. */
mach_port_t exc_port; /* Our replacement, which for. */
int sc; /* Desired suspend count. */
int cur_sc; /* Implemented suspend count. */
int run_sc; /* Default sc when the program is running. */
int pause_sc; /* Default sc when gdb has control. */
int resume_sc; /* Sc resulting from the last resume. */
int detach_sc; /* SC to leave around when detaching
from program. */
thread_state_data_t state; /* Registers, &c. */
int state_valid:1; /* True if STATE is up to date. */
int state_changed:1;
int aborted:1; /* True if thread_abort has been called. */
int dead:1; /* We happen to know it's actually dead. */
/* Bit mask of registers fetched by gdb. This is used when we re-fetch
STATE after aborting the thread, to detect that gdb may have out-of-date
information. */
unsigned long fetched_regs;
struct inf *inf; /* Where we come from. */
struct proc *next;
};
/* The task has a thread entry with this TID. */
#define PROC_TID_TASK (-1)
#define proc_is_task(proc) ((proc)->tid == PROC_TID_TASK)
#define proc_is_thread(proc) ((proc)->tid != PROC_TID_TASK)
extern int __proc_pid (struct proc *proc);
/* Make sure that the state field in PROC is up to date, and return a
pointer to it, or 0 if something is wrong. If WILL_MODIFY is true,
makes sure that the thread is stopped and aborted first, and sets
the state_changed field in PROC to true. */
extern thread_state_t proc_get_state (struct proc *proc, int will_modify);
/* Return printable description of proc. */
extern char *proc_string (struct proc *proc);
#define proc_debug(_proc, msg, args...) \
do { struct proc *__proc = (_proc); \
debug ("{proc %d/%d %p}: " msg, \
__proc_pid (__proc), __proc->tid, __proc , ##args); } while (0)
extern int gnu_debug_flag;
#define debug(msg, args...) \
do { if (gnu_debug_flag) \
fprintf_unfiltered (gdb_stdlog, "%s: " msg "\r\n", __FUNCTION__ , ##args); } while (0)
#endif /* __GNU_NAT_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,576 +0,0 @@
/* Definitions for data structures and routines for the regular
expression library, version 0.12.
Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.
NOTE: The canonical source of this file is maintained with the
GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifndef _REGEX_H
#define _REGEX_H 1
/* Allow the use in C++ code. */
#ifdef __cplusplus
extern "C" {
#endif
/* POSIX says that <sys/types.h> must be included (by the caller) before
<regex.h>. */
#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
should be there. */
# include <stddef.h>
#endif
/* GDB LOCAL: define _REGEX_RE_COMP to get BSD style re_comp and re_exec */
#ifndef _REGEX_RE_COMP
#define _REGEX_RE_COMP
#endif
/* The following two types have to be signed and unsigned integer type
wide enough to hold a value of a pointer. For most ANSI compilers
ptrdiff_t and size_t should be likely OK. Still size of these two
types is 2 for Microsoft C. Ugh... */
typedef long int s_reg_t;
typedef unsigned long int active_reg_t;
/* The following bits are used to determine the regexp syntax we
recognize. The set/not-set meanings are chosen so that Emacs syntax
remains the value 0. The bits are given in alphabetical order, and
the definitions shifted by one from the previous bit; thus, when we
add or remove a bit, only one other definition need change. */
typedef unsigned long int reg_syntax_t;
/* If this bit is not set, then \ inside a bracket expression is literal.
If set, then such a \ quotes the following character. */
#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
/* If this bit is not set, then + and ? are operators, and \+ and \? are
literals.
If set, then \+ and \? are operators and + and ? are literals. */
#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
/* If this bit is set, then character classes are supported. They are:
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
If not set, then character classes are not supported. */
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
/* If this bit is set, then ^ and $ are always anchors (outside bracket
expressions, of course).
If this bit is not set, then it depends:
^ is an anchor if it is at the beginning of a regular
expression or after an open-group or an alternation operator;
$ is an anchor if it is at the end of a regular expression, or
before a close-group or an alternation operator.
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
POSIX draft 11.2 says that * etc. in leading positions is undefined.
We already implemented a previous draft which made those constructs
invalid, though, so we haven't changed the code back. */
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
/* If this bit is set, then special characters are always special
regardless of where they are in the pattern.
If this bit is not set, then special characters are special only in
some contexts; otherwise they are ordinary. Specifically,
* + ? and intervals are only special when not after the beginning,
open-group, or alternation operator. */
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
immediately after an alternation or begin-group operator. */
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
/* If this bit is set, then . matches newline.
If not set, then it doesn't. */
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
/* If this bit is set, then . doesn't match NUL.
If not set, then it does. */
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
/* If this bit is set, nonmatching lists [^...] do not match newline.
If not set, they do. */
#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
/* If this bit is set, either \{...\} or {...} defines an
interval, depending on RE_NO_BK_BRACES.
If not set, \{, \}, {, and } are literals. */
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
/* If this bit is set, +, ? and | aren't recognized as operators.
If not set, they are. */
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
/* If this bit is set, newline is an alternation operator.
If not set, newline is literal. */
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
are literals.
If not set, then `\{...\}' defines an interval. */
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
/* If this bit is set, (...) defines a group, and \( and \) are literals.
If not set, \(...\) defines a group, and ( and ) are literals. */
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
/* If this bit is set, then \<digit> matches <digit>.
If not set, then \<digit> is a back-reference. */
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
/* If this bit is set, then | is an alternation operator, and \| is literal.
If not set, then \| is an alternation operator, and | is literal. */
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
/* If this bit is set, then an ending range point collating higher
than the starting range point, as in [z-a], is invalid.
If not set, then when ending range point collates higher than the
starting range point, the range is ignored. */
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
/* If this bit is set, then an unmatched ) is ordinary.
If not set, then an unmatched ) is invalid. */
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
/* If this bit is set, succeed as soon as we match the whole pattern,
without further backtracking. */
#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
/* If this bit is set, do not process the GNU regex operators.
If not set, then the GNU regex operators are recognized. */
#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
/* If this bit is set, turn on internal regex debugging.
If not set, and debugging was on, turn it off.
This only works if regex.c is compiled -DDEBUG.
We define this bit always, so that all that's needed to turn on
debugging is to recompile regex.c; the calling code can always have
this bit set, and it won't affect anything in the normal case. */
#define RE_DEBUG (RE_NO_GNU_OPS << 1)
/* This global variable defines the particular regexp syntax to use (for
some interfaces). When a regexp is compiled, the syntax used is
stored in the pattern buffer, so changing this does not affect
already-compiled regexps. */
extern reg_syntax_t re_syntax_options;
/* Define combinations of the above bits for the standard possibilities.
(The [[[ comments delimit what gets put into the Texinfo file, so
don't delete them!) */
/* [[[begin syntaxes]]] */
#define RE_SYNTAX_EMACS 0
#define RE_SYNTAX_AWK \
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
| RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
| RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
#define RE_SYNTAX_GNU_AWK \
((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
& ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS))
#define RE_SYNTAX_POSIX_AWK \
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
| RE_INTERVALS | RE_NO_GNU_OPS)
#define RE_SYNTAX_GREP \
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
| RE_NEWLINE_ALT)
#define RE_SYNTAX_EGREP \
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
| RE_NO_BK_VBAR)
#define RE_SYNTAX_POSIX_EGREP \
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
/* Syntax bits common to both basic and extended POSIX regex syntax. */
#define _RE_SYNTAX_POSIX_COMMON \
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
#define RE_SYNTAX_POSIX_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
isn't minimal, since other operators, such as \`, aren't disabled. */
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
#define RE_SYNTAX_POSIX_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
| RE_UNMATCHED_RIGHT_PAREN_ORD)
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
/* [[[end syntaxes]]] */
/* Maximum number of duplicates an interval can allow. Some systems
(erroneously) define this in other header files, but we want our
value, so remove any previous define. */
#ifdef RE_DUP_MAX
# undef RE_DUP_MAX
#endif
/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
#define RE_DUP_MAX (0x7fff)
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
/* If this bit is set, then use extended regular expression syntax.
If not set, then use basic regular expression syntax. */
#define REG_EXTENDED 1
/* If this bit is set, then ignore case when matching.
If not set, then case is significant. */
#define REG_ICASE (REG_EXTENDED << 1)
/* If this bit is set, then anchors do not match at newline
characters in the string.
If not set, then anchors do match at newlines. */
#define REG_NEWLINE (REG_ICASE << 1)
/* If this bit is set, then report only success or fail in regexec.
If not set, then returns differ between not matching and errors. */
#define REG_NOSUB (REG_NEWLINE << 1)
/* POSIX `eflags' bits (i.e., information for regexec). */
/* If this bit is set, then the beginning-of-line operator doesn't match
the beginning of the string (presumably because it's not the
beginning of a line).
If not set, then the beginning-of-line operator does match the
beginning of the string. */
#define REG_NOTBOL 1
/* Like REG_NOTBOL, except for the end-of-line. */
#define REG_NOTEOL (1 << 1)
/* If any error codes are removed, changed, or added, update the
`re_error_msg' table in regex.c. */
typedef enum
{
#if (_XOPEN_SOURCE - 0) == 500
REG_NOSYS = -1, /* This will never happen for this implementation. */
#endif
REG_NOERROR = 0, /* Success. */
REG_NOMATCH, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
REG_BADPAT, /* Invalid pattern. */
REG_ECOLLATE, /* Not implemented. */
REG_ECTYPE, /* Invalid character class name. */
REG_EESCAPE, /* Trailing backslash. */
REG_ESUBREG, /* Invalid back reference. */
REG_EBRACK, /* Unmatched left bracket. */
REG_EPAREN, /* Parenthesis imbalance. */
REG_EBRACE, /* Unmatched \{. */
REG_BADBR, /* Invalid contents of \{\}. */
REG_ERANGE, /* Invalid range end. */
REG_ESPACE, /* Ran out of memory. */
REG_BADRPT, /* No preceding re for repetition op. */
/* Error codes we've added. */
REG_EEND, /* Premature end. */
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
} reg_errcode_t;
/* This data structure represents a compiled pattern. Before calling
the pattern compiler, the fields `buffer', `allocated', `fastmap',
`translate', and `no_sub' can be set. After the pattern has been
compiled, the `re_nsub' field is available. All other fields are
private to the regex routines. */
#ifndef RE_TRANSLATE_TYPE
# define RE_TRANSLATE_TYPE char *
#endif
struct re_pattern_buffer
{
/* [[[begin pattern_buffer]]] */
/* Space that holds the compiled pattern. It is declared as
`unsigned char *' because its elements are
sometimes used as array indexes. */
unsigned char *buffer;
/* Number of bytes to which `buffer' points. */
unsigned long int allocated;
/* Number of bytes actually used in `buffer'. */
unsigned long int used;
/* Syntax setting with which the pattern was compiled. */
reg_syntax_t syntax;
/* Pointer to a fastmap, if any, otherwise zero. re_search uses
the fastmap, if there is one, to skip over impossible
starting points for matches. */
char *fastmap;
/* Either a translate table to apply to all characters before
comparing them, or zero for no translation. The translation
is applied to a pattern when it is compiled and to a string
when it is matched. */
RE_TRANSLATE_TYPE translate;
/* Number of subexpressions found by the compiler. */
size_t re_nsub;
/* Zero if this pattern cannot match the empty string, one else.
Well, in truth it's used only in `re_search_2', to see
whether or not we should use the fastmap, so we don't set
this absolutely perfectly; see `re_compile_fastmap' (the
`duplicate' case). */
unsigned can_be_null : 1;
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
for `max (RE_NREGS, re_nsub + 1)' groups.
If REGS_REALLOCATE, reallocate space if necessary.
If REGS_FIXED, use what's there. */
#define REGS_UNALLOCATED 0
#define REGS_REALLOCATE 1
#define REGS_FIXED 2
unsigned regs_allocated : 2;
/* Set to zero when `regex_compile' compiles a pattern; set to one
by `re_compile_fastmap' if it updates the fastmap. */
unsigned fastmap_accurate : 1;
/* If set, `re_match_2' does not return information about
subexpressions. */
unsigned no_sub : 1;
/* If set, a beginning-of-line anchor doesn't match at the
beginning of the string. */
unsigned not_bol : 1;
/* Similarly for an end-of-line anchor. */
unsigned not_eol : 1;
/* If true, an anchor at a newline matches. */
unsigned newline_anchor : 1;
/* [[[end pattern_buffer]]] */
};
typedef struct re_pattern_buffer regex_t;
/* Type for byte offsets within the string. POSIX mandates this. */
typedef int regoff_t;
/* This is the structure we store register match data in. See
regex.texinfo for a full description of what registers match. */
struct re_registers
{
unsigned num_regs;
regoff_t *start;
regoff_t *end;
};
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
`re_match_2' returns information about at least this many registers
the first time a `regs' structure is passed. */
#ifndef RE_NREGS
# define RE_NREGS 30
#endif
/* POSIX specification for registers. Aside from the different names than
`re_registers', POSIX uses an array of structures, instead of a
structure of arrays. */
typedef struct
{
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
} regmatch_t;
/* Declarations for routines. */
/* To avoid duplicating every routine declaration -- once with a
prototype (if we are ANSI), and once without (if we aren't) -- we
use the following macro to declare argument types. This
unfortunately clutters up the declarations a bit, but I think it's
worth it. */
#if __STDC__
# define _RE_ARGS(args) args
#else /* not __STDC__ */
# define _RE_ARGS(args) ()
#endif /* not __STDC__ */
/* Sets the current default syntax to SYNTAX, and return the old syntax.
You can also simply assign to the `re_syntax_options' variable. */
extern reg_syntax_t __re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
/* Compile the regular expression PATTERN, with length LENGTH
and syntax given by the global `re_syntax_options', into the buffer
BUFFER. Return NULL if successful, and an error string if not. */
extern const char *__re_compile_pattern
_RE_ARGS ((const char *pattern, size_t length,
struct re_pattern_buffer *buffer));
extern const char *re_compile_pattern
_RE_ARGS ((const char *pattern, size_t length,
struct re_pattern_buffer *buffer));
/* Compile a fastmap for the compiled pattern in BUFFER; used to
accelerate searches. Return 0 if successful and -2 if was an
internal error. */
extern int __re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
/* Search in the string STRING (with length LENGTH) for the pattern
compiled into BUFFER. Start searching at position START, for RANGE
characters. Return the starting position of the match, -1 for no
match, or -2 for an internal error. Also return register
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
extern int __re_search
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, int range, struct re_registers *regs));
extern int re_search
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, int range, struct re_registers *regs));
/* Like `re_search', but search in the concatenation of STRING1 and
STRING2. Also, stop searching at index START + STOP. */
extern int __re_search_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, int range, struct re_registers *regs, int stop));
extern int re_search_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, int range, struct re_registers *regs, int stop));
/* Like `re_search', but return how many characters in STRING the regexp
in BUFFER matched, starting at position START. */
extern int __re_match
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, struct re_registers *regs));
extern int re_match
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
int length, int start, struct re_registers *regs));
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
extern int __re_match_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, struct re_registers *regs, int stop));
extern int re_match_2
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
int length1, const char *string2, int length2,
int start, struct re_registers *regs, int stop));
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
ENDS. Subsequent matches using BUFFER and REGS will use this memory
for recording register information. STARTS and ENDS must be
allocated with malloc, and must each be at least `NUM_REGS * sizeof
(regoff_t)' bytes long.
If NUM_REGS == 0, then subsequent matches should allocate their own
register data.
Unless this function is called, the first search or match using
PATTERN_BUFFER will allocate its own register data, without
freeing the old data. */
extern void __re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
extern void re_set_registers
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
unsigned num_regs, regoff_t *starts, regoff_t *ends));
#ifdef _REGEX_RE_COMP
# ifndef _CRAY
/* 4.2 bsd compatibility. */
extern char *re_comp _RE_ARGS ((const char *));
extern int re_exec _RE_ARGS ((const char *));
# endif
#endif
/* POSIX compatibility. */
extern int __regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern,
int __cflags));
extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern,
int __cflags));
extern int __regexec _RE_ARGS ((const regex_t *__preg,
const char *__string, size_t __nmatch,
regmatch_t __pmatch[], int __eflags));
extern int regexec _RE_ARGS ((const regex_t *__preg,
const char *__string, size_t __nmatch,
regmatch_t __pmatch[], int __eflags));
extern size_t __regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
char *__errbuf, size_t __errbuf_size));
extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
char *__errbuf, size_t __errbuf_size));
extern void __regfree _RE_ARGS ((regex_t *__preg));
extern void regfree _RE_ARGS ((regex_t *__preg));
#ifdef __cplusplus
}
#endif /* C++ */
#endif /* regex.h */
/*
Local variables:
make-backup-files: t
version-control: t
trim-versions-without-asking: nil
End:
*/

View File

@ -1,35 +0,0 @@
/* Host-dependent code for dos running GO32 for GDB, the GNU debugger.
Copyright 1992 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <stdio.h>
int
sigsetmask (mask)
int mask;
{
return 0;
}
void
strlwr (str)
char *str;
{
for (; *str; str++)
*str = tolower(*str);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,150 +0,0 @@
/* hpread.h
* Common include file for:
* hp_symtab_read.c
* hp_psymtab_read.c
*/
/* Copyright 1993, 1996 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Written by the Center for Software Science at the University of Utah
and by Cygnus Support. */
#include "defs.h"
#include "bfd.h"
#include "gdb_string.h"
#include "hp-symtab.h"
#include "syms.h"
#include "symtab.h"
#include "symfile.h"
#include "objfiles.h"
#include "buildsym.h"
#include "complaints.h"
#include "gdb-stabs.h"
#include "gdbtypes.h"
#include "demangle.h"
/* Private information attached to an objfile which we use to find
and internalize the HP C debug symbols within that objfile. */
struct hpread_symfile_info
{
/* The contents of each of the debug sections (there are 4 of them). */
char *gntt;
char *lntt;
char *slt;
char *vt;
/* We keep the size of the $VT$ section for range checking. */
unsigned int vt_size;
/* Some routines still need to know the number of symbols in the
main debug sections ($LNTT$ and $GNTT$). */
unsigned int lntt_symcount;
unsigned int gntt_symcount;
/* To keep track of all the types we've processed. */
struct type **type_vector;
int type_vector_length;
/* Keeps track of the beginning of a range of source lines. */
sltpointer sl_index;
/* Some state variables we'll need. */
int within_function;
/* Keep track of the current function's address. We may need to look
up something based on this address. */
unsigned int current_function_value;
};
/* Accessor macros to get at the fields. */
#define HPUX_SYMFILE_INFO(o) \
((struct hpread_symfile_info *)((o)->sym_private))
#define GNTT(o) (HPUX_SYMFILE_INFO(o)->gntt)
#define LNTT(o) (HPUX_SYMFILE_INFO(o)->lntt)
#define SLT(o) (HPUX_SYMFILE_INFO(o)->slt)
#define VT(o) (HPUX_SYMFILE_INFO(o)->vt)
#define VT_SIZE(o) (HPUX_SYMFILE_INFO(o)->vt_size)
#define LNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->lntt_symcount)
#define GNTT_SYMCOUNT(o) (HPUX_SYMFILE_INFO(o)->gntt_symcount)
#define TYPE_VECTOR(o) (HPUX_SYMFILE_INFO(o)->type_vector)
#define TYPE_VECTOR_LENGTH(o) (HPUX_SYMFILE_INFO(o)->type_vector_length)
#define SL_INDEX(o) (HPUX_SYMFILE_INFO(o)->sl_index)
#define WITHIN_FUNCTION(o) (HPUX_SYMFILE_INFO(o)->within_function)
#define CURRENT_FUNCTION_VALUE(o) (HPUX_SYMFILE_INFO(o)->current_function_value)
/* Given the native debug symbol SYM, set NAMEP to the name associated
with the debug symbol. Note we may be called with a debug symbol which
has no associated name, in that case we return an empty string.
Also note we "know" that the name for any symbol is always in the
same place. Hence we don't have to conditionalize on the symbol type. */
#define SET_NAMESTRING(SYM, NAMEP, OBJFILE) \
if (! hpread_has_name ((SYM)->dblock.kind)) \
*NAMEP = ""; \
else if (((unsigned)(SYM)->dsfile.name) >= VT_SIZE (OBJFILE)) \
{ \
complain (&string_table_offset_complaint, (char *) symnum); \
*NAMEP = ""; \
} \
else \
*NAMEP = (SYM)->dsfile.name + VT (OBJFILE)
/* We put a pointer to this structure in the read_symtab_private field
of the psymtab. */
struct symloc
{
/* The offset within the file symbol table of first local symbol for
this file. */
int ldsymoff;
/* Length (in bytes) of the section of the symbol table devoted to
this file's symbols (actually, the section bracketed may contain
more than just this file's symbols). If ldsymlen is 0, the only
reason for this thing's existence is the dependency list.
Nothing else will happen when it is read in. */
int ldsymlen;
};
#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
/* FIXME: Shouldn't this stuff be in a .h file somewhere? */
/* Nonzero means give verbose info on gdb action. */
extern int info_verbose;
/* Complaints about the symbols we have encountered. */
extern struct complaint string_table_offset_complaint;
extern struct complaint lbrac_unmatched_complaint;
extern struct complaint lbrac_mismatch_complaint;
extern union sltentry *hpread_get_slt
PARAMS ((int, struct objfile *));
extern union dnttentry *hpread_get_lntt
PARAMS ((int, struct objfile *));
int hpread_has_name
PARAMS ((enum dntt_entry_type));
/* end of hpread.h */

View File

@ -1,271 +0,0 @@
/* Low level interface to i386 running the GNU Hurd.
Copyright 1992, 1995, 1996, 1998, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "inferior.h"
#include "floatformat.h"
#include "regcache.h"
#include "gdb_assert.h"
#include <errno.h>
#include <stdio.h>
#include <mach.h>
#include <mach_error.h>
#include <mach/message.h>
#include <mach/exception.h>
#include "i386-tdep.h"
#include "gnu-nat.h"
#include "i387-nat.h"
/* Offset to the thread_state_t location where REG is stored. */
#define REG_OFFSET(reg) offsetof (struct i386_thread_state, reg)
/* At REG_OFFSET[N] is the offset to the thread_state_t location where
the GDB register N is stored. */
static int reg_offset[] =
{
REG_OFFSET (eax), REG_OFFSET (ecx), REG_OFFSET (edx), REG_OFFSET (ebx),
REG_OFFSET (uesp), REG_OFFSET (ebp), REG_OFFSET (esi), REG_OFFSET (edi),
REG_OFFSET (eip), REG_OFFSET (efl), REG_OFFSET (cs), REG_OFFSET (ss),
REG_OFFSET (ds), REG_OFFSET (es), REG_OFFSET (fs), REG_OFFSET (gs)
};
#define REG_ADDR(state, regnum) ((char *)(state) + reg_offset[regnum])
/* Get the whole floating-point state of THREAD and record the
values of the corresponding (pseudo) registers. */
static void
fetch_fpregs (struct proc *thread)
{
mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
struct i386_float_state state;
error_t err;
err = thread_get_state (thread->port, i386_FLOAT_STATE,
(thread_state_t) &state, &count);
if (err)
{
warning ("Couldn't fetch floating-point state from %s",
proc_string (thread));
return;
}
if (!state.initialized)
/* The floating-point state isn't initialized. */
{
int i;
for (i = FP0_REGNUM; i <= FOP_REGNUM; i++)
supply_register (i, NULL);
return;
}
/* Supply the floating-point registers. */
i387_supply_fsave (state.hw_state);
}
/* Fetch register REGNO, or all regs if REGNO is -1. */
void
gnu_fetch_registers (int regno)
{
struct proc *thread;
/* Make sure we know about new threads. */
inf_update_procs (current_inferior);
thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
if (!thread)
error ("Can't fetch registers from thread %d: No such thread",
PIDGET (inferior_ptid));
if (regno < NUM_GREGS || regno == -1)
{
thread_state_t state;
/* This does the dirty work for us. */
state = proc_get_state (thread, 0);
if (!state)
{
warning ("Couldn't fetch registers from %s",
proc_string (thread));
return;
}
if (regno == -1)
{
int i;
proc_debug (thread, "fetching all register");
for (i = 0; i < NUM_GREGS; i++)
supply_register (i, REG_ADDR (state, i));
thread->fetched_regs = ~0;
}
else
{
proc_debug (thread, "fetching register %s", REGISTER_NAME (regno));
supply_register (regno, REG_ADDR (state, regno));
thread->fetched_regs |= (1 << regno);
}
}
if (regno >= NUM_GREGS || regno == -1)
{
proc_debug (thread, "fetching floating-point registers");
fetch_fpregs (thread);
}
}
/* Store the whole floating-point state into THREAD using information
from the corresponding (pseudo) registers. */
static void
store_fpregs (struct proc *thread, int regno)
{
mach_msg_type_number_t count = i386_FLOAT_STATE_COUNT;
struct i386_float_state state;
error_t err;
err = thread_get_state (thread->port, i386_FLOAT_STATE,
(thread_state_t) &state, &count);
if (err)
{
warning ("Couldn't fetch floating-point state from %s",
proc_string (thread));
return;
}
/* FIXME: kettenis/2001-07-15: Is this right? Should we somehow
take into account REGISTER_VALID like the old code did? */
i387_fill_fsave (state.hw_state, regno);
err = thread_set_state (thread->port, i386_FLOAT_STATE,
(thread_state_t) &state, i386_FLOAT_STATE_COUNT);
if (err)
{
warning ("Couldn't store floating-point state into %s",
proc_string (thread));
return;
}
}
/* Store at least register REGNO, or all regs if REGNO == -1. */
void
gnu_store_registers (int regno)
{
struct proc *thread;
/* Make sure we know about new threads. */
inf_update_procs (current_inferior);
thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid));
if (!thread)
error ("Couldn't store registers into thread %d: No such thread",
PIDGET (inferior_ptid));
if (regno < NUM_GREGS || regno == -1)
{
thread_state_t state;
thread_state_data_t old_state;
int was_aborted = thread->aborted;
int was_valid = thread->state_valid;
int trace;
if (!was_aborted && was_valid)
memcpy (&old_state, &thread->state, sizeof (old_state));
state = proc_get_state (thread, 1);
if (!state)
{
warning ("Couldn't store registers into %s", proc_string (thread));
return;
}
/* Save the T bit. We might try to restore the %eflags register
below, but changing the T bit would seriously confuse GDB. */
trace = ((struct i386_thread_state *)state)->efl & 0x100;
if (!was_aborted && was_valid)
/* See which registers have changed after aborting the thread. */
{
int check_regno;
for (check_regno = 0; check_regno < NUM_GREGS; check_regno++)
if ((thread->fetched_regs & (1 << check_regno))
&& memcpy (REG_ADDR (&old_state, check_regno),
REG_ADDR (state, check_regno),
REGISTER_RAW_SIZE (check_regno)))
/* Register CHECK_REGNO has changed! Ack! */
{
warning ("Register %s changed after the thread was aborted",
REGISTER_NAME (check_regno));
if (regno >= 0 && regno != check_regno)
/* Update GDB's copy of the register. */
supply_register (check_regno, REG_ADDR (state, check_regno));
else
warning ("... also writing this register! Suspicious...");
}
}
#define fill(state, regno) \
memcpy (REG_ADDR(state, regno), &registers[REGISTER_BYTE (regno)], \
REGISTER_RAW_SIZE (regno))
if (regno == -1)
{
int i;
proc_debug (thread, "storing all registers");
for (i = 0; i < NUM_GREGS; i++)
if (register_valid[i])
fill (state, i);
}
else
{
proc_debug (thread, "storing register %s", REGISTER_NAME (regno));
gdb_assert (register_valid[regno]);
fill (state, regno);
}
/* Restore the T bit. */
((struct i386_thread_state *)state)->efl &= ~0x100;
((struct i386_thread_state *)state)->efl |= trace;
}
#undef fill
if (regno >= NUM_GREGS || regno == -1)
{
proc_debug (thread, "storing floating-point registers");
store_fpregs (thread, regno);
}
}

View File

@ -1,207 +0,0 @@
/* Native support for the SGI Iris running IRIX version 4, for GDB.
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1995, 1996, 1999, 2000,
2001 Free Software Foundation, Inc.
Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
Implemented for Irix 4.x by Garrett A. Wollman.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include <sys/time.h>
#include <sys/procfs.h>
#include <setjmp.h> /* For JB_XXX. */
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* Size of elements in jmpbuf */
#define JB_ELEMENT_SIZE 4
typedef unsigned int greg_t; /* why isn't this defined? */
static void fetch_core_registers (char *, unsigned int, int, CORE_ADDR);
/*
* See the comment in m68k-tdep.c regarding the utility of these functions.
*/
void
supply_gregset (gregset_t *gregsetp)
{
register int regi;
register greg_t *regp = (greg_t *) (gregsetp->gp_regs);
static char zerobuf[MAX_REGISTER_RAW_SIZE] =
{0};
/* FIXME: somewhere, there should be a #define for the meaning
of this magic number 32; we should use that. */
for (regi = 0; regi < 32; regi++)
supply_register (regi, (char *) (regp + regi));
supply_register (PC_REGNUM, (char *) &(gregsetp->gp_pc));
supply_register (HI_REGNUM, (char *) &(gregsetp->gp_mdhi));
supply_register (LO_REGNUM, (char *) &(gregsetp->gp_mdlo));
supply_register (CAUSE_REGNUM, (char *) &(gregsetp->gp_cause));
/* Fill inaccessible registers with zero. */
supply_register (BADVADDR_REGNUM, zerobuf);
}
void
fill_gregset (gregset_t *gregsetp, int regno)
{
int regi;
register greg_t *regp = (greg_t *) (gregsetp->gp_regs);
/* same FIXME as above wrt 32 */
for (regi = 0; regi < 32; regi++)
if ((regno == -1) || (regno == regi))
*(regp + regi) = *(greg_t *) & registers[REGISTER_BYTE (regi)];
if ((regno == -1) || (regno == PC_REGNUM))
gregsetp->gp_pc = *(greg_t *) & registers[REGISTER_BYTE (PC_REGNUM)];
if ((regno == -1) || (regno == CAUSE_REGNUM))
gregsetp->gp_cause = *(greg_t *) & registers[REGISTER_BYTE (CAUSE_REGNUM)];
if ((regno == -1) || (regno == HI_REGNUM))
gregsetp->gp_mdhi = *(greg_t *) & registers[REGISTER_BYTE (HI_REGNUM)];
if ((regno == -1) || (regno == LO_REGNUM))
gregsetp->gp_mdlo = *(greg_t *) & registers[REGISTER_BYTE (LO_REGNUM)];
}
/*
* Now we do the same thing for floating-point registers.
* We don't bother to condition on FP0_REGNUM since any
* reasonable MIPS configuration has an R3010 in it.
*
* Again, see the comments in m68k-tdep.c.
*/
void
supply_fpregset (fpregset_t *fpregsetp)
{
register int regi;
static char zerobuf[MAX_REGISTER_RAW_SIZE] =
{0};
for (regi = 0; regi < 32; regi++)
supply_register (FP0_REGNUM + regi,
(char *) &fpregsetp->fp_r.fp_regs[regi]);
supply_register (FCRCS_REGNUM, (char *) &fpregsetp->fp_csr);
/* FIXME: how can we supply FCRIR_REGNUM? SGI doesn't tell us. */
supply_register (FCRIR_REGNUM, zerobuf);
}
void
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
int regi;
char *from, *to;
for (regi = FP0_REGNUM; regi < FP0_REGNUM + 32; regi++)
{
if ((regno == -1) || (regno == regi))
{
from = (char *) &registers[REGISTER_BYTE (regi)];
to = (char *) &(fpregsetp->fp_r.fp_regs[regi - FP0_REGNUM]);
memcpy (to, from, REGISTER_RAW_SIZE (regi));
}
}
if ((regno == -1) || (regno == FCRCS_REGNUM))
fpregsetp->fp_csr = *(unsigned *) &registers[REGISTER_BYTE (FCRCS_REGNUM)];
}
/* Figure out where the longjmp will land.
We expect the first arg to be a pointer to the jmp_buf structure from which
we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
This routine returns true on success. */
int
get_longjmp_target (CORE_ADDR *pc)
{
char *buf;
CORE_ADDR jb_addr;
buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
jb_addr = read_register (A0_REGNUM);
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
TARGET_PTR_BIT / TARGET_CHAR_BIT))
return 0;
*pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
return 1;
}
/* Provide registers to GDB from a core file.
CORE_REG_SECT points to an array of bytes, which were obtained from
a core file which BFD thinks might contain register contents.
CORE_REG_SIZE is its size.
Normally, WHICH says which register set corelow suspects this is:
0 --- the general-purpose register set
2 --- the floating-point register set
However, for Irix 4, WHICH isn't used.
REG_ADDR is also unused. */
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
int which, CORE_ADDR reg_addr)
{
if (core_reg_size != REGISTER_BYTES)
{
warning ("wrong size gregset struct in core file");
return;
}
memcpy ((char *) registers, core_reg_sect, core_reg_size);
}
/* Register that we are able to handle irix4 core file formats.
FIXME: is this really bfd_target_unknown_flavour? */
static struct core_fns irix4_core_fns =
{
bfd_target_unknown_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_core_irix4 (void)
{
add_core_fns (&irix4_core_fns);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +0,0 @@
/* Copyright (C) 1993 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include <machine/reg.h>
int rloc[] = {
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, FP, SP, PS, PC
};

File diff suppressed because it is too large Load Diff

View File

@ -1,38 +0,0 @@
/* Main loop for the standalone kernel debugger, for GDB, the GNU Debugger.
Copyright 1989, 1991, 1992 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
static char *args[] =
{"kdb", "kdb-symbols", 0};
static char *environment[] =
{0};
char **environ;
start ()
{
INIT_STACK (kdb_stack_beg, kdb_stack_end);
environ = environment;
main (2, args, environment);
}

View File

@ -1,829 +0,0 @@
/* Native-dependent code for LynxOS.
Copyright 1993, 1994, 1995, 1996, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
#include "regcache.h"
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/fpp.h>
static unsigned long registers_addr (int pid);
static void fetch_core_registers (char *, unsigned, int, CORE_ADDR);
#define X(ENTRY)(offsetof(struct econtext, ENTRY))
#ifdef I386
/* Mappings from tm-i386v.h */
static int regmap[] =
{
X (eax),
X (ecx),
X (edx),
X (ebx),
X (esp), /* sp */
X (ebp), /* fp */
X (esi),
X (edi),
X (eip), /* pc */
X (flags), /* ps */
X (cs),
X (ss),
X (ds),
X (es),
X (ecode), /* Lynx doesn't give us either fs or gs, so */
X (fault), /* we just substitute these two in the hopes
that they are useful. */
};
#endif /* I386 */
#ifdef M68K
/* Mappings from tm-m68k.h */
static int regmap[] =
{
X (regs[0]), /* d0 */
X (regs[1]), /* d1 */
X (regs[2]), /* d2 */
X (regs[3]), /* d3 */
X (regs[4]), /* d4 */
X (regs[5]), /* d5 */
X (regs[6]), /* d6 */
X (regs[7]), /* d7 */
X (regs[8]), /* a0 */
X (regs[9]), /* a1 */
X (regs[10]), /* a2 */
X (regs[11]), /* a3 */
X (regs[12]), /* a4 */
X (regs[13]), /* a5 */
X (regs[14]), /* fp */
offsetof (st_t, usp) - offsetof (st_t, ec), /* sp */
X (status), /* ps */
X (pc),
X (fregs[0 * 3]), /* fp0 */
X (fregs[1 * 3]), /* fp1 */
X (fregs[2 * 3]), /* fp2 */
X (fregs[3 * 3]), /* fp3 */
X (fregs[4 * 3]), /* fp4 */
X (fregs[5 * 3]), /* fp5 */
X (fregs[6 * 3]), /* fp6 */
X (fregs[7 * 3]), /* fp7 */
X (fcregs[0]), /* fpcontrol */
X (fcregs[1]), /* fpstatus */
X (fcregs[2]), /* fpiaddr */
X (ssw), /* fpcode */
X (fault), /* fpflags */
};
#endif /* M68K */
#ifdef SPARC
/* Mappings from tm-sparc.h */
#define FX(ENTRY)(offsetof(struct fcontext, ENTRY))
static int regmap[] =
{
-1, /* g0 */
X (g1),
X (g2),
X (g3),
X (g4),
-1, /* g5->g7 aren't saved by Lynx */
-1,
-1,
X (o[0]),
X (o[1]),
X (o[2]),
X (o[3]),
X (o[4]),
X (o[5]),
X (o[6]), /* sp */
X (o[7]), /* ra */
-1, -1, -1, -1, -1, -1, -1, -1, /* l0 -> l7 */
-1, -1, -1, -1, -1, -1, -1, -1, /* i0 -> i7 */
FX (f.fregs[0]), /* f0 */
FX (f.fregs[1]),
FX (f.fregs[2]),
FX (f.fregs[3]),
FX (f.fregs[4]),
FX (f.fregs[5]),
FX (f.fregs[6]),
FX (f.fregs[7]),
FX (f.fregs[8]),
FX (f.fregs[9]),
FX (f.fregs[10]),
FX (f.fregs[11]),
FX (f.fregs[12]),
FX (f.fregs[13]),
FX (f.fregs[14]),
FX (f.fregs[15]),
FX (f.fregs[16]),
FX (f.fregs[17]),
FX (f.fregs[18]),
FX (f.fregs[19]),
FX (f.fregs[20]),
FX (f.fregs[21]),
FX (f.fregs[22]),
FX (f.fregs[23]),
FX (f.fregs[24]),
FX (f.fregs[25]),
FX (f.fregs[26]),
FX (f.fregs[27]),
FX (f.fregs[28]),
FX (f.fregs[29]),
FX (f.fregs[30]),
FX (f.fregs[31]),
X (y),
X (psr),
X (wim),
X (tbr),
X (pc),
X (npc),
FX (fsr), /* fpsr */
-1, /* cpsr */
};
#endif /* SPARC */
#ifdef rs6000
static int regmap[] =
{
X (iregs[0]), /* r0 */
X (iregs[1]),
X (iregs[2]),
X (iregs[3]),
X (iregs[4]),
X (iregs[5]),
X (iregs[6]),
X (iregs[7]),
X (iregs[8]),
X (iregs[9]),
X (iregs[10]),
X (iregs[11]),
X (iregs[12]),
X (iregs[13]),
X (iregs[14]),
X (iregs[15]),
X (iregs[16]),
X (iregs[17]),
X (iregs[18]),
X (iregs[19]),
X (iregs[20]),
X (iregs[21]),
X (iregs[22]),
X (iregs[23]),
X (iregs[24]),
X (iregs[25]),
X (iregs[26]),
X (iregs[27]),
X (iregs[28]),
X (iregs[29]),
X (iregs[30]),
X (iregs[31]),
X (fregs[0]), /* f0 */
X (fregs[1]),
X (fregs[2]),
X (fregs[3]),
X (fregs[4]),
X (fregs[5]),
X (fregs[6]),
X (fregs[7]),
X (fregs[8]),
X (fregs[9]),
X (fregs[10]),
X (fregs[11]),
X (fregs[12]),
X (fregs[13]),
X (fregs[14]),
X (fregs[15]),
X (fregs[16]),
X (fregs[17]),
X (fregs[18]),
X (fregs[19]),
X (fregs[20]),
X (fregs[21]),
X (fregs[22]),
X (fregs[23]),
X (fregs[24]),
X (fregs[25]),
X (fregs[26]),
X (fregs[27]),
X (fregs[28]),
X (fregs[29]),
X (fregs[30]),
X (fregs[31]),
X (srr0), /* IAR (PC) */
X (srr1), /* MSR (PS) */
X (cr), /* CR */
X (lr), /* LR */
X (ctr), /* CTR */
X (xer), /* XER */
X (mq) /* MQ */
};
#endif /* rs6000 */
#ifdef SPARC
/* This routine handles some oddball cases for Sparc registers and LynxOS.
In partucular, it causes refs to G0, g5->7, and all fp regs to return zero.
It also handles knows where to find the I & L regs on the stack. */
void
fetch_inferior_registers (int regno)
{
int whatregs = 0;
#define WHATREGS_FLOAT 1
#define WHATREGS_GEN 2
#define WHATREGS_STACK 4
if (regno == -1)
whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
whatregs = WHATREGS_STACK;
else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
whatregs = WHATREGS_FLOAT;
else
whatregs = WHATREGS_GEN;
if (whatregs & WHATREGS_GEN)
{
struct econtext ec; /* general regs */
char buf[MAX_REGISTER_RAW_SIZE];
int retval;
int i;
errno = 0;
retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & ec, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_GETREGS)");
memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM));
supply_register (G0_REGNUM, buf);
supply_register (TBR_REGNUM, (char *) &ec.tbr);
memcpy (&registers[REGISTER_BYTE (G1_REGNUM)], &ec.g1,
4 * REGISTER_RAW_SIZE (G1_REGNUM));
for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++)
register_valid[i] = 1;
supply_register (PS_REGNUM, (char *) &ec.psr);
supply_register (Y_REGNUM, (char *) &ec.y);
supply_register (PC_REGNUM, (char *) &ec.pc);
supply_register (NPC_REGNUM, (char *) &ec.npc);
supply_register (WIM_REGNUM, (char *) &ec.wim);
memcpy (&registers[REGISTER_BYTE (O0_REGNUM)], ec.o,
8 * REGISTER_RAW_SIZE (O0_REGNUM));
for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++)
register_valid[i] = 1;
}
if (whatregs & WHATREGS_STACK)
{
CORE_ADDR sp;
int i;
sp = read_register (SP_REGNUM);
target_read_memory (sp + FRAME_SAVED_I0,
&registers[REGISTER_BYTE (I0_REGNUM)],
8 * REGISTER_RAW_SIZE (I0_REGNUM));
for (i = I0_REGNUM; i <= I7_REGNUM; i++)
register_valid[i] = 1;
target_read_memory (sp + FRAME_SAVED_L0,
&registers[REGISTER_BYTE (L0_REGNUM)],
8 * REGISTER_RAW_SIZE (L0_REGNUM));
for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++)
register_valid[i] = 1;
}
if (whatregs & WHATREGS_FLOAT)
{
struct fcontext fc; /* fp regs */
int retval;
int i;
errno = 0;
retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & fc, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_GETFPREGS)");
memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs,
32 * REGISTER_RAW_SIZE (FP0_REGNUM));
for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++)
register_valid[i] = 1;
supply_register (FPS_REGNUM, (char *) &fc.fsr);
}
}
/* This routine handles storing of the I & L regs for the Sparc. The trick
here is that they actually live on the stack. The really tricky part is
that when changing the stack pointer, the I & L regs must be written to
where the new SP points, otherwise the regs will be incorrect when the
process is started up again. We assume that the I & L regs are valid at
this point. */
void
store_inferior_registers (int regno)
{
int whatregs = 0;
if (regno == -1)
whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK;
else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
whatregs = WHATREGS_STACK;
else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32)
whatregs = WHATREGS_FLOAT;
else if (regno == SP_REGNUM)
whatregs = WHATREGS_STACK | WHATREGS_GEN;
else
whatregs = WHATREGS_GEN;
if (whatregs & WHATREGS_GEN)
{
struct econtext ec; /* general regs */
int retval;
ec.tbr = read_register (TBR_REGNUM);
memcpy (&ec.g1, &registers[REGISTER_BYTE (G1_REGNUM)],
4 * REGISTER_RAW_SIZE (G1_REGNUM));
ec.psr = read_register (PS_REGNUM);
ec.y = read_register (Y_REGNUM);
ec.pc = read_register (PC_REGNUM);
ec.npc = read_register (NPC_REGNUM);
ec.wim = read_register (WIM_REGNUM);
memcpy (ec.o, &registers[REGISTER_BYTE (O0_REGNUM)],
8 * REGISTER_RAW_SIZE (O0_REGNUM));
errno = 0;
retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & ec, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_SETREGS)");
}
if (whatregs & WHATREGS_STACK)
{
int regoffset;
CORE_ADDR sp;
sp = read_register (SP_REGNUM);
if (regno == -1 || regno == SP_REGNUM)
{
if (!register_valid[L0_REGNUM + 5])
internal_error (__FILE__, __LINE__, "failed internal consistency check");
target_write_memory (sp + FRAME_SAVED_I0,
&registers[REGISTER_BYTE (I0_REGNUM)],
8 * REGISTER_RAW_SIZE (I0_REGNUM));
target_write_memory (sp + FRAME_SAVED_L0,
&registers[REGISTER_BYTE (L0_REGNUM)],
8 * REGISTER_RAW_SIZE (L0_REGNUM));
}
else if (regno >= L0_REGNUM && regno <= I7_REGNUM)
{
if (!register_valid[regno])
internal_error (__FILE__, __LINE__, "failed internal consistency check");
if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7)
regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM)
+ FRAME_SAVED_L0;
else
regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM)
+ FRAME_SAVED_I0;
target_write_memory (sp + regoffset,
&registers[REGISTER_BYTE (regno)],
REGISTER_RAW_SIZE (regno));
}
}
if (whatregs & WHATREGS_FLOAT)
{
struct fcontext fc; /* fp regs */
int retval;
/* We read fcontext first so that we can get good values for fq_t... */
errno = 0;
retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & fc, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_GETFPREGS)");
memcpy (fc.f.fregs, &registers[REGISTER_BYTE (FP0_REGNUM)],
32 * REGISTER_RAW_SIZE (FP0_REGNUM));
fc.fsr = read_register (FPS_REGNUM);
errno = 0;
retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & fc, 0);
if (errno)
perror_with_name ("ptrace(PTRACE_SETFPREGS)");
}
}
#endif /* SPARC */
#if defined (I386) || defined (M68K) || defined (rs6000)
/* Return the offset relative to the start of the per-thread data to the
saved context block. */
static unsigned long
registers_addr (int pid)
{
CORE_ADDR stblock;
int ecpoff = offsetof (st_t, ecp);
CORE_ADDR ecp;
errno = 0;
stblock = (CORE_ADDR) ptrace (PTRACE_THREADUSER, pid, (PTRACE_ARG3_TYPE) 0,
0);
if (errno)
perror_with_name ("ptrace(PTRACE_THREADUSER)");
ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, pid, (PTRACE_ARG3_TYPE) ecpoff,
0);
if (errno)
perror_with_name ("ptrace(PTRACE_PEEKTHREAD)");
return ecp - stblock;
}
/* Fetch one or more registers from the inferior. REGNO == -1 to get
them all. We actually fetch more than requested, when convenient,
marking them as valid so we won't fetch them again. */
void
fetch_inferior_registers (int regno)
{
int reglo, reghi;
int i;
unsigned long ecp;
if (regno == -1)
{
reglo = 0;
reghi = NUM_REGS - 1;
}
else
reglo = reghi = regno;
ecp = registers_addr (PIDGET (inferior_ptid));
for (regno = reglo; regno <= reghi; regno++)
{
char buf[MAX_REGISTER_RAW_SIZE];
int ptrace_fun = PTRACE_PEEKTHREAD;
#ifdef M68K
ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD;
#endif
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
unsigned int reg;
errno = 0;
reg = ptrace (ptrace_fun, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0);
if (errno)
perror_with_name ("ptrace(PTRACE_PEEKUSP)");
*(int *) &buf[i] = reg;
}
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). */
void
store_inferior_registers (int regno)
{
int reglo, reghi;
int i;
unsigned long ecp;
if (regno == -1)
{
reglo = 0;
reghi = NUM_REGS - 1;
}
else
reglo = reghi = regno;
ecp = registers_addr (PIDGET (inferior_ptid));
for (regno = reglo; regno <= reghi; regno++)
{
int ptrace_fun = PTRACE_POKEUSER;
if (CANNOT_STORE_REGISTER (regno))
continue;
#ifdef M68K
ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER;
#endif
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
unsigned int reg;
reg = *(unsigned int *) &registers[REGISTER_BYTE (regno) + i];
errno = 0;
ptrace (ptrace_fun, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg);
if (errno)
perror_with_name ("ptrace(PTRACE_POKEUSP)");
}
}
}
#endif /* defined (I386) || defined (M68K) || defined (rs6000) */
/* Wait for child to do something. Return pid of child, or -1 in case
of error; store status through argument pointer OURSTATUS. */
ptid_t
child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
int save_errno;
int thread;
union wait status;
int pid;
while (1)
{
int sig;
set_sigint_trap (); /* Causes SIGINT to be passed on to the
attached process. */
pid = wait (&status);
save_errno = errno;
clear_sigint_trap ();
if (pid == -1)
{
if (save_errno == EINTR)
continue;
fprintf_unfiltered (gdb_stderr, "Child process unexpectedly missing: %s.\n",
safe_strerror (save_errno));
/* Claim it exited with unknown signal. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
return -1;
}
if (pid != PIDGET (inferior_ptid)) /* Some other process?!? */
continue;
thread = status.w_tid; /* Get thread id from status */
/* Initial thread value can only be acquired via wait, so we have to
resort to this hack. */
if (TIDGET (inferior_ptid) == 0 && thread != 0)
{
inferior_ptid = MERGEPID (PIDGET (inferior_ptid), thread);
add_thread (inferior_ptid);
}
ptid = BUILDPID (pid, thread);
/* We've become a single threaded process again. */
if (thread == 0)
inferior_ptid = ptid;
/* Check for thread creation. */
if (WIFSTOPPED (status)
&& WSTOPSIG (status) == SIGTRAP
&& !in_thread_list (ptid))
{
int realsig;
realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
(PTRACE_ARG3_TYPE) 0, 0);
if (realsig == SIGNEWTHREAD)
{
/* It's a new thread notification. We don't want to much with
realsig -- the code in wait_for_inferior expects SIGTRAP. */
ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
ourstatus->value.sig = TARGET_SIGNAL_0;
return ptid;
}
else
error ("Signal for unknown thread was not SIGNEWTHREAD");
}
/* Check for thread termination. */
else if (WIFSTOPPED (status)
&& WSTOPSIG (status) == SIGTRAP
&& in_thread_list (ptid))
{
int realsig;
realsig = ptrace (PTRACE_GETTRACESIG, PIDGET (ptid),
(PTRACE_ARG3_TYPE) 0, 0);
if (realsig == SIGTHREADEXIT)
{
ptrace (PTRACE_CONT, PIDGET (ptid), (PTRACE_ARG3_TYPE) 0, 0);
continue;
}
}
#ifdef SPARC
/* SPARC Lynx uses an byte reversed wait status; we must use the
host macros to access it. These lines just a copy of
store_waitstatus. We can't use CHILD_SPECIAL_WAITSTATUS
because target.c can't include the Lynx <sys/wait.h>. */
if (WIFEXITED (status))
{
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = WEXITSTATUS (status);
}
else if (!WIFSTOPPED (status))
{
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig =
target_signal_from_host (WTERMSIG (status));
}
else
{
ourstatus->kind = TARGET_WAITKIND_STOPPED;
ourstatus->value.sig =
target_signal_from_host (WSTOPSIG (status));
}
#else
store_waitstatus (ourstatus, status.w_status);
#endif
return ptid;
}
}
/* Return nonzero if the given thread is still alive. */
int
child_thread_alive (ptid_t ptid)
{
int pid = PIDGET (ptid);
/* Arggh. Apparently pthread_kill only works for threads within
the process that calls pthread_kill.
We want to avoid the lynx signal extensions as they simply don't
map well to the generic gdb interface we want to keep.
All we want to do is determine if a particular thread is alive;
it appears as if we can just make a harmless thread specific
ptrace call to do that. */
return (ptrace (PTRACE_THREADUSER, pid, 0, 0) != -1);
}
/* Resume execution of the inferior process.
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
void
child_resume (ptid_t ptid, int step, enum target_signal signal)
{
int func;
int pid = PIDGET (ptid);
errno = 0;
/* If pid == -1, then we want to step/continue all threads, else
we only want to step/continue a single thread. */
if (pid == -1)
{
pid = PIDGET (inferior_ptid);
func = step ? PTRACE_SINGLESTEP : PTRACE_CONT;
}
else
func = step ? PTRACE_SINGLESTEP_ONE : PTRACE_CONT_ONE;
/* An address of (PTRACE_ARG3_TYPE)1 tells ptrace to continue from where
it was. (If GDB wanted it to start some other way, we have already
written a new PC value to the child.)
If this system does not support PT_STEP, a higher level function will
have called single_step() to transmute the step request into a
continue request (by setting breakpoints on all possible successor
instructions), so we don't have to worry about that here. */
ptrace (func, pid, (PTRACE_ARG3_TYPE) 1, target_signal_to_host (signal));
if (errno)
perror_with_name ("ptrace");
}
/* Convert a Lynx process ID to a string. Returns the string in a static
buffer. */
char *
child_pid_to_str (ptid_t ptid)
{
static char buf[40];
sprintf (buf, "process %d thread %d", PIDGET (ptid), TIDGET (ptid));
return buf;
}
/* Extract the register values out of the core file and store
them where `read_register' will find them.
CORE_REG_SECT points to the register values themselves, read into memory.
CORE_REG_SIZE is the size of that area.
WHICH says which set of registers we are handling (0 = int, 2 = float
on machines where they are discontiguous).
REG_ADDR is the offset from u.u_ar0 to the register values relative to
core_reg_sect. This is used with old-fashioned core files to
locate the registers in a large upage-plus-stack ".reg" section.
Original upage address X is at location core_reg_sect+x+reg_addr.
*/
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
CORE_ADDR reg_addr)
{
struct st_entry s;
unsigned int regno;
for (regno = 0; regno < NUM_REGS; regno++)
if (regmap[regno] != -1)
supply_register (regno, core_reg_sect + offsetof (st_t, ec)
+ regmap[regno]);
#ifdef SPARC
/* Fetching this register causes all of the I & L regs to be read from the
stack and validated. */
fetch_inferior_registers (I0_REGNUM);
#endif
}
/* Register that we are able to handle lynx core file formats.
FIXME: is this really bfd_target_unknown_flavour? */
static struct core_fns lynx_core_fns =
{
bfd_target_unknown_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_core_lynx (void)
{
add_core_fns (&lynx_core_fns);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,626 +0,0 @@
/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB,
the GNU debugger.
Copyright 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Adapted by Michael Snyder of Cygnus Support.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* This module defines communication with the Mitsubishi m32r monitor */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "symtab.h"
#include "command.h"
#include "gdbcmd.h"
#include "symfile.h" /* for generic load */
#include <time.h> /* for time_t */
#include "gdb_string.h"
#include "objfiles.h" /* for ALL_OBJFILES etc. */
#include "inferior.h" /* for write_pc() */
#include <ctype.h>
#include "regcache.h"
extern void report_transfer_performance (unsigned long, time_t, time_t);
/*
* All this stuff just to get my host computer's IP address!
*/
#include <sys/types.h>
#include <netdb.h> /* for hostent */
#include <netinet/in.h> /* for struct in_addr */
#if 1
#include <arpa/inet.h> /* for inet_ntoa */
#endif
static char *board_addr; /* user-settable IP address for M32R-EVA */
static char *server_addr; /* user-settable IP address for gdb host */
static char *download_path; /* user-settable path for SREC files */
/*
* Function: m32r_load_1 (helper function)
*/
static void
m32r_load_section (bfd *abfd, asection *s, void *obj)
{
unsigned int *data_count = obj;
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size = bfd_section_size (abfd, s);
bfd_vma section_base = bfd_section_lma (abfd, s);
unsigned int buffer, i;
*data_count += section_size;
printf_filtered ("Loading section %s, size 0x%lx lma ",
bfd_section_name (abfd, s), section_size);
print_address_numeric (section_base, 1, gdb_stdout);
printf_filtered ("\n");
gdb_flush (gdb_stdout);
monitor_printf ("%s mw\r", paddr_nz (section_base));
for (i = 0; i < section_size; i += 4)
{
QUIT;
monitor_expect (" -> ", NULL, 0);
bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
monitor_printf ("%x\n", buffer);
}
monitor_expect (" -> ", NULL, 0);
monitor_printf ("q\n");
monitor_expect_prompt (NULL, 0);
}
}
static int
m32r_load_1 (void *dummy)
{
int data_count = 0;
bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count);
return data_count;
}
/*
* Function: m32r_load (an alternate way to load)
*/
static void
m32r_load (char *filename, int from_tty)
{
bfd *abfd;
asection *s;
unsigned int i, data_count = 0;
time_t start_time, end_time; /* for timing of download */
if (filename == NULL || filename[0] == 0)
filename = get_exec_file (1);
abfd = bfd_openr (filename, 0);
if (!abfd)
error ("Unable to open file %s\n", filename);
if (bfd_check_format (abfd, bfd_object) == 0)
error ("File is not an object file\n");
start_time = time (NULL);
#if 0
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size = bfd_section_size (abfd, s);
bfd_vma section_base = bfd_section_vma (abfd, s);
unsigned int buffer;
data_count += section_size;
printf_filtered ("Loading section %s, size 0x%lx vma ",
bfd_section_name (abfd, s), section_size);
print_address_numeric (section_base, 1, gdb_stdout);
printf_filtered ("\n");
gdb_flush (gdb_stdout);
monitor_printf ("%x mw\r", section_base);
for (i = 0; i < section_size; i += 4)
{
monitor_expect (" -> ", NULL, 0);
bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4);
monitor_printf ("%x\n", buffer);
}
monitor_expect (" -> ", NULL, 0);
monitor_printf ("q\n");
monitor_expect_prompt (NULL, 0);
}
#else
if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL)))
{
monitor_printf ("q\n");
return;
}
#endif
end_time = time (NULL);
printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
report_transfer_performance (data_count, start_time, end_time);
/* Finally, make the PC point at the start address */
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
inferior_ptid = null_ptid; /* No process now */
/* This is necessary because many things were based on the PC at the
time that we attached to the monitor, which is no longer valid
now that we have loaded new code (and just changed the PC).
Another way to do this might be to call normal_stop, except that
the stack may not be valid, and things would get horribly
confused... */
clear_symtab_users ();
}
static void
m32r_load_gen (char *filename, int from_tty)
{
generic_load (filename, from_tty);
}
static void m32r_open (char *args, int from_tty);
static void mon2000_open (char *args, int from_tty);
/* This array of registers needs to match the indexes used by GDB. The
whole reason this exists is because the various ROM monitors use
different names than GDB does, and don't support all the registers
either. So, typing "info reg sp" becomes an "A7". */
static char *m32r_regnames[] =
{"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch",
};
static void
m32r_supply_register (char *regname, int regnamelen, char *val, int vallen)
{
int regno;
int num_regs = sizeof (m32r_regnames) / sizeof (m32r_regnames[0]);
for (regno = 0; regno < num_regs; regno++)
if (strncmp (regname, m32r_regnames[regno], regnamelen) == 0)
break;
if (regno >= num_regs)
return; /* no match */
if (regno == ACCL_REGNUM)
{ /* special handling for 64-bit acc reg */
monitor_supply_register (ACCH_REGNUM, val);
val = strchr (val, ':'); /* skip past ':' to get 2nd word */
if (val != NULL)
monitor_supply_register (ACCL_REGNUM, val + 1);
}
else
{
monitor_supply_register (regno, val);
if (regno == PSW_REGNUM)
{
unsigned long psw = strtoul (val, NULL, 16);
char *zero = "00000000", *one = "00000001";
#ifdef SM_REGNUM
/* Stack mode bit */
monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero);
#endif
#ifdef BSM_REGNUM
/* Backup stack mode bit */
monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero);
#endif
#ifdef IE_REGNUM
/* Interrupt enable bit */
monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero);
#endif
#ifdef BIE_REGNUM
/* Backup interrupt enable bit */
monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero);
#endif
#ifdef COND_REGNUM
/* Condition bit (carry etc.) */
monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero);
#endif
#ifdef CBR_REGNUM
monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero);
#endif
#ifdef BPC_REGNUM
monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */
#endif
#ifdef BCARRY_REGNUM
monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */
#endif
}
if (regno == SPI_REGNUM || regno == SPU_REGNUM)
{ /* special handling for stack pointer (spu or spi) */
unsigned long stackmode = read_register (PSW_REGNUM) & 0x80;
if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */
monitor_supply_register (SP_REGNUM, val);
else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */
monitor_supply_register (SP_REGNUM, val);
}
}
}
/* m32r RevC board monitor */
static struct target_ops m32r_ops;
static char *m32r_inits[] =
{"\r", NULL};
static struct monitor_ops m32r_cmds;
static void
init_m32r_cmds (void)
{
m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
m32r_cmds.init = m32r_inits; /* Init strings */
m32r_cmds.cont = "go\r"; /* continue command */
m32r_cmds.step = "step\r"; /* single step */
m32r_cmds.stop = NULL; /* interrupt command */
m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */
m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */
m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
m32r_cmds.setmem.term = NULL; /* setmem.term */
m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
m32r_cmds.getmem.term = NULL; /* getmem.term */
m32r_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
m32r_cmds.setreg.term = NULL; /* setreg.term */
m32r_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
m32r_cmds.getreg.term = NULL; /* getreg.term */
m32r_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */
m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
m32r_cmds.supply_register = m32r_supply_register; /* supply_register */
m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
m32r_cmds.load = NULL; /* download command */
m32r_cmds.loadresp = NULL; /* load response */
m32r_cmds.prompt = "ok "; /* monitor command prompt */
m32r_cmds.line_term = "\r"; /* end-of-line terminator */
m32r_cmds.cmd_end = NULL; /* optional command terminator */
m32r_cmds.target = &m32r_ops; /* target operations */
m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
m32r_cmds.regnames = m32r_regnames; /* registers names */
m32r_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
} /* init_m32r_cmds */
static void
m32r_open (char *args, int from_tty)
{
monitor_open (args, &m32r_cmds, from_tty);
}
/* Mon2000 monitor (MSA2000 board) */
static struct target_ops mon2000_ops;
static struct monitor_ops mon2000_cmds;
static void
init_mon2000_cmds (void)
{
mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST;
mon2000_cmds.init = m32r_inits; /* Init strings */
mon2000_cmds.cont = "go\r"; /* continue command */
mon2000_cmds.step = "step\r"; /* single step */
mon2000_cmds.stop = NULL; /* interrupt command */
mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */
mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */
mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */
mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */
mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */
mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r"; /* setmem.cmdw (addr, value) */
mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r"; /* setmem.cmdl (addr, value) */
mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
mon2000_cmds.setmem.term = NULL; /* setmem.term */
mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */
mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
mon2000_cmds.getmem.term = NULL; /* getmem.term */
mon2000_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */
mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
mon2000_cmds.setreg.term = NULL; /* setreg.term */
mon2000_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */
mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */
mon2000_cmds.getreg.term = NULL; /* getreg.term */
mon2000_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */
mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */
mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */
mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
mon2000_cmds.load = NULL; /* download command */
mon2000_cmds.loadresp = NULL; /* load response */
mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */
mon2000_cmds.line_term = "\r"; /* end-of-line terminator */
mon2000_cmds.cmd_end = NULL; /* optional command terminator */
mon2000_cmds.target = &mon2000_ops; /* target operations */
mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
mon2000_cmds.regnames = m32r_regnames; /* registers names */
mon2000_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
} /* init_mon2000_cmds */
static void
mon2000_open (char *args, int from_tty)
{
monitor_open (args, &mon2000_cmds, from_tty);
}
/* Function: set_board_address
Tell the BootOne monitor what it's ethernet IP address is. */
static void
m32r_set_board_address (char *args, int from_tty)
{
int resp_len;
char buf[1024];
if (args && *args)
{
monitor_printf ("ulip %s\n", args);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
/* now parse the result for success */
}
else
error ("Requires argument (IP address for M32R-EVA board)");
}
/* Function: set_server_address
Tell the BootOne monitor what gdb's ethernet IP address is. */
static void
m32r_set_server_address (char *args, int from_tty)
{
int resp_len;
char buf[1024];
if (args && *args)
{
monitor_printf ("uhip %s\n", args);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
/* now parse the result for success */
}
else
error ("Requires argument (IP address of GDB's host computer)");
}
/* Function: set_download_path
Tell the BootOne monitor the default path for downloadable SREC files. */
static void
m32r_set_download_path (char *args, int from_tty)
{
int resp_len;
char buf[1024];
if (args && *args)
{
monitor_printf ("up %s\n", args);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
/* now parse the result for success */
}
else
error ("Requires argument (default path for downloadable SREC files)");
}
static void
m32r_upload_command (char *args, int from_tty)
{
bfd *abfd;
asection *s;
time_t start_time, end_time; /* for timing of download */
int resp_len, data_count = 0;
char buf[1024];
struct hostent *hostent;
struct in_addr inet_addr;
/* first check to see if there's an ethernet port! */
monitor_printf ("ust\r");
resp_len = monitor_expect_prompt (buf, sizeof (buf));
if (!strchr (buf, ':'))
error ("No ethernet connection!");
if (board_addr == 0)
{
/* scan second colon in the output from the "ust" command */
char *myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1;
while (isspace (*myIPaddress))
myIPaddress++;
if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */
error ("Please use 'set board-address' to set the M32R-EVA board's IP address.");
if (strchr (myIPaddress, '('))
*(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */
board_addr = xstrdup (myIPaddress);
}
if (server_addr == 0)
{
buf[0] = 0;
gethostname (buf, sizeof (buf));
if (buf[0] != 0)
hostent = gethostbyname (buf);
if (hostent != 0)
{
#if 1
memcpy (&inet_addr.s_addr, hostent->h_addr,
sizeof (inet_addr.s_addr));
server_addr = (char *) inet_ntoa (inet_addr);
#else
server_addr = (char *) inet_ntoa (hostent->h_addr);
#endif
}
if (server_addr == 0) /* failed? */
error ("Need to know gdb host computer's IP address (use 'set server-address')");
}
if (args == 0 || args[0] == 0) /* no args: upload the current file */
args = get_exec_file (1);
if (args[0] != '/' && download_path == 0)
{
if (current_directory)
download_path = xstrdup (current_directory);
else
error ("Need to know default download path (use 'set download-path')");
}
start_time = time (NULL);
monitor_printf ("uhip %s\r", server_addr);
resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
monitor_printf ("ulip %s\r", board_addr);
resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
if (args[0] != '/')
monitor_printf ("up %s\r", download_path); /* use default path */
else
monitor_printf ("up\r"); /* rooted filename/path */
resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec"))
monitor_printf ("ul %s\r", args);
else /* add ".srec" suffix */
monitor_printf ("ul %s.srec\r", args);
resp_len = monitor_expect_prompt (buf, sizeof (buf)); /* parse result? */
if (buf[0] == 0 || strstr (buf, "complete") == 0)
error ("Upload file not found: %s.srec\nCheck IP addresses and download path.", args);
else
printf_filtered (" -- Ethernet load complete.\n");
end_time = time (NULL);
abfd = bfd_openr (args, 0);
if (abfd != NULL)
{ /* Download is done -- print section statistics */
if (bfd_check_format (abfd, bfd_object) == 0)
{
printf_filtered ("File is not an object file\n");
}
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size = bfd_section_size (abfd, s);
bfd_vma section_base = bfd_section_lma (abfd, s);
unsigned int buffer;
data_count += section_size;
printf_filtered ("Loading section %s, size 0x%lx lma ",
bfd_section_name (abfd, s), section_size);
print_address_numeric (section_base, 1, gdb_stdout);
printf_filtered ("\n");
gdb_flush (gdb_stdout);
}
/* Finally, make the PC point at the start address */
write_pc (bfd_get_start_address (abfd));
report_transfer_performance (data_count, start_time, end_time);
printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd));
}
inferior_ptid = null_ptid; /* No process now */
/* This is necessary because many things were based on the PC at the
time that we attached to the monitor, which is no longer valid
now that we have loaded new code (and just changed the PC).
Another way to do this might be to call normal_stop, except that
the stack may not be valid, and things would get horribly
confused... */
clear_symtab_users ();
}
void
_initialize_m32r_rom (void)
{
/* Initialize m32r RevC monitor target */
init_m32r_cmds ();
init_monitor_ops (&m32r_ops);
m32r_ops.to_shortname = "m32r";
m32r_ops.to_longname = "m32r monitor";
m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
m32r_ops.to_doc = "Debug via the m32r monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
m32r_ops.to_open = m32r_open;
add_target (&m32r_ops);
/* Initialize mon2000 monitor target */
init_mon2000_cmds ();
init_monitor_ops (&mon2000_ops);
mon2000_ops.to_shortname = "mon2000";
mon2000_ops.to_longname = "Mon2000 monitor";
mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */
mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
mon2000_ops.to_open = mon2000_open;
add_target (&mon2000_ops);
add_show_from_set
(add_set_cmd ("download-path", class_obscure, var_string,
(char *) &download_path,
"Set the default path for downloadable SREC files.",
&setlist),
&showlist);
add_show_from_set
(add_set_cmd ("board-address", class_obscure, var_string,
(char *) &board_addr,
"Set IP address for M32R-EVA target board.",
&setlist),
&showlist);
add_show_from_set
(add_set_cmd ("server-address", class_obscure, var_string,
(char *) &server_addr,
"Set IP address for download server (GDB's host computer).",
&setlist),
&showlist);
add_com ("upload", class_obscure, m32r_upload_command,
"Upload the srec file via the monitor's Ethernet upload capability.");
add_com ("tload", class_obscure, m32r_load, "test upload command.");
}

File diff suppressed because it is too large Load Diff

View File

@ -1,705 +0,0 @@
/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger.
Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "obstack.h"
#include "target.h"
#include "value.h"
#include "bfd.h"
#include "gdb_string.h"
#include "gdbcore.h"
#include "symfile.h"
#include "regcache.h"
/* Function: m32r_use_struct_convention
Return nonzero if call_function should allocate stack space for a
struct return? */
int
m32r_use_struct_convention (int gcc_p, struct type *type)
{
return (TYPE_LENGTH (type) > 8);
}
/* Function: frame_find_saved_regs
Return the frame_saved_regs structure for the frame.
Doesn't really work for dummy frames, but it does pass back
an empty frame_saved_regs, so I guess that's better than total failure */
void
m32r_frame_find_saved_regs (struct frame_info *fi,
struct frame_saved_regs *regaddr)
{
memcpy (regaddr, &fi->fsr, sizeof (struct frame_saved_regs));
}
/* Turn this on if you want to see just how much instruction decoding
if being done, its quite a lot
*/
#if 0
static void
dump_insn (char *commnt, CORE_ADDR pc, int insn)
{
printf_filtered (" %s %08x %08x ",
commnt, (unsigned int) pc, (unsigned int) insn);
TARGET_PRINT_INSN (pc, &tm_print_insn_info);
printf_filtered ("\n");
}
#define insn_debug(args) { printf_filtered args; }
#else
#define dump_insn(a,b,c) {}
#define insn_debug(args) {}
#endif
#define DEFAULT_SEARCH_LIMIT 44
/* Function: scan_prologue
This function decodes the target function prologue to determine
1) the size of the stack frame, and 2) which registers are saved on it.
It saves the offsets of saved regs in the frame_saved_regs argument,
and returns the frame size. */
/*
The sequence it currently generates is:
if (varargs function) { ddi sp,#n }
push registers
if (additional stack <= 256) { addi sp,#-stack }
else if (additional stack < 65k) { add3 sp,sp,#-stack
} else if (additional stack) {
seth sp,#(stack & 0xffff0000)
or3 sp,sp,#(stack & 0x0000ffff)
sub sp,r4
}
if (frame pointer) {
mv sp,fp
}
These instructions are scheduled like everything else, so you should stop at
the first branch instruction.
*/
/* This is required by skip prologue and by m32r_init_extra_frame_info.
The results of decoding a prologue should be cached because this
thrashing is getting nuts.
I am thinking of making a container class with two indexes, name and
address. It may be better to extend the symbol table.
*/
static void
decode_prologue (CORE_ADDR start_pc, CORE_ADDR scan_limit, CORE_ADDR *pl_endptr, /* var parameter */
unsigned long *framelength, struct frame_info *fi,
struct frame_saved_regs *fsr)
{
unsigned long framesize;
int insn;
int op1;
int maybe_one_more = 0;
CORE_ADDR after_prologue = 0;
CORE_ADDR after_stack_adjust = 0;
CORE_ADDR current_pc;
framesize = 0;
after_prologue = 0;
insn_debug (("rd prolog l(%d)\n", scan_limit - current_pc));
for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2)
{
insn = read_memory_unsigned_integer (current_pc, 2);
dump_insn ("insn-1", current_pc, insn); /* MTZ */
/* If this is a 32 bit instruction, we dont want to examine its
immediate data as though it were an instruction */
if (current_pc & 0x02)
{ /* Clear the parallel execution bit from 16 bit instruction */
if (maybe_one_more)
{ /* The last instruction was a branch, usually terminates
the series, but if this is a parallel instruction,
it may be a stack framing instruction */
if (!(insn & 0x8000))
{
insn_debug (("Really done"));
break; /* nope, we are really done */
}
}
insn &= 0x7fff; /* decode this instruction further */
}
else
{
if (maybe_one_more)
break; /* This isnt the one more */
if (insn & 0x8000)
{
insn_debug (("32 bit insn\n"));
if (current_pc == scan_limit)
scan_limit += 2; /* extend the search */
current_pc += 2; /* skip the immediate data */
if (insn == 0x8faf) /* add3 sp, sp, xxxx */
/* add 16 bit sign-extended offset */
{
insn_debug (("stack increment\n"));
framesize += -((short) read_memory_unsigned_integer (current_pc, 2));
}
else
{
if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */
read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24)
{ /* subtract 24 bit sign-extended negative-offset */
dump_insn ("insn-2", current_pc + 2, insn);
insn = read_memory_unsigned_integer (current_pc - 2, 4);
dump_insn ("insn-3(l4)", current_pc - 2, insn);
if (insn & 0x00800000) /* sign extend */
insn |= 0xff000000; /* negative */
else
insn &= 0x00ffffff; /* positive */
framesize += insn;
}
}
after_prologue = current_pc;
continue;
}
}
op1 = insn & 0xf000; /* isolate just the first nibble */
if ((insn & 0xf0ff) == 0x207f)
{ /* st reg, @-sp */
int regno;
insn_debug (("push\n"));
#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */
if (((insn & 0xffff) == 0x2d7f) && fi)
fi->using_frame_pointer = 1;
#endif
framesize += 4;
#if 0
/* Why should we increase the scan limit, just because we did a push?
And if there is a reason, surely we would only want to do it if we
had already reached the scan limit... */
if (current_pc == scan_limit)
scan_limit += 2;
#endif
regno = ((insn >> 8) & 0xf);
if (fsr) /* save_regs offset */
fsr->regs[regno] = framesize;
after_prologue = 0;
continue;
}
if ((insn >> 8) == 0x4f) /* addi sp, xx */
/* add 8 bit sign-extended offset */
{
int stack_adjust = (char) (insn & 0xff);
/* there are probably two of these stack adjustments:
1) A negative one in the prologue, and
2) A positive one in the epilogue.
We are only interested in the first one. */
if (stack_adjust < 0)
{
framesize -= stack_adjust;
after_prologue = 0;
/* A frameless function may have no "mv fp, sp".
In that case, this is the end of the prologue. */
after_stack_adjust = current_pc + 2;
}
continue;
}
if (insn == 0x1d8f)
{ /* mv fp, sp */
if (fi)
fi->using_frame_pointer = 1; /* fp is now valid */
insn_debug (("done fp found\n"));
after_prologue = current_pc + 2;
break; /* end of stack adjustments */
}
if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */
{
insn_debug (("nop\n"));
after_prologue = current_pc + 2;
continue; /* nop occurs between pushes */
}
/* End of prolog if any of these are branch instructions */
if ((op1 == 0x7000)
|| (op1 == 0xb000)
|| (op1 == 0xf000))
{
after_prologue = current_pc;
insn_debug (("Done: branch\n"));
maybe_one_more = 1;
continue;
}
/* Some of the branch instructions are mixed with other types */
if (op1 == 0x1000)
{
int subop = insn & 0x0ff0;
if ((subop == 0x0ec0) || (subop == 0x0fc0))
{
insn_debug (("done: jmp\n"));
after_prologue = current_pc;
maybe_one_more = 1;
continue; /* jmp , jl */
}
}
}
if (current_pc >= scan_limit)
{
if (pl_endptr)
{
#if 1
if (after_stack_adjust != 0)
/* We did not find a "mv fp,sp", but we DID find
a stack_adjust. Is it safe to use that as the
end of the prologue? I just don't know. */
{
*pl_endptr = after_stack_adjust;
if (framelength)
*framelength = framesize;
}
else
#endif
/* We reached the end of the loop without finding the end
of the prologue. No way to win -- we should report failure.
The way we do that is to return the original start_pc.
GDB will set a breakpoint at the start of the function (etc.) */
*pl_endptr = start_pc;
}
return;
}
if (after_prologue == 0)
after_prologue = current_pc;
insn_debug ((" framesize %d, firstline %08x\n", framesize, after_prologue));
if (framelength)
*framelength = framesize;
if (pl_endptr)
*pl_endptr = after_prologue;
} /* decode_prologue */
/* Function: skip_prologue
Find end of function prologue */
CORE_ADDR
m32r_skip_prologue (CORE_ADDR pc)
{
CORE_ADDR func_addr, func_end;
struct symtab_and_line sal;
/* See what the symbol table says */
if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
{
sal = find_pc_line (func_addr, 0);
if (sal.line != 0 && sal.end <= func_end)
{
insn_debug (("BP after prologue %08x\n", sal.end));
func_end = sal.end;
}
else
/* Either there's no line info, or the line after the prologue is after
the end of the function. In this case, there probably isn't a
prologue. */
{
insn_debug (("No line info, line(%x) sal_end(%x) funcend(%x)\n",
sal.line, sal.end, func_end));
func_end = min (func_end, func_addr + DEFAULT_SEARCH_LIMIT);
}
}
else
func_end = pc + DEFAULT_SEARCH_LIMIT;
decode_prologue (pc, func_end, &sal.end, 0, 0, 0);
return sal.end;
}
static unsigned long
m32r_scan_prologue (struct frame_info *fi, struct frame_saved_regs *fsr)
{
struct symtab_and_line sal;
CORE_ADDR prologue_start, prologue_end, current_pc;
unsigned long framesize = 0;
/* this code essentially duplicates skip_prologue,
but we need the start address below. */
if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end))
{
sal = find_pc_line (prologue_start, 0);
if (sal.line == 0) /* no line info, use current PC */
if (prologue_start == entry_point_address ())
return 0;
}
else
{
prologue_start = fi->pc;
prologue_end = prologue_start + 48; /* We're in the boondocks:
allow for 16 pushes, an add,
and "mv fp,sp" */
}
#if 0
prologue_end = min (prologue_end, fi->pc);
#endif
insn_debug (("fipc(%08x) start(%08x) end(%08x)\n",
fi->pc, prologue_start, prologue_end));
prologue_end = min (prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT);
decode_prologue (prologue_start, prologue_end, &prologue_end, &framesize,
fi, fsr);
return framesize;
}
/* Function: init_extra_frame_info
This function actually figures out the frame address for a given pc and
sp. This is tricky on the m32r because we sometimes don't use an explicit
frame pointer, and the previous stack pointer isn't necessarily recorded
on the stack. The only reliable way to get this info is to
examine the prologue. */
void
m32r_init_extra_frame_info (struct frame_info *fi)
{
int reg;
if (fi->next)
fi->pc = FRAME_SAVED_PC (fi->next);
memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs);
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
{
/* We need to setup fi->frame here because run_stack_dummy gets it wrong
by assuming it's always FP. */
fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM);
fi->framesize = 0;
return;
}
else
{
fi->using_frame_pointer = 0;
fi->framesize = m32r_scan_prologue (fi, &fi->fsr);
if (!fi->next)
if (fi->using_frame_pointer)
{
fi->frame = read_register (FP_REGNUM);
}
else
fi->frame = read_register (SP_REGNUM);
else
/* fi->next means this is not the innermost frame */ if (fi->using_frame_pointer)
/* we have an FP */
if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */
fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4);
for (reg = 0; reg < NUM_REGS; reg++)
if (fi->fsr.regs[reg] != 0)
fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg];
}
}
/* Function: m32r_virtual_frame_pointer
Return the register that the function uses for a frame pointer,
plus any necessary offset to be applied to the register before
any frame pointer offsets. */
void
m32r_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset)
{
struct frame_info fi;
/* Set up a dummy frame_info. */
fi.next = NULL;
fi.prev = NULL;
fi.frame = 0;
fi.pc = pc;
/* Analyze the prolog and fill in the extra info. */
m32r_init_extra_frame_info (&fi);
/* Results will tell us which type of frame it uses. */
if (fi.using_frame_pointer)
{
*reg = FP_REGNUM;
*offset = 0;
}
else
{
*reg = SP_REGNUM;
*offset = 0;
}
}
/* Function: find_callers_reg
Find REGNUM on the stack. Otherwise, it's in an active register. One thing
we might want to do here is to check REGNUM against the clobber mask, and
somehow flag it as invalid if it isn't saved on the stack somewhere. This
would provide a graceful failure mode when trying to get the value of
caller-saves registers for an inner frame. */
CORE_ADDR
m32r_find_callers_reg (struct frame_info *fi, int regnum)
{
for (; fi; fi = fi->next)
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
return generic_read_register_dummy (fi->pc, fi->frame, regnum);
else if (fi->fsr.regs[regnum] != 0)
return read_memory_integer (fi->fsr.regs[regnum],
REGISTER_RAW_SIZE (regnum));
return read_register (regnum);
}
/* Function: frame_chain
Given a GDB frame, determine the address of the calling function's frame.
This will be used to create a new GDB frame struct, and then
INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
For m32r, we save the frame size when we initialize the frame_info. */
CORE_ADDR
m32r_frame_chain (struct frame_info *fi)
{
CORE_ADDR fn_start, callers_pc, fp;
/* is this a dummy frame? */
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
return fi->frame; /* dummy frame same as caller's frame */
/* is caller-of-this a dummy frame? */
callers_pc = FRAME_SAVED_PC (fi); /* find out who called us: */
fp = m32r_find_callers_reg (fi, FP_REGNUM);
if (PC_IN_CALL_DUMMY (callers_pc, fp, fp))
return fp; /* dummy frame's frame may bear no relation to ours */
if (find_pc_partial_function (fi->pc, 0, &fn_start, 0))
if (fn_start == entry_point_address ())
return 0; /* in _start fn, don't chain further */
if (fi->framesize == 0)
{
printf_filtered ("cannot determine frame size @ %s , pc(%s)\n",
paddr (fi->frame),
paddr (fi->pc));
return 0;
}
insn_debug (("m32rx frame %08x\n", fi->frame + fi->framesize));
return fi->frame + fi->framesize;
}
/* Function: push_return_address (pc)
Set up the return address for the inferior function call.
Necessary for targets that don't actually execute a JSR/BSR instruction
(ie. when using an empty CALL_DUMMY) */
CORE_ADDR
m32r_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
{
write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ());
return sp;
}
/* Function: pop_frame
Discard from the stack the innermost frame,
restoring all saved registers. */
struct frame_info *
m32r_pop_frame (struct frame_info *frame)
{
int regnum;
if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
generic_pop_dummy_frame ();
else
{
for (regnum = 0; regnum < NUM_REGS; regnum++)
if (frame->fsr.regs[regnum] != 0)
write_register (regnum,
read_memory_integer (frame->fsr.regs[regnum], 4));
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
write_register (SP_REGNUM, read_register (FP_REGNUM));
if (read_register (PSW_REGNUM) & 0x80)
write_register (SPU_REGNUM, read_register (SP_REGNUM));
else
write_register (SPI_REGNUM, read_register (SP_REGNUM));
}
flush_cached_frames ();
return NULL;
}
/* Function: frame_saved_pc
Find the caller of this frame. We do this by seeing if RP_REGNUM is saved
in the stack anywhere, otherwise we get it from the registers. */
CORE_ADDR
m32r_frame_saved_pc (struct frame_info *fi)
{
if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
return generic_read_register_dummy (fi->pc, fi->frame, PC_REGNUM);
else
return m32r_find_callers_reg (fi, RP_REGNUM);
}
/* Function: push_arguments
Setup the function arguments for calling a function in the inferior.
On the Mitsubishi M32R architecture, there are four registers (R0 to R3)
which are dedicated for passing function arguments. Up to the first
four arguments (depending on size) may go into these registers.
The rest go on the stack.
Arguments that are smaller than 4 bytes will still take up a whole
register or a whole 32-bit word on the stack, and will be
right-justified in the register or the stack word. This includes
chars, shorts, and small aggregate types.
Arguments of 8 bytes size are split between two registers, if
available. If only one register is available, the argument will
be split between the register and the stack. Otherwise it is
passed entirely on the stack. Aggregate types with sizes between
4 and 8 bytes are passed entirely on the stack, and are left-justified
within the double-word (as opposed to aggregates smaller than 4 bytes
which are right-justified).
Aggregates of greater than 8 bytes are first copied onto the stack,
and then a pointer to the copy is passed in the place of the normal
argument (either in a register if available, or on the stack).
Functions that must return an aggregate type can return it in the
normal return value registers (R0 and R1) if its size is 8 bytes or
less. For larger return values, the caller must allocate space for
the callee to copy the return value to. A pointer to this space is
passed as an implicit first argument, always in R0. */
CORE_ADDR
m32r_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
unsigned char struct_return, CORE_ADDR struct_addr)
{
int stack_offset, stack_alloc;
int argreg;
int argnum;
struct type *type;
CORE_ADDR regval;
char *val;
char valbuf[4];
int len;
int odd_sized_struct;
/* first force sp to a 4-byte alignment */
sp = sp & ~3;
argreg = ARG0_REGNUM;
/* The "struct return pointer" pseudo-argument goes in R0 */
if (struct_return)
write_register (argreg++, struct_addr);
/* Now make sure there's space on the stack */
for (argnum = 0, stack_alloc = 0;
argnum < nargs; argnum++)
stack_alloc += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 3) & ~3);
sp -= stack_alloc; /* make room on stack for args */
/* Now load as many as possible of the first arguments into
registers, and push the rest onto the stack. There are 16 bytes
in four registers available. Loop thru args from first to last. */
argreg = ARG0_REGNUM;
for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++)
{
type = VALUE_TYPE (args[argnum]);
len = TYPE_LENGTH (type);
memset (valbuf, 0, sizeof (valbuf));
if (len < 4)
{ /* value gets right-justified in the register or stack word */
memcpy (valbuf + (4 - len),
(char *) VALUE_CONTENTS (args[argnum]), len);
val = valbuf;
}
else
val = (char *) VALUE_CONTENTS (args[argnum]);
if (len > 4 && (len & 3) != 0)
odd_sized_struct = 1; /* such structs go entirely on stack */
else
odd_sized_struct = 0;
while (len > 0)
{
if (argreg > ARGLAST_REGNUM || odd_sized_struct)
{ /* must go on the stack */
write_memory (sp + stack_offset, val, 4);
stack_offset += 4;
}
/* NOTE WELL!!!!! This is not an "else if" clause!!!
That's because some *&^%$ things get passed on the stack
AND in the registers! */
if (argreg <= ARGLAST_REGNUM)
{ /* there's room in a register */
regval = extract_address (val, REGISTER_RAW_SIZE (argreg));
write_register (argreg++, regval);
}
/* Store the value 4 bytes at a time. This means that things
larger than 4 bytes may go partly in registers and partly
on the stack. */
len -= REGISTER_RAW_SIZE (argreg);
val += REGISTER_RAW_SIZE (argreg);
}
}
return sp;
}
/* Function: fix_call_dummy
If there is real CALL_DUMMY code (eg. on the stack), this function
has the responsability to insert the address of the actual code that
is the target of the target function call. */
void
m32r_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
struct value **args, struct type *type, int gcc_p)
{
/* ld24 r8, <(imm24) fun> */
*(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000;
}
/* Function: m32r_write_sp
Because SP is really a read-only register that mirrors either SPU or SPI,
we must actually write one of those two as well, depending on PSW. */
void
m32r_write_sp (CORE_ADDR val)
{
unsigned long psw = read_register (PSW_REGNUM);
if (psw & 0x80) /* stack mode: user or interrupt */
write_register (SPU_REGNUM, val);
else
write_register (SPI_REGNUM, val);
write_register (SP_REGNUM, val);
}
void
_initialize_m32r_tdep (void)
{
tm_print_insn = print_insn_m32r;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,685 +0,0 @@
/* Target dependent code for the Motorola 68000 series.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "symtab.h"
#include "gdbcore.h"
#include "value.h"
#include "gdb_string.h"
#include "inferior.h"
#include "regcache.h"
#define P_LINKL_FP 0x480e
#define P_LINKW_FP 0x4e56
#define P_PEA_FP 0x4856
#define P_MOVL_SP_FP 0x2c4f
#define P_MOVL 0x207c
#define P_JSR 0x4eb9
#define P_BSR 0x61ff
#define P_LEAL 0x43fb
#define P_MOVML 0x48ef
#define P_FMOVM 0xf237
#define P_TRAP 0x4e40
/* The only reason this is here is the tm-altos.h reference below. It
was moved back here from tm-m68k.h. FIXME? */
extern CORE_ADDR
altos_skip_prologue (CORE_ADDR pc)
{
register int op = read_memory_integer (pc, 2);
if (op == P_LINKW_FP)
pc += 4; /* Skip link #word */
else if (op == P_LINKL_FP)
pc += 6; /* Skip link #long */
/* Not sure why branches are here. */
/* From tm-altos.h */
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 */
return pc;
}
int
delta68_in_sigtramp (CORE_ADDR pc, char *name)
{
if (name != NULL)
return strcmp (name, "_sigcode") == 0;
else
return 0;
}
CORE_ADDR
delta68_frame_args_address (struct frame_info *frame_info)
{
/* we assume here that the only frameless functions are the system calls
or other functions who do not put anything on the stack. */
if (frame_info->signal_handler_caller)
return frame_info->frame + 12;
else if (frameless_look_for_prologue (frame_info))
{
/* Check for an interrupted system call */
if (frame_info->next && frame_info->next->signal_handler_caller)
return frame_info->next->frame + 16;
else
return frame_info->frame + 4;
}
else
return frame_info->frame;
}
CORE_ADDR
delta68_frame_saved_pc (struct frame_info *frame_info)
{
return read_memory_integer (delta68_frame_args_address (frame_info) + 4, 4);
}
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
int
isi_frame_num_args (struct frame_info *fi)
{
int val;
CORE_ADDR pc = FRAME_SAVED_PC (fi);
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;
return val;
}
int
delta68_frame_num_args (struct frame_info *fi)
{
int val;
CORE_ADDR pc = FRAME_SAVED_PC (fi);
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;
return val;
}
int
news_frame_num_args (struct frame_info *fi)
{
int val;
CORE_ADDR pc = FRAME_SAVED_PC (fi);
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;
return val;
}
/* Push an empty stack frame, to record the current PC, etc. */
void
m68k_push_dummy_frame (void)
{
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);
/* Always save the floating-point registers, whether they exist on
this target or not. */
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. */
void
m68k_pop_frame (void)
{
register struct frame_info *frame = get_current_frame ();
register CORE_ADDR fp;
register int regnum;
struct frame_saved_regs fsr;
char raw_buffer[12];
fp = FRAME_FP (frame);
get_frame_saved_regs (frame, &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 ();
}
/* Given an ip value corresponding to the start of a function,
return the ip of the first instruction after the function
prologue. This is the generic m68k support. Machines which
require something different can override the SKIP_PROLOGUE
macro to point elsewhere.
Some instructions which typically may appear in a function
prologue include:
A link instruction, word form:
link.w %a6,&0 4e56 XXXX
A link instruction, long form:
link.l %fp,&F%1 480e XXXX XXXX
A movm instruction to preserve integer regs:
movm.l &M%1,(4,%sp) 48ef XXXX XXXX
A fmovm instruction to preserve float regs:
fmovm &FPM%1,(FPO%1,%sp) f237 XXXX XXXX XXXX XXXX
Some profiling setup code (FIXME, not recognized yet):
lea.l (.L3,%pc),%a1 43fb XXXX XXXX XXXX
bsr _mcount 61ff XXXX XXXX
*/
CORE_ADDR
m68k_skip_prologue (CORE_ADDR ip)
{
register CORE_ADDR limit;
struct symtab_and_line sal;
register int op;
/* Find out if there is a known limit for the extent of the prologue.
If so, ensure we don't go past it. If not, assume "infinity". */
sal = find_pc_line (ip, 0);
limit = (sal.end) ? sal.end : (CORE_ADDR) ~ 0;
while (ip < limit)
{
op = read_memory_integer (ip, 2);
op &= 0xFFFF;
if (op == P_LINKW_FP)
ip += 4; /* Skip link.w */
else if (op == P_PEA_FP)
ip += 2; /* Skip pea %fp */
else if (op == P_MOVL_SP_FP)
ip += 2; /* Skip move.l %sp, %fp */
else if (op == P_LINKL_FP)
ip += 6; /* Skip link.l */
else if (op == P_MOVML)
ip += 6; /* Skip movm.l */
else if (op == P_FMOVM)
ip += 10; /* Skip fmovm */
else
break; /* Found unknown code, bail out. */
}
return (ip);
}
void
m68k_find_saved_regs (struct frame_info *frame_info,
struct frame_saved_regs *saved_regs)
{
register int regnum;
register int regmask;
register CORE_ADDR next_addr;
register CORE_ADDR pc;
/* First possible address for a pc in a call dummy for this frame. */
CORE_ADDR possible_call_dummy_start =
(frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - 8 * 12;
int nextinsn;
memset (saved_regs, 0, sizeof (*saved_regs));
if ((frame_info)->pc >= possible_call_dummy_start
&& (frame_info)->pc <= (frame_info)->frame)
{
/* It is a call dummy. We could just stop now, since we know
what the call dummy saves and where. But this code proceeds
to parse the "prologue" which is part of the call dummy.
This is needlessly complex and confusing. FIXME. */
next_addr = (frame_info)->frame;
pc = possible_call_dummy_start;
}
else
{
pc = get_pc_function_start ((frame_info)->pc);
nextinsn = read_memory_integer (pc, 2);
if (P_PEA_FP == nextinsn
&& P_MOVL_SP_FP == read_memory_integer (pc + 2, 2))
{
/* pea %fp
move.l %sp, %fp */
next_addr = frame_info->frame;
pc += 4;
}
else if (P_LINKL_FP == nextinsn)
/* link.l %fp */
/* Find the address above the saved
regs using the amount of storage from the link instruction. */
{
next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 4);
pc += 6;
}
else if (P_LINKW_FP == nextinsn)
/* link.w %fp */
/* Find the address above the saved
regs using the amount of storage from the link instruction. */
{
next_addr = (frame_info)->frame + read_memory_integer (pc + 2, 2);
pc += 4;
}
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;
}
for ( ; ; )
{
nextinsn = 0xffff & read_memory_integer (pc, 2);
regmask = read_memory_integer (pc + 2, 2);
/* fmovemx to -(sp) */
if (0xf227 == nextinsn && (regmask & 0xff00) == 0xe000)
{
/* Regmask's low bit is for register fp7, the first pushed */
for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
if (regmask & 1)
saved_regs->regs[regnum] = (next_addr -= 12);
pc += 4;
}
/* fmovemx to (fp + displacement) */
else if (0171056 == nextinsn && (regmask & 0xff00) == 0xf000)
{
register CORE_ADDR addr;
addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
/* Regmask's low bit is for register fp7, the first pushed */
for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
if (regmask & 1)
{
saved_regs->regs[regnum] = addr;
addr += 12;
}
pc += 6;
}
/* moveml to (sp) */
else if (0044327 == nextinsn)
{
/* Regmask's low bit is for register 0, the first written */
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
if (regmask & 1)
{
saved_regs->regs[regnum] = next_addr;
next_addr += 4;
}
pc += 4;
}
/* moveml to (fp + displacement) */
else if (0044356 == nextinsn)
{
register CORE_ADDR addr;
addr = (frame_info)->frame + read_memory_integer (pc + 4, 2);
/* Regmask's low bit is for register 0, the first written */
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
if (regmask & 1)
{
saved_regs->regs[regnum] = addr;
addr += 4;
}
pc += 6;
}
/* moveml to -(sp) */
else if (0044347 == nextinsn)
{
/* Regmask's low bit is for register 15, the first pushed */
for (regnum = 16; --regnum >= 0; regmask >>= 1)
if (regmask & 1)
saved_regs->regs[regnum] = (next_addr -= 4);
pc += 4;
}
/* movl r,-(sp) */
else if (0x2f00 == (0xfff0 & nextinsn))
{
regnum = 0xf & nextinsn;
saved_regs->regs[regnum] = (next_addr -= 4);
pc += 2;
}
/* fmovemx to index of sp */
else if (0xf236 == nextinsn && (regmask & 0xff00) == 0xf000)
{
/* Regmask's low bit is for register fp0, the first written */
for (regnum = FP0_REGNUM + 8; --regnum >= FP0_REGNUM; regmask >>= 1)
if (regmask & 1)
{
saved_regs->regs[regnum] = next_addr;
next_addr += 12;
}
pc += 10;
}
/* clrw -(sp); movw ccr,-(sp) */
else if (0x4267 == nextinsn && 0x42e7 == regmask)
{
saved_regs->regs[PS_REGNUM] = (next_addr -= 4);
pc += 4;
}
else
break;
}
lose:;
saved_regs->regs[SP_REGNUM] = (frame_info)->frame + 8;
saved_regs->regs[FP_REGNUM] = (frame_info)->frame;
saved_regs->regs[PC_REGNUM] = (frame_info)->frame + 4;
#ifdef SIG_SP_FP_OFFSET
/* Adjust saved SP_REGNUM for fake _sigtramp frames. */
if (frame_info->signal_handler_caller && frame_info->next)
saved_regs->regs[SP_REGNUM] = frame_info->next->frame + SIG_SP_FP_OFFSET;
#endif
}
#ifdef USE_PROC_FS /* Target dependent support for /proc */
#include <sys/procfs.h>
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* The /proc interface divides the target machine's register set up into
two different sets, the general register set (gregset) and the floating
point register set (fpregset). For each set, there is an ioctl to get
the current register set and another ioctl to set the current values.
The actual structure passed through the ioctl interface is, of course,
naturally machine dependent, and is different for each set of registers.
For the m68k for example, the general register set is typically defined
by:
typedef int gregset_t[18];
#define R_D0 0
...
#define R_PS 17
and the floating point set by:
typedef struct fpregset {
int f_pcr;
int f_psr;
int f_fpiaddr;
int f_fpregs[8][3]; (8 regs, 96 bits each)
} fpregset_t;
These routines provide the packing and unpacking of gregset_t and
fpregset_t formatted data.
*/
/* Atari SVR4 has R_SR but not R_PS */
#if !defined (R_PS) && defined (R_SR)
#define R_PS R_SR
#endif
/* Given a pointer to a general register set in /proc format (gregset_t *),
unpack the register contents and supply them as gdb's idea of the current
register values. */
void
supply_gregset (gregset_t *gregsetp)
{
register int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi < R_PC; regi++)
{
supply_register (regi, (char *) (regp + regi));
}
supply_register (PS_REGNUM, (char *) (regp + R_PS));
supply_register (PC_REGNUM, (char *) (regp + R_PC));
}
void
fill_gregset (gregset_t *gregsetp, int regno)
{
register int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi < R_PC; regi++)
{
if ((regno == -1) || (regno == regi))
{
*(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
}
}
if ((regno == -1) || (regno == PS_REGNUM))
{
*(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
}
if ((regno == -1) || (regno == PC_REGNUM))
{
*(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
}
}
#if defined (FP0_REGNUM)
/* Given a pointer to a floating point register set in /proc format
(fpregset_t *), unpack the register contents and supply them as gdb's
idea of the current floating point register values. */
void
supply_fpregset (fpregset_t *fpregsetp)
{
register int regi;
char *from;
for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
{
from = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
supply_register (regi, from);
}
supply_register (FPC_REGNUM, (char *) &(fpregsetp->f_pcr));
supply_register (FPS_REGNUM, (char *) &(fpregsetp->f_psr));
supply_register (FPI_REGNUM, (char *) &(fpregsetp->f_fpiaddr));
}
/* Given a pointer to a floating point register set in /proc format
(fpregset_t *), update the register specified by REGNO from gdb's idea
of the current floating point register set. If REGNO is -1, update
them all. */
void
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
int regi;
char *to;
char *from;
for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
{
if ((regno == -1) || (regno == regi))
{
from = (char *) &registers[REGISTER_BYTE (regi)];
to = (char *) &(fpregsetp->f_fpregs[regi - FP0_REGNUM][0]);
memcpy (to, from, REGISTER_RAW_SIZE (regi));
}
}
if ((regno == -1) || (regno == FPC_REGNUM))
{
fpregsetp->f_pcr = *(int *) &registers[REGISTER_BYTE (FPC_REGNUM)];
}
if ((regno == -1) || (regno == FPS_REGNUM))
{
fpregsetp->f_psr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
}
if ((regno == -1) || (regno == FPI_REGNUM))
{
fpregsetp->f_fpiaddr = *(int *) &registers[REGISTER_BYTE (FPI_REGNUM)];
}
}
#endif /* defined (FP0_REGNUM) */
#endif /* USE_PROC_FS */
/* Figure out where the longjmp will land. Slurp the args out of the stack.
We expect the first arg to be a pointer to the jmp_buf structure from which
we extract the pc (JB_PC) that we will land at. The pc is copied into PC.
This routine returns true on success. */
/* NOTE: cagney/2000-11-08: For this function to be fully multi-arched
the macro's JB_PC and JB_ELEMENT_SIZE would need to be moved into
the ``struct gdbarch_tdep'' object and then set on a target ISA/ABI
dependant basis. */
int
m68k_get_longjmp_target (CORE_ADDR *pc)
{
#if defined (JB_PC) && defined (JB_ELEMENT_SIZE)
char *buf;
CORE_ADDR sp, jb_addr;
buf = alloca (TARGET_PTR_BIT / TARGET_CHAR_BIT);
sp = read_register (SP_REGNUM);
if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
buf,
TARGET_PTR_BIT / TARGET_CHAR_BIT))
return 0;
jb_addr = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
if (target_read_memory (jb_addr + JB_PC * JB_ELEMENT_SIZE, buf,
TARGET_PTR_BIT / TARGET_CHAR_BIT))
return 0;
*pc = extract_address (buf, TARGET_PTR_BIT / TARGET_CHAR_BIT);
return 1;
#else
internal_error (__FILE__, __LINE__,
"m68k_get_longjmp_target: not implemented");
return 0;
#endif
}
/* Immediately after a function call, return the saved pc before the frame
is setup. For sun3's, we check for the common case of being inside of a
system call, and if so, we know that Sun pushes the call # on the stack
prior to doing the trap. */
CORE_ADDR
m68k_saved_pc_after_call (struct frame_info *frame)
{
#ifdef SYSCALL_TRAP
int op;
op = read_memory_integer (frame->pc - SYSCALL_TRAP_OFFSET, 2);
if (op == SYSCALL_TRAP)
return read_memory_integer (read_register (SP_REGNUM) + 4, 4);
else
#endif /* SYSCALL_TRAP */
return read_memory_integer (read_register (SP_REGNUM), 4);
}
void
_initialize_m68k_tdep (void)
{
tm_print_insn = print_insn_m68k;
}

View File

@ -1,710 +0,0 @@
/* Motorola m68k native support for GNU/Linux.
Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation,
Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "language.h"
#include "gdbcore.h"
#include "regcache.h"
#ifdef USG
#include <sys/types.h>
#endif
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/procfs.h>
#ifdef HAVE_SYS_REG_H
#include <sys/reg.h>
#endif
#include <sys/file.h>
#include "gdb_stat.h"
#include "floatformat.h"
#include "target.h"
/* This table must line up with REGISTER_NAMES in tm-m68k.h */
static const int regmap[] =
{
PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
PT_SR, PT_PC,
/* PT_FP0, ..., PT_FP7 */
21, 24, 27, 30, 33, 36, 39, 42,
/* PT_FPCR, PT_FPSR, PT_FPIAR */
45, 46, 47
};
/* Which ptrace request retrieves which registers?
These apply to the corresponding SET requests as well. */
#define NUM_GREGS (18)
#define MAX_NUM_REGS (NUM_GREGS + 11)
int
getregs_supplies (int regno)
{
return 0 <= regno && regno < NUM_GREGS;
}
int
getfpregs_supplies (int regno)
{
return FP0_REGNUM <= regno && regno <= FPI_REGNUM;
}
/* Does the current host support the GETREGS request? */
int have_ptrace_getregs =
#ifdef HAVE_PTRACE_GETREGS
1
#else
0
#endif
;
/* BLOCKEND is the value of u.u_ar0, and points to the place where GS
is stored. */
int
m68k_linux_register_u_addr (int blockend, int regnum)
{
return (blockend + 4 * regmap[regnum]);
}
/* Fetching registers directly from the U area, one at a time. */
/* FIXME: This duplicates code from `inptrace.c'. The problem is that we
define FETCH_INFERIOR_REGISTERS since we want to use our own versions
of {fetch,store}_inferior_registers that use the GETREGS request. This
means that the code in `infptrace.c' is #ifdef'd out. But we need to
fall back on that code when GDB is running on top of a kernel that
doesn't support the GETREGS request. */
#ifndef PT_READ_U
#define PT_READ_U PTRACE_PEEKUSR
#endif
#ifndef PT_WRITE_U
#define PT_WRITE_U PTRACE_POKEUSR
#endif
/* Default the type of the ptrace transfer to int. */
#ifndef PTRACE_XFER_TYPE
#define PTRACE_XFER_TYPE int
#endif
/* Fetch one register. */
static void
fetch_register (int regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
register int i;
unsigned int offset; /* Offset of registers within the u area. */
char buf[MAX_REGISTER_RAW_SIZE];
int tid;
if (CANNOT_FETCH_REGISTER (regno))
{
memset (buf, '\0', REGISTER_RAW_SIZE (regno)); /* Supply zeroes */
supply_register (regno, buf);
return;
}
/* Overload thread id onto process id */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
*(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
sprintf (mess, "reading register %s (#%d)",
REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
supply_register (regno, buf);
}
/* Fetch register values from the inferior.
If REGNO is negative, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
old_fetch_inferior_registers (int regno)
{
if (regno >= 0)
{
fetch_register (regno);
}
else
{
for (regno = 0; regno < NUM_REGS; regno++)
{
fetch_register (regno);
}
}
}
/* Store one register. */
static void
store_register (int regno)
{
/* This isn't really an address. But ptrace thinks of it as one. */
CORE_ADDR regaddr;
char mess[128]; /* For messages */
register int i;
unsigned int offset; /* Offset of registers within the u area. */
int tid;
char *buf = alloca (MAX_REGISTER_RAW_SIZE);
if (CANNOT_STORE_REGISTER (regno))
{
return;
}
/* Overload thread id onto process id */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* no thread id, just use process id */
offset = U_REGS_OFFSET;
regaddr = register_addr (regno, offset);
/* Put the contents of regno into a local buffer */
regcache_collect (regno, buf);
/* Store the local buffer into the inferior a chunk at the time. */
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE))
{
errno = 0;
ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
*(PTRACE_XFER_TYPE *) (buf + i));
regaddr += sizeof (PTRACE_XFER_TYPE);
if (errno != 0)
{
sprintf (mess, "writing register %s (#%d)",
REGISTER_NAME (regno), regno);
perror_with_name (mess);
}
}
}
/* Store our register values back into the inferior.
If REGNO is negative, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
void
old_store_inferior_registers (int regno)
{
if (regno >= 0)
{
store_register (regno);
}
else
{
for (regno = 0; regno < NUM_REGS; regno++)
{
store_register (regno);
}
}
}
/* Given a pointer to a general register set in /proc format
(elf_gregset_t *), unpack the register contents and supply
them as gdb's idea of the current register values. */
/* Note both m68k-tdep.c and m68klinux-nat.c contain definitions
for supply_gregset and supply_fpregset. The definitions
in m68k-tdep.c are valid if USE_PROC_FS is defined. Otherwise,
the definitions in m68klinux-nat.c will be used. This is a
bit of a hack. The supply_* routines do not belong in
*_tdep.c files. But, there are several lynx ports that currently
depend on these definitions. */
#ifndef USE_PROC_FS
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
void
supply_gregset (elf_gregset_t *gregsetp)
{
elf_greg_t *regp = (elf_greg_t *) gregsetp;
int regi;
for (regi = D0_REGNUM; regi <= SP_REGNUM; regi++)
supply_register (regi, (char *) &regp[regmap[regi]]);
supply_register (PS_REGNUM, (char *) &regp[PT_SR]);
supply_register (PC_REGNUM, (char *) &regp[PT_PC]);
}
/* Fill register REGNO (if it is a general-purpose register) in
*GREGSETPS with the value in GDB's register array. If REGNO is -1,
do this for all registers. */
void
fill_gregset (elf_gregset_t *gregsetp, int regno)
{
elf_greg_t *regp = (elf_greg_t *) gregsetp;
int i;
for (i = 0; i < NUM_GREGS; i++)
if ((regno == -1 || regno == i))
regcache_collect (i, regp + regmap[i]);
}
#ifdef HAVE_PTRACE_GETREGS
/* Fetch all general-purpose registers from process/thread TID and
store their values in GDB's register array. */
static void
fetch_regs (int tid)
{
elf_gregset_t regs;
if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
{
if (errno == EIO)
{
/* The kernel we're running on doesn't support the GETREGS
request. Reset `have_ptrace_getregs'. */
have_ptrace_getregs = 0;
return;
}
perror_with_name ("Couldn't get registers");
}
supply_gregset (&regs);
}
/* Store all valid general-purpose registers in GDB's register array
into the process/thread specified by TID. */
static void
store_regs (int tid, int regno)
{
elf_gregset_t regs;
if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
perror_with_name ("Couldn't get registers");
fill_gregset (&regs, regno);
if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
perror_with_name ("Couldn't write registers");
}
#else
static void fetch_regs (int tid) {}
static void store_regs (int tid, int regno) {}
#endif
/* Transfering floating-point registers between GDB, inferiors and cores. */
/* What is the address of fpN within the floating-point register set F? */
#define FPREG_ADDR(f, n) ((char *) &(f)->fpregs[(n) * 3])
/* Fill GDB's register array with the floating-point register values in
*FPREGSETP. */
void
supply_fpregset (elf_fpregset_t *fpregsetp)
{
int regi;
for (regi = FP0_REGNUM; regi < FPC_REGNUM; regi++)
supply_register (regi, FPREG_ADDR (fpregsetp, regi - FP0_REGNUM));
supply_register (FPC_REGNUM, (char *) &fpregsetp->fpcntl[0]);
supply_register (FPS_REGNUM, (char *) &fpregsetp->fpcntl[1]);
supply_register (FPI_REGNUM, (char *) &fpregsetp->fpcntl[2]);
}
/* Fill register REGNO (if it is a floating-point register) in
*FPREGSETP with the value in GDB's register array. If REGNO is -1,
do this for all registers. */
void
fill_fpregset (elf_fpregset_t *fpregsetp, int regno)
{
int i;
/* Fill in the floating-point registers. */
for (i = FP0_REGNUM; i < FP0_REGNUM + 8; i++)
if (regno == -1 || regno == i)
regcache_collect (regno, FPREG_ADDR (fpregsetp, regno - FP0_REGNUM));
/* Fill in the floating-point control registers. */
for (i = FPC_REGNUM; i <= FPI_REGNUM; i++)
if (regno == -1 || regno == i)
regcache_collect (regno, (char *) &fpregsetp->fpcntl[regno - FPC_REGNUM]);
}
#ifdef HAVE_PTRACE_GETREGS
/* Fetch all floating-point registers from process/thread TID and store
thier values in GDB's register array. */
static void
fetch_fpregs (int tid)
{
elf_fpregset_t fpregs;
if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
perror_with_name ("Couldn't get floating point status");
supply_fpregset (&fpregs);
}
/* Store all valid floating-point registers in GDB's register array
into the process/thread specified by TID. */
static void
store_fpregs (int tid, int regno)
{
elf_fpregset_t fpregs;
if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
perror_with_name ("Couldn't get floating point status");
fill_fpregset (&fpregs, regno);
if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
perror_with_name ("Couldn't write floating point status");
}
#else
static void fetch_fpregs (int tid) {}
static void store_fpregs (int tid, int regno) {}
#endif
#endif
/* Transferring arbitrary registers between GDB and inferior. */
/* Fetch register REGNO from the child process. If REGNO is -1, do
this for all registers (including the floating point and SSE
registers). */
void
fetch_inferior_registers (int regno)
{
int tid;
/* Use the old method of peeking around in `struct user' if the
GETREGS request isn't available. */
if (! have_ptrace_getregs)
{
old_fetch_inferior_registers (regno);
return;
}
/* GNU/Linux LWP ID's are process ID's. */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
/* Use the PTRACE_GETFPXREGS request whenever possible, since it
transfers more registers in one system call, and we'll cache the
results. But remember that fetch_fpxregs can fail, and return
zero. */
if (regno == -1)
{
fetch_regs (tid);
/* The call above might reset `have_ptrace_getregs'. */
if (! have_ptrace_getregs)
{
old_fetch_inferior_registers (-1);
return;
}
fetch_fpregs (tid);
return;
}
if (getregs_supplies (regno))
{
fetch_regs (tid);
return;
}
if (getfpregs_supplies (regno))
{
fetch_fpregs (tid);
return;
}
internal_error (__FILE__, __LINE__,
"Got request for bad register number %d.", regno);
}
/* Store register REGNO back into the child process. If REGNO is -1,
do this for all registers (including the floating point and SSE
registers). */
void
store_inferior_registers (int regno)
{
int tid;
/* Use the old method of poking around in `struct user' if the
SETREGS request isn't available. */
if (! have_ptrace_getregs)
{
old_store_inferior_registers (regno);
return;
}
/* GNU/Linux LWP ID's are process ID's. */
if ((tid = TIDGET (inferior_ptid)) == 0)
tid = PIDGET (inferior_ptid); /* Not a threaded program. */
/* Use the PTRACE_SETFPREGS requests whenever possible, since it
transfers more registers in one system call. But remember that
store_fpregs can fail, and return zero. */
if (regno == -1)
{
store_regs (tid, regno);
store_fpregs (tid, regno);
return;
}
if (getregs_supplies (regno))
{
store_regs (tid, regno);
return;
}
if (getfpregs_supplies (regno))
{
store_fpregs (tid, regno);
return;
}
internal_error (__FILE__, __LINE__,
"Got request to store bad register number %d.", regno);
}
/* Interpreting register set info found in core files. */
/* Provide registers to GDB from a core file.
(We can't use the generic version of this function in
core-regset.c, because we need to use elf_gregset_t instead of
gregset_t.)
CORE_REG_SECT points to an array of bytes, which are the contents
of a `note' from a core file which BFD thinks might contain
register contents. CORE_REG_SIZE is its size.
WHICH says which register set corelow suspects this is:
0 --- the general-purpose register set, in elf_gregset_t format
2 --- the floating-point register set, in elf_fpregset_t format
REG_ADDR isn't used on GNU/Linux. */
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
int which, CORE_ADDR reg_addr)
{
elf_gregset_t gregset;
elf_fpregset_t fpregset;
switch (which)
{
case 0:
if (core_reg_size != sizeof (gregset))
warning ("Wrong size gregset in core file.");
else
{
memcpy (&gregset, core_reg_sect, sizeof (gregset));
supply_gregset (&gregset);
}
break;
case 2:
if (core_reg_size != sizeof (fpregset))
warning ("Wrong size fpregset in core file.");
else
{
memcpy (&fpregset, core_reg_sect, sizeof (fpregset));
supply_fpregset (&fpregset);
}
break;
default:
/* We've covered all the kinds of registers we know about here,
so this must be something we wouldn't know what to do with
anyway. Just ignore it. */
break;
}
}
int
kernel_u_size (void)
{
return (sizeof (struct user));
}
/* Check whether insn1 and insn2 are parts of a signal trampoline. */
#define IS_SIGTRAMP(insn1, insn2) \
(/* addaw #20,sp; moveq #119,d0; trap #0 */ \
(insn1 == 0xdefc0014 && insn2 == 0x70774e40) \
/* moveq #119,d0; trap #0 */ \
|| insn1 == 0x70774e40)
#define IS_RT_SIGTRAMP(insn1, insn2) \
(/* movel #173,d0; trap #0 */ \
(insn1 == 0x203c0000 && insn2 == 0x00ad4e40) \
/* moveq #82,d0; notb d0; trap #0 */ \
|| (insn1 == 0x70524600 && (insn2 >> 16) == 0x4e40))
/* Return non-zero if PC points into the signal trampoline. For the sake
of m68k_linux_frame_saved_pc we also distinguish between non-RT and RT
signal trampolines. */
int
m68k_linux_in_sigtramp (CORE_ADDR pc)
{
CORE_ADDR sp;
char buf[12];
unsigned long insn0, insn1, insn2;
if (read_memory_nobpt (pc - 4, buf, sizeof (buf)))
return 0;
insn1 = extract_unsigned_integer (buf + 4, 4);
insn2 = extract_unsigned_integer (buf + 8, 4);
if (IS_SIGTRAMP (insn1, insn2))
return 1;
if (IS_RT_SIGTRAMP (insn1, insn2))
return 2;
insn0 = extract_unsigned_integer (buf, 4);
if (IS_SIGTRAMP (insn0, insn1))
return 1;
if (IS_RT_SIGTRAMP (insn0, insn1))
return 2;
insn0 = (insn0 << 16) | (insn1 >> 16);
insn1 = (insn1 << 16) | (insn2 >> 16);
if (IS_SIGTRAMP (insn0, insn1))
return 1;
if (IS_RT_SIGTRAMP (insn0, insn1))
return 2;
return 0;
}
/* Offset to saved PC in sigcontext, from <asm/sigcontext.h>. */
#define SIGCONTEXT_PC_OFFSET 26
/* Offset to saved PC in ucontext, from <asm/ucontext.h>. */
#define UCONTEXT_PC_OFFSET 88
/* Get saved user PC for sigtramp from sigcontext or ucontext. */
static CORE_ADDR
m68k_linux_sigtramp_saved_pc (struct frame_info *frame)
{
CORE_ADDR sigcontext_addr;
char buf[TARGET_PTR_BIT / TARGET_CHAR_BIT];
int ptrbytes = TARGET_PTR_BIT / TARGET_CHAR_BIT;
int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
/* Get sigcontext address, it is the third parameter on the stack. */
if (frame->next)
sigcontext_addr = read_memory_integer (FRAME_ARGS_ADDRESS (frame->next)
+ FRAME_ARGS_SKIP
+ sigcontext_offs,
ptrbytes);
else
sigcontext_addr = read_memory_integer (read_register (SP_REGNUM)
+ sigcontext_offs,
ptrbytes);
/* Don't cause a memory_error when accessing sigcontext in case the
stack layout has changed or the stack is corrupt. */
if (m68k_linux_in_sigtramp (frame->pc) == 2)
target_read_memory (sigcontext_addr + UCONTEXT_PC_OFFSET, buf, ptrbytes);
else
target_read_memory (sigcontext_addr + SIGCONTEXT_PC_OFFSET, buf, ptrbytes);
return extract_unsigned_integer (buf, ptrbytes);
}
/* Return the saved program counter for FRAME. */
CORE_ADDR
m68k_linux_frame_saved_pc (struct frame_info *frame)
{
if (frame->signal_handler_caller)
return m68k_linux_sigtramp_saved_pc (frame);
return read_memory_integer (frame->frame + 4, 4);
}
/* Register that we are able to handle GNU/Linux ELF core file
formats. */
static struct core_fns linux_elf_core_fns =
{
bfd_target_elf_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_m68k_linux_nat ()
{
add_core_fns (&linux_elf_core_fns);
}

View File

@ -1,103 +0,0 @@
/* Native-dependent code for Motorola m68k's running NetBSD, for GDB.
Copyright 1988, 1989, 1991, 1992, 1994, 1996, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
void
fetch_inferior_registers (int regno)
{
struct reg inferior_registers;
struct fpreg inferior_fp_registers;
ptrace (PT_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
memcpy (&registers[REGISTER_BYTE (0)], &inferior_registers,
sizeof (inferior_registers));
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
sizeof (inferior_fp_registers));
registers_fetched ();
}
void
store_inferior_registers (int regno)
{
struct reg inferior_registers;
struct fpreg inferior_fp_registers;
memcpy (&inferior_registers, &registers[REGISTER_BYTE (0)],
sizeof (inferior_registers));
ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
sizeof (inferior_fp_registers));
ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_fp_registers, 0);
}
struct md_core
{
struct reg intreg;
struct fpreg freg;
};
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
CORE_ADDR ignore)
{
struct md_core *core_reg = (struct md_core *) core_reg_sect;
/* Integer registers */
memcpy (&registers[REGISTER_BYTE (0)],
&core_reg->intreg, sizeof (struct reg));
/* Floating point registers */
memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)],
&core_reg->freg, sizeof (struct fpreg));
}
/* Register that we are able to handle m68knbsd core file formats.
FIXME: is this really bfd_target_unknown_flavour? */
static struct core_fns m68knbsd_core_fns =
{
bfd_target_unknown_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_m68knbsd_nat (void)
{
add_core_fns (&m68knbsd_core_fns);
}

View File

@ -1,290 +0,0 @@
/* Native-dependent Motorola 88xxx support for GDB, the GNU Debugger.
Copyright 1988, 1990, 1991, 1992, 1993, 1995, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "regcache.h"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include "gdbcore.h"
#include <sys/user.h>
#ifndef USER /* added to support BCS ptrace_user */
#define USER ptrace_user
#endif
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/file.h>
#include "gdb_stat.h"
#include "symtab.h"
#include "setjmp.h"
#include "value.h"
#ifdef DELTA88
#include <sys/ptrace.h>
/* define offsets to the pc instruction offsets in ptrace_user struct */
#define SXIP_OFFSET ((char *)&u.pt_sigframe.sig_sxip - (char *)&u)
#define SNIP_OFFSET ((char *)&u.pt_sigframe.sig_snip - (char *)&u)
#define SFIP_OFFSET ((char *)&u.pt_sigframe.sig_sfip - (char *)&u)
#else
/* define offsets to the pc instruction offsets in ptrace_user struct */
#define SXIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u)
#define SNIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u)
#define SFIP_OFFSET ((char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u)
#endif
extern int have_symbol_file_p ();
extern jmp_buf stack_jmp;
extern int errno;
void
fetch_inferior_registers (int regno)
{
register unsigned int regaddr;
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
struct USER u;
unsigned int offset;
offset = (char *) &u.pt_r0 - (char *) &u;
regaddr = offset; /* byte offset to r0; */
/* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */
for (regno = 0; regno < NUM_REGS; regno++)
{
/*regaddr = register_addr (regno, offset); */
/* 88k enhancement */
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
*(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, 0);
regaddr += sizeof (int);
}
supply_register (regno, buf);
}
/* now load up registers 36 - 38; special pc registers */
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, 0);
supply_register (SXIP_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, 0);
supply_register (SNIP_REGNUM, buf);
*(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, 0);
supply_register (SFIP_REGNUM, 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). */
void
store_inferior_registers (int regno)
{
register unsigned int regaddr;
char buf[80];
struct USER u;
unsigned int offset = (char *) &u.pt_r0 - (char *) &u;
regaddr = offset;
/* Don't try to deal with EXIP_REGNUM or ENIP_REGNUM, because I think either
svr3 doesn't run on an 88110, or the kernel isolates the different (not
completely sure this is true, but seems to be. */
if (regno >= 0)
{
/* regaddr = register_addr (regno, offset); */
if (regno < PC_REGNUM)
{
regaddr = offset + regno * sizeof (int);
errno = 0;
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, read_register (regno));
if (errno != 0)
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
}
}
else if (regno == SXIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (regno));
else if (regno == SNIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (regno));
else if (regno == SFIP_REGNUM)
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (regno));
else
printf_unfiltered ("Bad register number for store_inferior routine\n");
}
else
{
for (regno = 0; regno < PC_REGNUM; regno++)
{
/* regaddr = register_addr (regno, offset); */
errno = 0;
regaddr = offset + regno * sizeof (int);
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) regaddr, read_register (regno));
if (errno != 0)
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
}
}
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SXIP_OFFSET, read_register (SXIP_REGNUM));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SNIP_OFFSET, read_register (SNIP_REGNUM));
ptrace (6, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) SFIP_OFFSET, read_register (SFIP_REGNUM));
}
}
/* blockend is the address of the end of the user structure */
m88k_register_u_addr (int blockend, int regnum)
{
struct USER u;
int ustart = blockend - sizeof (struct USER);
switch (regnum)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
return (ustart + ((int) &u.pt_r0 - (int) &u) + REGISTER_SIZE * regnum);
case PSR_REGNUM:
return (ustart + ((int) &u.pt_psr - (int) &u));
case FPSR_REGNUM:
return (ustart + ((int) &u.pt_fpsr - (int) &u));
case FPCR_REGNUM:
return (ustart + ((int) &u.pt_fpcr - (int) &u));
case SXIP_REGNUM:
return (ustart + SXIP_OFFSET);
case SNIP_REGNUM:
return (ustart + SNIP_OFFSET);
case SFIP_REGNUM:
return (ustart + SFIP_OFFSET);
default:
if (regnum < NUM_REGS)
/* The register is one of those which is not defined...
give it zero */
return (ustart + ((int) &u.pt_r0 - (int) &u));
else
return (blockend + REGISTER_SIZE * regnum);
}
}
#ifdef USE_PROC_FS
#include <sys/procfs.h>
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* Given a pointer to a general register set in /proc format (gregset_t *),
unpack the register contents and supply them as gdb's idea of the current
register values. */
void
supply_gregset (gregset_t *gregsetp)
{
register int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi <= SP_REGNUM; regi++)
supply_register (regi, (char *) (regp + regi));
supply_register (SXIP_REGNUM, (char *) (regp + R_XIP));
supply_register (SNIP_REGNUM, (char *) (regp + R_NIP));
supply_register (SFIP_REGNUM, (char *) (regp + R_FIP));
supply_register (PSR_REGNUM, (char *) (regp + R_PSR));
supply_register (FPSR_REGNUM, (char *) (regp + R_FPSR));
supply_register (FPCR_REGNUM, (char *) (regp + R_FPCR));
}
void
fill_gregset (gregset_t *gregsetp, int regno)
{
int regi;
register greg_t *regp = (greg_t *) gregsetp;
for (regi = 0; regi <= R_R31; regi++)
if ((regno == -1) || (regno == regi))
*(regp + regi) = *(int *) &registers[REGISTER_BYTE (regi)];
if ((regno == -1) || (regno == SXIP_REGNUM))
*(regp + R_XIP) = *(int *) &registers[REGISTER_BYTE (SXIP_REGNUM)];
if ((regno == -1) || (regno == SNIP_REGNUM))
*(regp + R_NIP) = *(int *) &registers[REGISTER_BYTE (SNIP_REGNUM)];
if ((regno == -1) || (regno == SFIP_REGNUM))
*(regp + R_FIP) = *(int *) &registers[REGISTER_BYTE (SFIP_REGNUM)];
if ((regno == -1) || (regno == PSR_REGNUM))
*(regp + R_PSR) = *(int *) &registers[REGISTER_BYTE (PSR_REGNUM)];
if ((regno == -1) || (regno == FPSR_REGNUM))
*(regp + R_FPSR) = *(int *) &registers[REGISTER_BYTE (FPSR_REGNUM)];
if ((regno == -1) || (regno == FPCR_REGNUM))
*(regp + R_FPCR) = *(int *) &registers[REGISTER_BYTE (FPCR_REGNUM)];
}
#endif /* USE_PROC_FS */

View File

@ -1,634 +0,0 @@
/* Target-machine dependent code for Motorola 88000 series, for GDB.
Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000,
2001 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "value.h"
#include "gdbcore.h"
#include "symtab.h"
#include "setjmp.h"
#include "value.h"
#include "regcache.h"
/* Size of an instruction */
#define BYTES_PER_88K_INSN 4
void frame_find_saved_regs ();
/* Is this target an m88110? Otherwise assume m88100. This has
relevance for the ways in which we screw with instruction pointers. */
int target_is_m88110 = 0;
/* The type of a register. */
struct type *
m88k_register_type (int regnum)
{
if (regnum >= XFP_REGNUM)
return builtin_type_m88110_ext;
else if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM)
return builtin_type_void_func_ptr;
else
return builtin_type_int32;
}
/* The m88k kernel aligns all instructions on 4-byte boundaries. The
kernel also uses the least significant two bits for its own hocus
pocus. When gdb receives an address from the kernel, it needs to
preserve those right-most two bits, but gdb also needs to be careful
to realize that those two bits are not really a part of the address
of an instruction. Shrug. */
CORE_ADDR
m88k_addr_bits_remove (CORE_ADDR addr)
{
return ((addr) & ~3);
}
/* Given a GDB frame, determine the address of the calling function's frame.
This will be used to create a new GDB frame struct, and then
INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
For us, the frame address is its stack pointer value, so we look up
the function prologue to determine the caller's sp value, and return it. */
CORE_ADDR
frame_chain (struct frame_info *thisframe)
{
frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
/* NOTE: this depends on frame_find_saved_regs returning the VALUE, not
the ADDRESS, of SP_REGNUM. It also depends on the cache of
frame_find_saved_regs results. */
if (thisframe->fsr->regs[SP_REGNUM])
return thisframe->fsr->regs[SP_REGNUM];
else
return thisframe->frame; /* Leaf fn -- next frame up has same SP. */
}
int
frameless_function_invocation (struct frame_info *frame)
{
frame_find_saved_regs (frame, (struct frame_saved_regs *) 0);
/* NOTE: this depends on frame_find_saved_regs returning the VALUE, not
the ADDRESS, of SP_REGNUM. It also depends on the cache of
frame_find_saved_regs results. */
if (frame->fsr->regs[SP_REGNUM])
return 0; /* Frameful -- return addr saved somewhere */
else
return 1; /* Frameless -- no saved return address */
}
void
init_extra_frame_info (int fromleaf, struct frame_info *frame)
{
frame->fsr = 0; /* Not yet allocated */
frame->args_pointer = 0; /* Unknown */
frame->locals_pointer = 0; /* Unknown */
}
/* Examine an m88k function prologue, recording the addresses at which
registers are saved explicitly by the prologue code, and returning
the address of the first instruction after the prologue (but not
after the instruction at address LIMIT, as explained below).
LIMIT places an upper bound on addresses of the instructions to be
examined. If the prologue code scan reaches LIMIT, the scan is
aborted and LIMIT is returned. This is used, when examining the
prologue for the current frame, to keep examine_prologue () from
claiming that a given register has been saved when in fact the
instruction that saves it has not yet been executed. LIMIT is used
at other times to stop the scan when we hit code after the true
function prologue (e.g. for the first source line) which might
otherwise be mistaken for function prologue.
The format of the function prologue matched by this routine is
derived from examination of the source to gcc 1.95, particularly
the routine output_prologue () in config/out-m88k.c.
subu r31,r31,n # stack pointer update
(st rn,r31,offset)? # save incoming regs
(st.d rn,r31,offset)?
(addu r30,r31,n)? # frame pointer update
(pic sequence)? # PIC code prologue
(or rn,rm,0)? # Move parameters to other regs
*/
/* Macros for extracting fields from instructions. */
#define BITMASK(pos, width) (((0x1 << (width)) - 1) << (pos))
#define EXTRACT_FIELD(val, pos, width) ((val) >> (pos) & BITMASK (0, width))
#define SUBU_OFFSET(x) ((unsigned)(x & 0xFFFF))
#define ST_OFFSET(x) ((unsigned)((x) & 0xFFFF))
#define ST_SRC(x) EXTRACT_FIELD ((x), 21, 5)
#define ADDU_OFFSET(x) ((unsigned)(x & 0xFFFF))
/*
* prologue_insn_tbl is a table of instructions which may comprise a
* function prologue. Associated with each table entry (corresponding
* to a single instruction or group of instructions), is an action.
* This action is used by examine_prologue (below) to determine
* the state of certain machine registers and where the stack frame lives.
*/
enum prologue_insn_action
{
PIA_SKIP, /* don't care what the instruction does */
PIA_NOTE_ST, /* note register stored and where */
PIA_NOTE_STD, /* note pair of registers stored and where */
PIA_NOTE_SP_ADJUSTMENT, /* note stack pointer adjustment */
PIA_NOTE_FP_ASSIGNMENT, /* note frame pointer assignment */
PIA_NOTE_PROLOGUE_END, /* no more prologue */
};
struct prologue_insns
{
unsigned long insn;
unsigned long mask;
enum prologue_insn_action action;
};
struct prologue_insns prologue_insn_tbl[] =
{
/* Various register move instructions */
{0x58000000, 0xf800ffff, PIA_SKIP}, /* or/or.u with immed of 0 */
{0xf4005800, 0xfc1fffe0, PIA_SKIP}, /* or rd, r0, rs */
{0xf4005800, 0xfc00ffff, PIA_SKIP}, /* or rd, rs, r0 */
/* Stack pointer setup: "subu sp, sp, n" where n is a multiple of 8 */
{0x67ff0000, 0xffff0007, PIA_NOTE_SP_ADJUSTMENT},
/* Frame pointer assignment: "addu r30, r31, n" */
{0x63df0000, 0xffff0000, PIA_NOTE_FP_ASSIGNMENT},
/* Store to stack instructions; either "st rx, sp, n" or "st.d rx, sp, n" */
{0x241f0000, 0xfc1f0000, PIA_NOTE_ST}, /* st rx, sp, n */
{0x201f0000, 0xfc1f0000, PIA_NOTE_STD}, /* st.d rs, sp, n */
/* Instructions needed for setting up r25 for pic code. */
{0x5f200000, 0xffff0000, PIA_SKIP}, /* or.u r25, r0, offset_high */
{0xcc000002, 0xffffffff, PIA_SKIP}, /* bsr.n Lab */
{0x5b390000, 0xffff0000, PIA_SKIP}, /* or r25, r25, offset_low */
{0xf7396001, 0xffffffff, PIA_SKIP}, /* Lab: addu r25, r25, r1 */
/* Various branch or jump instructions which have a delay slot -- these
do not form part of the prologue, but the instruction in the delay
slot might be a store instruction which should be noted. */
{0xc4000000, 0xe4000000, PIA_NOTE_PROLOGUE_END},
/* br.n, bsr.n, bb0.n, or bb1.n */
{0xec000000, 0xfc000000, PIA_NOTE_PROLOGUE_END}, /* bcnd.n */
{0xf400c400, 0xfffff7e0, PIA_NOTE_PROLOGUE_END} /* jmp.n or jsr.n */
};
/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
is not the address of a valid instruction, the address of the next
instruction beyond ADDR otherwise. *PWORD1 receives the first word
of the instruction. */
#define NEXT_PROLOGUE_INSN(addr, lim, pword1) \
(((addr) < (lim)) ? next_insn (addr, pword1) : 0)
/* Read the m88k instruction at 'memaddr' and return the address of
the next instruction after that, or 0 if 'memaddr' is not the
address of a valid instruction. The instruction
is stored at 'pword1'. */
CORE_ADDR
next_insn (CORE_ADDR memaddr, unsigned long *pword1)
{
*pword1 = read_memory_integer (memaddr, BYTES_PER_88K_INSN);
return memaddr + BYTES_PER_88K_INSN;
}
/* Read a register from frames called by us (or from the hardware regs). */
static int
read_next_frame_reg (struct frame_info *frame, int regno)
{
for (; frame; frame = frame->next)
{
if (regno == SP_REGNUM)
return FRAME_FP (frame);
else if (frame->fsr->regs[regno])
return read_memory_integer (frame->fsr->regs[regno], 4);
}
return read_register (regno);
}
/* Examine the prologue of a function. `ip' points to the first instruction.
`limit' is the limit of the prologue (e.g. the addr of the first
linenumber, or perhaps the program counter if we're stepping through).
`frame_sp' is the stack pointer value in use in this frame.
`fsr' is a pointer to a frame_saved_regs structure into which we put
info about the registers saved by this frame.
`fi' is a struct frame_info pointer; we fill in various fields in it
to reflect the offsets of the arg pointer and the locals pointer. */
static CORE_ADDR
examine_prologue (register CORE_ADDR ip, register CORE_ADDR limit,
CORE_ADDR frame_sp, struct frame_saved_regs *fsr,
struct frame_info *fi)
{
register CORE_ADDR next_ip;
register int src;
unsigned long insn;
int size, offset;
char must_adjust[32]; /* If set, must adjust offsets in fsr */
int sp_offset = -1; /* -1 means not set (valid must be mult of 8) */
int fp_offset = -1; /* -1 means not set */
CORE_ADDR frame_fp;
CORE_ADDR prologue_end = 0;
memset (must_adjust, '\0', sizeof (must_adjust));
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
while (next_ip)
{
struct prologue_insns *pip;
for (pip = prologue_insn_tbl; (insn & pip->mask) != pip->insn;)
if (++pip >= prologue_insn_tbl + sizeof prologue_insn_tbl)
goto end_of_prologue_found; /* not a prologue insn */
switch (pip->action)
{
case PIA_NOTE_ST:
case PIA_NOTE_STD:
if (sp_offset != -1)
{
src = ST_SRC (insn);
offset = ST_OFFSET (insn);
must_adjust[src] = 1;
fsr->regs[src++] = offset; /* Will be adjusted later */
if (pip->action == PIA_NOTE_STD && src < 32)
{
offset += 4;
must_adjust[src] = 1;
fsr->regs[src++] = offset;
}
}
else
goto end_of_prologue_found;
break;
case PIA_NOTE_SP_ADJUSTMENT:
if (sp_offset == -1)
sp_offset = -SUBU_OFFSET (insn);
else
goto end_of_prologue_found;
break;
case PIA_NOTE_FP_ASSIGNMENT:
if (fp_offset == -1)
fp_offset = ADDU_OFFSET (insn);
else
goto end_of_prologue_found;
break;
case PIA_NOTE_PROLOGUE_END:
if (!prologue_end)
prologue_end = ip;
break;
case PIA_SKIP:
default:
/* Do nothing */
break;
}
ip = next_ip;
next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn);
}
end_of_prologue_found:
if (prologue_end)
ip = prologue_end;
/* We're done with the prologue. If we don't care about the stack
frame itself, just return. (Note that fsr->regs has been trashed,
but the one caller who calls with fi==0 passes a dummy there.) */
if (fi == 0)
return ip;
/*
OK, now we have:
sp_offset original (before any alloca calls) displacement of SP
(will be negative).
fp_offset displacement from original SP to the FP for this frame
or -1.
fsr->regs[0..31] displacement from original SP to the stack
location where reg[0..31] is stored.
must_adjust[0..31] set if corresponding offset was set.
If alloca has been called between the function prologue and the current
IP, then the current SP (frame_sp) will not be the original SP as set by
the function prologue. If the current SP is not the original SP, then the
compiler will have allocated an FP for this frame, fp_offset will be set,
and we can use it to calculate the original SP.
Then, we figure out where the arguments and locals are, and relocate the
offsets in fsr->regs to absolute addresses. */
if (fp_offset != -1)
{
/* We have a frame pointer, so get it, and base our calc's on it. */
frame_fp = (CORE_ADDR) read_next_frame_reg (fi->next, ACTUAL_FP_REGNUM);
frame_sp = frame_fp - fp_offset;
}
else
{
/* We have no frame pointer, therefore frame_sp is still the same value
as set by prologue. But where is the frame itself? */
if (must_adjust[SRP_REGNUM])
{
/* Function header saved SRP (r1), the return address. Frame starts
4 bytes down from where it was saved. */
frame_fp = frame_sp + fsr->regs[SRP_REGNUM] - 4;
fi->locals_pointer = frame_fp;
}
else
{
/* Function header didn't save SRP (r1), so we are in a leaf fn or
are otherwise confused. */
frame_fp = -1;
}
}
/* The locals are relative to the FP (whether it exists as an allocated
register, or just as an assumed offset from the SP) */
fi->locals_pointer = frame_fp;
/* The arguments are just above the SP as it was before we adjusted it
on entry. */
fi->args_pointer = frame_sp - sp_offset;
/* Now that we know the SP value used by the prologue, we know where
it saved all the registers. */
for (src = 0; src < 32; src++)
if (must_adjust[src])
fsr->regs[src] += frame_sp;
/* The saved value of the SP is always known. */
/* (we hope...) */
if (fsr->regs[SP_REGNUM] != 0
&& fsr->regs[SP_REGNUM] != frame_sp - sp_offset)
fprintf_unfiltered (gdb_stderr, "Bad saved SP value %lx != %lx, offset %x!\n",
fsr->regs[SP_REGNUM],
frame_sp - sp_offset, sp_offset);
fsr->regs[SP_REGNUM] = frame_sp - sp_offset;
return (ip);
}
/* Given an ip value corresponding to the start of a function,
return the ip of the first instruction after the function
prologue. */
CORE_ADDR
m88k_skip_prologue (CORE_ADDR ip)
{
struct frame_saved_regs saved_regs_dummy;
struct symtab_and_line sal;
CORE_ADDR limit;
sal = find_pc_line (ip, 0);
limit = (sal.end) ? sal.end : 0xffffffff;
return (examine_prologue (ip, limit, (CORE_ADDR) 0, &saved_regs_dummy,
(struct frame_info *) 0));
}
/* 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.
We cache the result of doing this in the frame_obstack, since it is
fairly expensive. */
void
frame_find_saved_regs (struct frame_info *fi, struct frame_saved_regs *fsr)
{
register struct frame_saved_regs *cache_fsr;
CORE_ADDR ip;
struct symtab_and_line sal;
CORE_ADDR limit;
if (!fi->fsr)
{
cache_fsr = (struct frame_saved_regs *)
frame_obstack_alloc (sizeof (struct frame_saved_regs));
memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
fi->fsr = cache_fsr;
/* Find the start and end of the function prologue. If the PC
is in the function prologue, we only consider the part that
has executed already. In the case where the PC is not in
the function prologue, we set limit to two instructions beyond
where the prologue ends in case if any of the prologue instructions
were moved into a delay slot of a branch instruction. */
ip = get_pc_function_start (fi->pc);
sal = find_pc_line (ip, 0);
limit = (sal.end && sal.end < fi->pc) ? sal.end + 2 * BYTES_PER_88K_INSN
: fi->pc;
/* This will fill in fields in *fi as well as in cache_fsr. */
#ifdef SIGTRAMP_FRAME_FIXUP
if (fi->signal_handler_caller)
SIGTRAMP_FRAME_FIXUP (fi->frame);
#endif
examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
#ifdef SIGTRAMP_SP_FIXUP
if (fi->signal_handler_caller && fi->fsr->regs[SP_REGNUM])
SIGTRAMP_SP_FIXUP (fi->fsr->regs[SP_REGNUM]);
#endif
}
if (fsr)
*fsr = *fi->fsr;
}
/* Return the address of the locals block for the frame
described by FI. Returns 0 if the address is unknown.
NOTE! Frame locals are referred to by negative offsets from the
argument pointer, so this is the same as frame_args_address(). */
CORE_ADDR
frame_locals_address (struct frame_info *fi)
{
struct frame_saved_regs fsr;
if (fi->args_pointer) /* Cached value is likely there. */
return fi->args_pointer;
/* Nope, generate it. */
get_frame_saved_regs (fi, &fsr);
return fi->args_pointer;
}
/* Return the address of the argument block for the frame
described by FI. Returns 0 if the address is unknown. */
CORE_ADDR
frame_args_address (struct frame_info *fi)
{
struct frame_saved_regs fsr;
if (fi->args_pointer) /* Cached value is likely there. */
return fi->args_pointer;
/* Nope, generate it. */
get_frame_saved_regs (fi, &fsr);
return fi->args_pointer;
}
/* Return the saved PC from this frame.
If the frame has a memory copy of SRP_REGNUM, use that. If not,
just use the register SRP_REGNUM itself. */
CORE_ADDR
frame_saved_pc (struct frame_info *frame)
{
return read_next_frame_reg (frame, SRP_REGNUM);
}
#define DUMMY_FRAME_SIZE 192
static void
write_word (CORE_ADDR sp, ULONGEST word)
{
register int len = REGISTER_SIZE;
char buffer[MAX_REGISTER_RAW_SIZE];
store_unsigned_integer (buffer, len, word);
write_memory (sp, buffer, len);
}
void
m88k_push_dummy_frame (void)
{
register CORE_ADDR sp = read_register (SP_REGNUM);
register int rn;
int offset;
sp -= DUMMY_FRAME_SIZE; /* allocate a bunch of space */
for (rn = 0, offset = 0; rn <= SP_REGNUM; rn++, offset += 4)
write_word (sp + offset, read_register (rn));
write_word (sp + offset, read_register (SXIP_REGNUM));
offset += 4;
write_word (sp + offset, read_register (SNIP_REGNUM));
offset += 4;
write_word (sp + offset, read_register (SFIP_REGNUM));
offset += 4;
write_word (sp + offset, read_register (PSR_REGNUM));
offset += 4;
write_word (sp + offset, read_register (FPSR_REGNUM));
offset += 4;
write_word (sp + offset, read_register (FPCR_REGNUM));
offset += 4;
write_register (SP_REGNUM, sp);
write_register (ACTUAL_FP_REGNUM, sp);
}
void
pop_frame (void)
{
register struct frame_info *frame = get_current_frame ();
register int regnum;
struct frame_saved_regs fsr;
get_frame_saved_regs (frame, &fsr);
if (PC_IN_CALL_DUMMY (read_pc (), read_register (SP_REGNUM), frame->frame))
{
/* FIXME: I think get_frame_saved_regs should be handling this so
that we can deal with the saved registers properly (e.g. frame
1 is a call dummy, the user types "frame 2" and then "print $ps"). */
register CORE_ADDR sp = read_register (ACTUAL_FP_REGNUM);
int offset;
for (regnum = 0, offset = 0; regnum <= SP_REGNUM; regnum++, offset += 4)
(void) write_register (regnum, read_memory_integer (sp + offset, 4));
write_register (SXIP_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
write_register (SNIP_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
write_register (SFIP_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
write_register (PSR_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
write_register (FPSR_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
write_register (FPCR_REGNUM, read_memory_integer (sp + offset, 4));
offset += 4;
}
else
{
for (regnum = FP_REGNUM; regnum > 0; regnum--)
if (fsr.regs[regnum])
write_register (regnum,
read_memory_integer (fsr.regs[regnum], 4));
write_pc (frame_saved_pc (frame));
}
reinit_frame_cache ();
}
void
_initialize_m88k_tdep (void)
{
tm_print_insn = print_insn_m88k;
}

View File

@ -1,260 +0,0 @@
/* Remote target glue for the Intel 960 MON960 ROM monitor.
Copyright 1995, 1996, 1997, 1998, 1999, 2000
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "srec.h"
#include "xmodem.h"
#include "symtab.h"
#include "symfile.h" /* for generic_load */
#include "inferior.h" /* for write_pc() */
#define USE_GENERIC_LOAD
static struct target_ops mon960_ops;
static void mon960_open (char *args, int from_tty);
#ifdef USE_GENERIC_LOAD
static void
mon960_load_gen (char *filename, int from_tty)
{
generic_load (filename, from_tty);
/* Finally, make the PC point at the start address */
if (exec_bfd)
write_pc (bfd_get_start_address (exec_bfd));
inferior_ptid = null_ptid; /* No process now */
}
#else
static void
mon960_load (struct serial *desc, char *file, int hashmark)
{
bfd *abfd;
asection *s;
char *buffer;
int i;
buffer = alloca (XMODEM_PACKETSIZE);
abfd = bfd_openr (file, 0);
if (!abfd)
{
printf_filtered ("Unable to open file %s\n", file);
return;
}
if (bfd_check_format (abfd, bfd_object) == 0)
{
printf_filtered ("File is not an object file\n");
return;
}
for (s = abfd->sections; s; s = s->next)
if (s->flags & SEC_LOAD)
{
bfd_size_type section_size;
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
s->vma + s->_raw_size);
gdb_flush (gdb_stdout);
monitor_printf (current_monitor->load, s->vma);
if (current_monitor->loadresp)
monitor_expect (current_monitor->loadresp, NULL, 0);
xmodem_init_xfer (desc);
section_size = bfd_section_size (abfd, s);
for (i = 0; i < section_size; i += XMODEM_DATASIZE)
{
int numbytes;
numbytes = min (XMODEM_DATASIZE, section_size - i);
bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i,
numbytes);
xmodem_send_packet (desc, buffer, numbytes, hashmark);
if (hashmark)
{
putchar_unfiltered ('#');
gdb_flush (gdb_stdout);
}
} /* Per-packet (or S-record) loop */
xmodem_finish_xfer (desc);
monitor_expect_prompt (NULL, 0);
putchar_unfiltered ('\n');
} /* Loadable sections */
if (hashmark)
putchar_unfiltered ('\n');
}
#endif /* USE_GENERIC_LOAD */
/* This array of registers need to match the indexes used by GDB.
This exists because the various ROM monitors use different strings
than does GDB, and don't necessarily support all the registers
either. So, typing "info reg sp" becomes a "r30". */
/* these correspond to the offsets from tm-* files from config directories */
/* g0-g14, fp, pfp, sp, rip,r3-15, pc, ac, tc, fp0-3 */
/* NOTE: "ip" is documented as "ir" in the Mon960 UG. */
/* NOTE: "ir" can't be accessed... but there's an ip and rip. */
static char *full_regnames[NUM_REGS] =
{
/* 0 */ "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
/* 8 */ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
/* 16 */ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
/* 24 */ "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
/* 32 */ "pc", "ac", "tc", "ip", "fp0", "fp1", "fp2", "fp3",
};
static char *mon960_regnames[NUM_REGS];
/* Define the monitor command strings. Since these are passed directly
through to a printf style function, we may include formatting
strings. We also need a CR or LF on the end. */
/* need to pause the monitor for timing reasons, so slow it down */
#if 0
/* FIXME: this extremely long init string causes MON960 to return two NAKS
instead of performing the autobaud recognition, at least when gdb
is running on GNU/Linux. The short string below works on Linux, and on
SunOS using a tcp serial connection. Must retest on SunOS using a
direct serial connection; if that works, get rid of the long string. */
static char *mon960_inits[] =
{"\n\r\r\r\r\r\r\r\r\r\r\r\r\r\r\n\r\n\r\n", NULL};
#else
static char *mon960_inits[] =
{"\r", NULL};
#endif
static struct monitor_ops mon960_cmds;
static void
init_mon960_cmds (void)
{
mon960_cmds.flags = MO_CLR_BREAK_USES_ADDR
| MO_NO_ECHO_ON_OPEN | MO_SEND_BREAK_ON_STOP | MO_GETMEM_READ_SINGLE; /* flags */
mon960_cmds.init = mon960_inits; /* Init strings */
mon960_cmds.cont = "go\n\r"; /* continue command */
mon960_cmds.step = "st\n\r"; /* single step */
mon960_cmds.stop = NULL; /* break interrupts the program */
mon960_cmds.set_break = NULL; /* set a breakpoint */
mon960_cmds.clr_break = /* can't use "br" because only 2 hw bps are supported */
mon960_cmds.clr_all_break = NULL; /* clear a breakpoint - "de" is for hw bps */
NULL, /* clear all breakpoints */
mon960_cmds.fill = NULL; /* fill (start end val) */
/* can't use "fi" because it takes words, not bytes */
/* can't use "mb", "md" or "mo" because they require interaction */
mon960_cmds.setmem.cmdb = NULL; /* setmem.cmdb (addr, value) */
mon960_cmds.setmem.cmdw = NULL; /* setmem.cmdw (addr, value) */
mon960_cmds.setmem.cmdl = "md %x %x\n\r"; /* setmem.cmdl (addr, value) */
mon960_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
mon960_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
mon960_cmds.setmem.term = NULL; /* setmem.term */
mon960_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
/* since the parsing of multiple bytes is difficult due to
interspersed addresses, we'll only read 1 value at a time,
even tho these can handle a count */
mon960_cmds.getmem.cmdb = "db %x\n\r"; /* getmem.cmdb (addr, #bytes) */
mon960_cmds.getmem.cmdw = "ds %x\n\r"; /* getmem.cmdw (addr, #swords) */
mon960_cmds.getmem.cmdl = "di %x\n\r"; /* getmem.cmdl (addr, #words) */
mon960_cmds.getmem.cmdll = "dd %x\n\r"; /* getmem.cmdll (addr, #dwords) */
mon960_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
mon960_cmds.getmem.term = NULL; /* getmem.term */
mon960_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
mon960_cmds.setreg.cmd = "md %s %x\n\r"; /* setreg.cmd (name, value) */
mon960_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
mon960_cmds.setreg.term = NULL; /* setreg.term */
mon960_cmds.setreg.term_cmd = NULL, /* setreg.term_cmd */
mon960_cmds.getreg.cmd = "di %s\n\r"; /* getreg.cmd (name) */
mon960_cmds.getreg.resp_delim = " : "; /* getreg.resp_delim */
mon960_cmds.getreg.term = NULL; /* getreg.term */
mon960_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
mon960_cmds.dump_registers = "re\n\r"; /* dump_registers */
mon960_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
mon960_cmds.supply_register = NULL; /* supply_register */
#ifdef USE_GENERIC_LOAD
mon960_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
mon960_cmds.load = NULL; /* download command */
mon960_cmds.loadresp = NULL; /* load response */
#else
mon960_cmds.load_routine = mon960_load; /* load_routine (defaults to SRECs) */
mon960_cmds.load = "do\n\r"; /* download command */
mon960_cmds.loadresp = "Downloading\n\r"; /* load response */
#endif
mon960_cmds.prompt = "=>"; /* monitor command prompt */
mon960_cmds.line_term = "\n\r"; /* end-of-command delimitor */
mon960_cmds.cmd_end = NULL; /* optional command terminator */
mon960_cmds.target = &mon960_ops; /* target operations */
mon960_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
mon960_cmds.regnames = mon960_regnames; /* registers names */
mon960_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
};
static void
mon960_open (char *args, int from_tty)
{
char buf[64];
monitor_open (args, &mon960_cmds, from_tty);
/* Attempt to fetch the value of the first floating point register (fp0).
If the monitor returns a string containing the word "Bad" we'll assume
this processor has no floating point registers, and nullify the
regnames entries that refer to FP registers. */
monitor_printf (mon960_cmds.getreg.cmd, full_regnames[FP0_REGNUM]); /* di fp0 */
if (monitor_expect_prompt (buf, sizeof (buf)) != -1)
if (strstr (buf, "Bad") != NULL)
{
int i;
for (i = FP0_REGNUM; i < FP0_REGNUM + 4; i++)
mon960_regnames[i] = NULL;
}
}
void
_initialize_mon960 (void)
{
memcpy (mon960_regnames, full_regnames, sizeof (full_regnames));
init_mon960_cmds ();
init_monitor_ops (&mon960_ops);
mon960_ops.to_shortname = "mon960"; /* for the target command */
mon960_ops.to_longname = "Intel 960 MON960 monitor";
#ifdef USE_GENERIC_LOAD
mon960_ops.to_load = mon960_load_gen; /* FIXME - should go back and try "do" */
#endif
/* use SW breaks; target only supports 2 HW breakpoints */
mon960_ops.to_insert_breakpoint = memory_insert_breakpoint;
mon960_ops.to_remove_breakpoint = memory_remove_breakpoint;
mon960_ops.to_doc =
"Use an Intel 960 board running the MON960 debug monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
mon960_ops.to_open = mon960_open;
add_target (&mon960_ops);
}

View File

@ -1,81 +0,0 @@
# Configuration fragment for GDB.
If "{host_canonical}" =~ /m68k-apple-mpw/
forward-include "{srcdir}"config:m68k:xm-mpw.h xm.h
Set siow_lib '"{Libraries}"SIOW.o'
Else If "{host_canonical}" =~ /powerpc-apple-mpw/
forward-include "{srcdir}"config:powerpc:xm-mpw.h xm.h
Set siow_lib '"{PPCLibraries}"PPCSIOW.o'
End If
Set xdepfiles '"{o}"mac-xdep.c.o'
Set enable_cflags ""
# Make a copy of this file and give it a different name, so it
# won't be confused with GDB's serial.h.
Duplicate -y "{CIncludes}"Serial.h MacSerial.h
Echo "/* dummy */" >termio.h
If "{target_canonical}" =~ /m68k-apple-macos/
forward-include "{srcdir}"config:m68k:tm-mac.h tm.h
forward-include "{srcdir}"config:m68k:tm-m68k.h 'm68k/tm-m68k.h'
Set tdepfiles '"{o}"m68k-tdep.c.o'
Else If "{target_canonical}" =~ /powerpc-apple-macos/
forward-include "{srcdir}"config:powerpc:tm-macos.h tm.h
forward-include "{srcdir}"config:rs6000:tm-rs6000.h 'rs6000/tm-rs6000.h'
Set tdepfiles '"{o}"rs6000-tdep.c.o "{o}"xcoffread.c.o'
Else If "{target_canonical}" =~ /i386-unknown-go32/
forward-include "{srcdir}"config:i386:tm-i386v.h tm.h
Set tdepfiles '"{o}"i386-tdep.c.o'
Else If "{target_canonical}" =~ /mips-idt-ecoff/
forward-include "{srcdir}"config:mips:tm-embed.h tm.h
forward-include "{srcdir}"config:mips:tm-bigmips.h 'mips/tm-bigmips.h'
forward-include "{srcdir}"config:mips:tm-mips.h 'mips/tm-mips.h'
Set tdepfiles '"{o}"mips-tdep.c.o "{o}"remote-mips.c.o'
Else If "{target_canonical}" =~ /sh-hitachi-hms/
forward-include "{srcdir}"config:sh:tm-sh.h tm.h
Set tdepfiles '"{o}"sh-tdep.c.o'
End If
If "{target_canonical}" =~ /m68k-apple-macos/
forward-include "{srcdir}"config:m68k:nm-macos.h nm.h
Set natdepfiles '"{o}"mac-nat.c.o'
Else If "{target_canonical}" =~ /powerpc-apple-macos/
forward-include "{srcdir}"config:powerpc:nm-macos.h nm.h
Set natdepfiles '"{o}"mac-nat.c.o'
Else
forward-include "{srcdir}"config:nm-empty.h nm.h
Set natdepfiles ' '
End If
Echo '# From mpw-config.in' > "{o}"mk.tmp
Echo "TDEPFILES = " {tdepfiles} >> "{o}"mk.tmp
Echo "XDEPFILES = " {xdepfiles} >> "{o}"mk.tmp
Echo "NATDEPFILES = " {natdepfiles} >> "{o}"mk.tmp
Echo "XM_ADD_FILES = " >> "{o}"mk.tmp
Echo "TM_ADD_FILES = " >> "{o}"mk.tmp
Echo "NAT_ADD_FILES = " >> "{o}"mk.tmp
Echo "XM_CDEPS = " >> "{o}"mk.tmp
Echo "TM_CDEPS = " >> "{o}"mk.tmp
Echo "NAT_CDEPS = " >> "{o}"mk.tmp
Echo "SIOW_LIB = " {siow_lib} >> "{o}"mk.tmp
Echo "ENABLE_CFLAGS = " {enable_cflags} >> "{o}"mk.tmp
Echo '# End from mpw-config.in' >> "{o}"mk.tmp
Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new
Echo '#include "mpw.h"' >> "{o}"config.new
MoveIfChange "{o}"config.new "{o}"config.h

View File

@ -1,178 +0,0 @@
# Sed commands that finish translating the GDB Unix Makefile to MPW syntax.
/^host_alias =/s/^/#/
/^target_alias =/s/^/#/
/^host_makefile_frag@$/d
/^target_makefile_frag@$/d
/@ENABLE_CFLAGS@/s/@ENABLE_CFLAGS@/{ENABLE_CFLAGS}/g
/^ENABLE_CFLAGS=/s/^/#/
# Edit all the symbolic definitions pointing to various libraries and such.
/^INCLUDE_DIR = /s/"{srcdir}":include/"{topsrcdir}"include:/
/^MMALLOC_DIR = /s/::mmalloc/mmalloc:/
/^MMALLOC_SRC = /s/"{srcdir}"/"{topsrcdir}"/
/^MMALLOC =/s/=.*$/=/
/MMALLOC_CFLAGS =/s/=.*$/= -u USE_MMALLOC/
/^BFD_DIR = /s/::bfd/bfd:/
/^BFD = /s/{BFD_DIR}:libbfd/{BFD_DIR}libbfd/
/^BFD_SRC = /s/"{srcdir}"/"{topsrcdir}"/
/^READLINE_DIR = /s/::readline/readline:/
/^READLINE =/s/=.*$/=/
/^READLINE_SRC = /s/"{srcdir}"/"{topsrcdir}"/
/^INCLUDE_CFLAGS = /s/$/ -i "{topsrcdir}"include:mpw: -i ::extra-include:/
/^SER_HARDWIRE =/s/ser-unix/ser-mac/
/^TERMCAP =/s/ =.*$/ =/
# Whack out various autoconf vars that we don't need.
/@CONFIG_LDFLAGS@/s/@CONFIG_LDFLAGS@//g
/@HLDFLAGS@/s/@HLDFLAGS@//g
/@DEFS@/s/@DEFS@//g
/@YACC@/s/@YACC@/byacc/g
/@ENABLE_OBS@/s/@ENABLE_OBS@//g
/@ENABLE_CLIBS@/s/@ENABLE_CLIBS@//g
/@LIBS@/s/@LIBS@//g
# Whack out autoconf hook for thread debugging.
/@THREAD_DB_OBS@/s/@THREAD_DB_OBS@//g
# Fix up paths to include directories.
/INCLUDE_DIR/s/"{s}"{INCLUDE_DIR}/{INCLUDE_DIR}/g
/INCLUDE_DIR/s/{INCLUDE_DIR}:/{INCLUDE_DIR}/g
/INCLUDE_DIR/s/"{INCLUDE_DIR}":/"{INCLUDE_DIR}"/g
/{BFD_DIR}/s/"{BFD_DIR}":/"{BFD_DIR}"/g
/{BFD_DIR}/s/\([ ]\){BFD_DIR}/\1::{BFD_DIR}/g
/{BFD_DIR}/s/\([ ]\)"{BFD_DIR}"/\1::"{BFD_DIR}"/g
/{BFD_SRC}/s/"{s}"{BFD_SRC}/{BFD_SRC}/g
/{BFD_SRC}/s/{BFD_SRC}:/{BFD_SRC}/g
/{READLINE_SRC}/s/"{s}"{READLINE_SRC}/{READLINE_SRC}/g
/^readline_headers =/,/^$/c\
readline_headers =\
# This isn't really useful, and seems to cause nonsensical complaints.
/{ALLDEPFILES}/s/{ALLDEPFILES}//g
/^copying.c \\Option-f /,/^$/d
# Fix the syntax of bits of C code that go into version.c.
/char /s/'char .Option-x/'char */
# Point at files in the obj dir rather than src dir.
/version/s/"{s}"version\.c/"{o}"version.c/g
/version/s/^version\.c/"{o}"version.c/
/config/s/"{s}"config\.h/"{o}"config.h/g
/config/s/^config\.h/"{o}"config.h/
/xm/s/"{s}"xm\.h/"{o}"xm.h/g
/xm/s/^xm\.h/"{o}"xm.h/
/tm/s/"{s}"tm\.h/"{o}"tm.h/g
/tm/s/^tm\.h/"{o}"tm.h/
/nm/s/"{s}"nm\.h/"{o}"nm.h/g
/nm/s/^nm\.h/"{o}"nm.h/
/exp.tab.c/s/"{s}"\([a-z0-9]*\)-exp\.tab\.c/"{o}"\1-exp.tab.c/g
/exp.tab.c/s/^\([a-z0-9]*\)-exp\.tab\.c/"{o}"\1-exp.tab.c/
/y.tab/s/"{s}"y.tab\.c/"{o}"y.tab.c/g
/y.tab/s/^y.tab\.c/"{o}"y.tab.c/
/init/s/"{s}"init\.c-tmp/"{o}"init.c-tmp/g
/init/s/^init\.c-tmp/"{o}"init.c-tmp/
/init/s/"{s}"init\.c/"{o}"init.c/g
/init/s/^init\.c/"{o}"init.c/
# Fix up the generation of version.c.
/"{o}"version.c \\Option-f Makefile/,/^$/c\
"{o}"version.c \\Option-f Makefile\
echo -n 'char *version = "' >"{o}"version.c\
echo -n "{VERSION}" >>"{o}"version.c\
echo '";' >>"{o}"version.c\
echo -n 'char *host_name = "' >>"{o}"version.c\
echo -n "{host_alias}" >>"{o}"version.c\
echo '";' >>"{o}"version.c\
echo -n 'char *target_name = "' >>"{o}"version.c\
echo -n "{target_alias}" >>"{o}"version.c\
echo '";' >>"{o}"version.c\
/ansidecl/s/include "{s}""ansidecl.h"/include "ansidecl.h"/
# Open-brace in a command causes much confusion; replace with the
# result from a script.
/initialize_all_files ()/c\
Echo -n 'void initialize_all_files () ' >> "{o}"init.c-tmp\
open-brace >> "{o}"init.c-tmp
# Replace the whole sed bit for init.c; it's simpler that way...
/echo {OBS} {TSOBS}/,/echo '}'/c\
For i in {OBS} {TSOBS}\
Set filename "`Echo {i} | sed \\Option-d\
-e '/^Onindy.c.o/d' \\Option-d\
-e '/^nindy.c.o/d' \\Option-d\
-e '/ttyflush.c.o/d' \\Option-d\
-e '/xdr_ld.c.o/d' \\Option-d\
-e '/xdr_ptrace.c.o/d' \\Option-d\
-e '/xdr_rdb.c.o/d' \\Option-d\
-e '/udr.c.o/d' \\Option-d\
-e '/udip2soc.c.o/d' \\Option-d\
-e '/udi2go32.c.o/d' \\Option-d\
-e '/version.c.o/d' \\Option-d\
-e '/[a-z0-9A-Z_]*-exp.tab.c.o/d' \\Option-d\
-e 's/\\.c\\.o/.c/' \\Option-d\
-e 's/^://'`"\
If "{filename}" != ""\
sed <"{s}""{filename}" >>"{o}"init.c-tmp -n \\Option-d\
-e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\\([a-z_0-9A-Z]*\\).*/ {extern void \\1 (); \\1 ();}/p'\
End If\
End For\
Echo '}' >>"{o}"init.c-tmp
# Fix the main compile/link command.
/{CC_LD} {INTERNAL_LDFLAGS} -o gdb/,/"{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {LOADLIBES}/c\
{CC_LD} {INTERNAL_LDFLAGS} -o gdb{PROG_EXT} "{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {LOADLIBES} {EXTRALIBS}\
{MAKEPEF} gdb{PROG_EXT} -o gdb {MAKEPEF_TOOL_FLAGS} {MAKEPEF_FLAGS}\
{REZ} "{s}"mac-gdb.r -o gdb -append -d PROG_NAME='"'gdb'"' -d VERSION_STRING='"'{version}'"'\
# Replace the install actions with MPW-friendly script.
/^install \\Option-f /,/^$/c\
install \\Option-f all install-only\
\
install-only \\Option-f \
NewFolderRecursive "{bindir}"\
Duplicate -y gdb "{bindir}"gdb\
If "`Exists SiowGDB`" != ""\
Duplicate -y SiowGDB "{bindir}"SiowGDB\
End If\
# Don't do any recursive subdir stuff.
/ subdir_do/s/{MAKE}/null-command/
# Edit out actions that only confuse MPW Make.
/^config.status \\Option-f/,/^$/d
/^Makefile \\Option-f/,/^$/d
# Don't test config.h dependencies.
/^"{o}"config.h \\Option-f/s/^/#/
# Add an action to build SIOWgdb.
$a\
SIOWgdb \\Option-f {OBS} {TSOBS} {ADD_DEPS} {CDEPS} "{o}"init.c.o\
Delete -i -y SIOWgdb\
{CC_LD} {INTERNAL_LDFLAGS} -t 'APPL' -c 'gdb ' -o SIOWgdb{PROG_EXT} "{o}"init.c.o {OBS} {TSOBS} {ADD_FILES} {CLIBS} {SIOW_LIB} {LOADLIBES} {EXTRALIBS}\
{MAKEPEF} SIOWgdb{PROG_EXT} -o SIOWgdb -ft 'APPL' -fc 'gdb ' {MAKEPEF_FLAGS} \
{REZ} -o SIOWgdb "{RIncludes}"siow.r -append -d __kPrefSize=5000 -d __kMinSize=2000 -d APPNAME='"'SIOWgdb'"' \
{REZ} "{s}"mac-gdb.r -o SIOWgdb -append -d VERSION_STRING='"'{version}'"'\

View File

@ -1,65 +0,0 @@
/* Low level interface to ptrace, for GDB when running under Unix.
Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef __GNUC__
/* Bad implement execle(3). It's depend for "/bin/cc".
main()
{
printf("execle:\n");
execle(FILE, ARGS, envp);
exit(1);
}
GCC:
link a6,#0
pea LC5 ; call printf
jbsr _printf
; ; (not popd stack)
pea _envp ; call execle
clrl sp@-
pea LC4
pea LC4
pea LC4
pea LC3
pea LC6
jbsr _execle
addw #32,sp ; delayed pop !!
/bin/cc:
link.l fp,#L23
movem.l #L24,(sp)
pea L26 ; call printf
jbsr _printf
addq.l #4,sp ; <--- popd stack !!
pea _envp ; call execle
clr.l -(sp)
pea L32
*/
execle(name, args)
char *name, *args;
{
register char **env = &args;
while (*env++)
;
execve(name, (char **)&args, (char **)*env);
}
#endif

View File

@ -1,78 +0,0 @@
/* Target-machine dependent code for the NINDY monitor running on the Intel 960
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 2000
Free Software Foundation, Inc.
Contributed by Intel Corporation.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
/* Miscellaneous NINDY-dependent routines.
Some replace macros normally defined in "tm.h". */
#include "defs.h"
#include "symtab.h"
#include "frame.h"
#include "gdbcore.h"
/* 'start_frame' is a variable in the NINDY runtime startup routine
that contains the frame pointer of the 'start' routine (the routine
that calls 'main'). By reading its contents out of remote memory,
we can tell where the frame chain ends: backtraces should halt before
they display this frame. */
int
nindy_frame_chain_valid (CORE_ADDR chain, struct frame_info *curframe)
{
struct symbol *sym;
struct minimal_symbol *msymbol;
/* crtnindy.o is an assembler module that is assumed to be linked
* first in an i80960 executable. It contains the true entry point;
* it performs startup up initialization and then calls 'main'.
*
* 'sf' is the name of a variable in crtnindy.o that is set
* during startup to the address of the first frame.
*
* 'a' is the address of that variable in 80960 memory.
*/
static char sf[] = "start_frame";
CORE_ADDR a;
chain &= ~0x3f; /* Zero low 6 bits because previous frame pointers
contain return status info in them. */
if (chain == 0)
{
return 0;
}
sym = lookup_symbol (sf, 0, VAR_NAMESPACE, (int *) NULL,
(struct symtab **) NULL);
if (sym != 0)
{
a = SYMBOL_VALUE (sym);
}
else
{
msymbol = lookup_minimal_symbol (sf, NULL, NULL);
if (msymbol == NULL)
return 0;
a = SYMBOL_VALUE_ADDRESS (msymbol);
}
return (chain != read_memory_integer (a, 4));
}

View File

@ -1,190 +0,0 @@
/* Print NS 32000 instructions for GDB, the GNU debugger.
Copyright 1986, 1988, 1991, 1992, 1994, 1995, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "gdbcore.h"
static int sign_extend (int value, int bits);
void
_initialize_ns32k_tdep (void)
{
tm_print_insn = print_insn_ns32k;
}
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
CORE_ADDR
umax_skip_prologue (CORE_ADDR pc)
{
register unsigned char op = read_memory_integer (pc, 1);
if (op == 0x82)
{
op = read_memory_integer (pc + 2, 1);
if ((op & 0x80) == 0)
pc += 3;
else if ((op & 0xc0) == 0x80)
pc += 4;
else
pc += 6;
}
return pc;
}
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell.
Encore's C compiler often reuses same area on stack for args,
so this will often not work properly. If the arg names
are known, it's likely most of them will be printed. */
int
umax_frame_num_args (struct frame_info *fi)
{
int numargs;
CORE_ADDR pc;
CORE_ADDR enter_addr;
unsigned int insn;
unsigned int addr_mode;
int width;
numargs = -1;
enter_addr = ns32k_get_enter_addr ((fi)->pc);
if (enter_addr > 0)
{
pc = ((enter_addr == 1)
? SAVED_PC_AFTER_CALL (fi)
: FRAME_SAVED_PC (fi));
insn = read_memory_integer (pc, 2);
addr_mode = (insn >> 11) & 0x1f;
insn = insn & 0x7ff;
if ((insn & 0x7fc) == 0x57c
&& addr_mode == 0x14) /* immediate */
{
if (insn == 0x57c) /* adjspb */
width = 1;
else if (insn == 0x57d) /* adjspw */
width = 2;
else if (insn == 0x57f) /* adjspd */
width = 4;
else
internal_error (__FILE__, __LINE__, "bad else");
numargs = read_memory_integer (pc + 2, width);
if (width > 1)
flip_bytes (&numargs, width);
numargs = -sign_extend (numargs, width * 8) / 4;
}
}
return numargs;
}
static int
sign_extend (int value, int bits)
{
value = value & ((1 << bits) - 1);
return (value & (1 << (bits - 1))
? value | (~((1 << bits) - 1))
: value);
}
void
flip_bytes (void *p, int count)
{
char tmp;
char *ptr = 0;
while (count > 0)
{
tmp = *ptr;
ptr[0] = ptr[count - 1];
ptr[count - 1] = tmp;
ptr++;
count -= 2;
}
}
/* Return the number of locals in the current frame given a pc
pointing to the enter instruction. This is used in the macro
FRAME_FIND_SAVED_REGS. */
int
ns32k_localcount (CORE_ADDR enter_pc)
{
unsigned char localtype;
int localcount;
localtype = read_memory_integer (enter_pc + 2, 1);
if ((localtype & 0x80) == 0)
localcount = localtype;
else if ((localtype & 0xc0) == 0x80)
localcount = (((localtype & 0x3f) << 8)
| (read_memory_integer (enter_pc + 3, 1) & 0xff));
else
localcount = (((localtype & 0x3f) << 24)
| ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
| ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
| (read_memory_integer (enter_pc + 5, 1) & 0xff));
return localcount;
}
/* Nonzero if instruction at PC is a return instruction. */
static int
ns32k_about_to_return (CORE_ADDR pc)
{
return (read_memory_integer (pc, 1) == 0x12);
}
/*
* Get the address of the enter opcode for the function
* containing PC, if there is an enter for the function,
* and if the pc is between the enter and exit.
* Returns positive address if pc is between enter/exit,
* 1 if pc before enter or after exit, 0 otherwise.
*/
CORE_ADDR
ns32k_get_enter_addr (CORE_ADDR pc)
{
CORE_ADDR enter_addr;
unsigned char op;
if (pc == 0)
return 0;
if (ns32k_about_to_return (pc))
return 1; /* after exit */
enter_addr = get_pc_function_start (pc);
if (pc == enter_addr)
return 1; /* before enter */
op = read_memory_integer (enter_addr, 1);
if (op != 0x82)
return 0; /* function has no enter/exit */
return enter_addr; /* pc is between enter and exit */
}

View File

@ -1,183 +0,0 @@
/* Low level interface to ns532 running mach 3.0.
Copyright (C) 1992 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "inferior.h"
#include <stdio.h>
#include <mach.h>
#include <mach/message.h>
#include <mach/exception.h>
#include <mach_error.h>
#define private static
/* Find offsets to thread states at compile time.
* If your compiler does not grok this, calculate offsets
* offsets yourself and use them (or get a compatible compiler :-)
*/
#define REG_N_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->ts.reg)
#define REG_F_OFFSET(reg) (int)(&((struct ns532_combined_state *)0)->fs.reg)
/* at reg_offset[i] is the offset to the ns532_combined_state
* location where the gdb registers[i] is stored.
*/
static int reg_offset[] =
{
REG_N_OFFSET(r0), REG_N_OFFSET(r1), REG_N_OFFSET(r2), REG_N_OFFSET(r3),
REG_N_OFFSET(r4), REG_N_OFFSET(r5), REG_N_OFFSET(r6), REG_N_OFFSET(r7),
REG_F_OFFSET(l0a), REG_F_OFFSET(l0b),REG_F_OFFSET(l2a),REG_F_OFFSET(l2b),
REG_F_OFFSET(l4a), REG_F_OFFSET(l4b),REG_F_OFFSET(l6a),REG_F_OFFSET(l6b),
REG_N_OFFSET(sp), REG_N_OFFSET(fp), REG_N_OFFSET(pc), REG_N_OFFSET(psr),
REG_F_OFFSET(fsr),
REG_F_OFFSET(l0a), REG_F_OFFSET(l1a),REG_F_OFFSET(l2a),REG_F_OFFSET(l3a),
REG_F_OFFSET(l4a), REG_F_OFFSET(l5a),REG_F_OFFSET(l6a),REG_F_OFFSET(l7a),
};
#define REG_ADDRESS(state,regnum) ((char *)(state)+reg_offset[regnum])
/* Fetch COUNT contiguous registers from thread STATE starting from REGNUM
* Caller knows that the regs handled in one transaction are of same size.
*/
#define FETCH_REGS(state, regnum, count) \
memcpy (&registers[REGISTER_BYTE (regnum)], \
(char *)state+reg_offset[ regnum ], \
count*REGISTER_SIZE)
/* Store COUNT contiguous registers to thread STATE starting from REGNUM */
#define STORE_REGS(state, regnum, count) \
memcpy ((char *)state+reg_offset[ regnum ], \
&registers[REGISTER_BYTE (regnum)], \
count*REGISTER_SIZE)
/*
* Fetch inferiors registers for gdb.
* REGNO specifies which (as gdb views it) register, -1 for all.
*/
void
fetch_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = NS532_COMBINED_STATE_COUNT;
int index;
if (! MACH_PORT_VALID (current_thread))
error ("fetch inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
ret = thread_get_state (current_thread,
NS532_COMBINED_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
warning ("fetch_inferior_registers: %s ",
mach_error_string (ret));
#if 0
/* It may be more effective to store validate all of them,
* since we fetched them all anyway
*/
else if (regno != -1)
supply_register (regno, (char *)state+reg_offset[regno]);
#endif
else
{
for (index = 0; index < NUM_REGS; index++)
supply_register (index, (char *)state+reg_offset[index]);
}
if (must_suspend_thread)
setup_thread (current_thread, 0);
}
/* Store our register values back into the inferior.
* If REGNO is -1, do this for all registers.
* Otherwise, REGNO specifies which register
*
* On mach3 all registers are always saved in one call.
*/
void
store_inferior_registers (regno)
int regno;
{
kern_return_t ret;
thread_state_data_t state;
unsigned int stateCnt = NS532_COMBINED_STATE_COUNT;
register int index;
if (! MACH_PORT_VALID (current_thread))
error ("store inferior registers: Invalid thread");
if (must_suspend_thread)
setup_thread (current_thread, 1);
/* Fetch the state of the current thread */
ret = thread_get_state (current_thread,
NS532_COMBINED_STATE,
state,
&stateCnt);
if (ret != KERN_SUCCESS)
{
warning ("store_inferior_registers (get): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
return;
}
/* move gdb's registers to thread's state
*
* Since we save all registers anyway, save the ones
* that gdb thinks are valid (e.g. ignore the regno
* parameter)
*/
#if 0
if (regno != -1)
STORE_REGS (state, regno, 1);
else
#endif
{
for (index = 0; index < NUM_REGS; index++)
STORE_REGS (state, index, 1);
}
/* Write gdb's current view of register to the thread
*/
ret = thread_set_state (current_thread,
NS532_COMBINED_STATE,
state,
NS532_COMBINED_STATE_COUNT);
if (ret != KERN_SUCCESS)
warning ("store_inferior_registers (set): %s",
mach_error_string (ret));
if (must_suspend_thread)
setup_thread (current_thread, 0);
}

View File

@ -1,364 +0,0 @@
/* Functions specific to running gdb native on an ns32k running NetBSD
Copyright 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
#include <machine/frame.h>
#include <machine/pcb.h>
#include "defs.h"
#include "inferior.h"
#include "target.h"
#include "gdbcore.h"
#include "regcache.h"
#define RF(dst, src) \
memcpy(&registers[REGISTER_BYTE(dst)], &src, sizeof(src))
#define RS(src, dst) \
memcpy(&dst, &registers[REGISTER_BYTE(src)], sizeof(dst))
void
fetch_inferior_registers (int regno)
{
struct reg inferior_registers;
struct fpreg inferior_fpregisters;
ptrace (PT_GETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
RF (R0_REGNUM + 0, inferior_registers.r_r0);
RF (R0_REGNUM + 1, inferior_registers.r_r1);
RF (R0_REGNUM + 2, inferior_registers.r_r2);
RF (R0_REGNUM + 3, inferior_registers.r_r3);
RF (R0_REGNUM + 4, inferior_registers.r_r4);
RF (R0_REGNUM + 5, inferior_registers.r_r5);
RF (R0_REGNUM + 6, inferior_registers.r_r6);
RF (R0_REGNUM + 7, inferior_registers.r_r7);
RF (SP_REGNUM, inferior_registers.r_sp);
RF (FP_REGNUM, inferior_registers.r_fp);
RF (PC_REGNUM, inferior_registers.r_pc);
RF (PS_REGNUM, inferior_registers.r_psr);
RF (FPS_REGNUM, inferior_fpregisters.r_fsr);
RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
registers_fetched ();
}
void
store_inferior_registers (int regno)
{
struct reg inferior_registers;
struct fpreg inferior_fpregisters;
RS (R0_REGNUM + 0, inferior_registers.r_r0);
RS (R0_REGNUM + 1, inferior_registers.r_r1);
RS (R0_REGNUM + 2, inferior_registers.r_r2);
RS (R0_REGNUM + 3, inferior_registers.r_r3);
RS (R0_REGNUM + 4, inferior_registers.r_r4);
RS (R0_REGNUM + 5, inferior_registers.r_r5);
RS (R0_REGNUM + 6, inferior_registers.r_r6);
RS (R0_REGNUM + 7, inferior_registers.r_r7);
RS (SP_REGNUM, inferior_registers.r_sp);
RS (FP_REGNUM, inferior_registers.r_fp);
RS (PC_REGNUM, inferior_registers.r_pc);
RS (PS_REGNUM, inferior_registers.r_psr);
RS (FPS_REGNUM, inferior_fpregisters.r_fsr);
RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
ptrace (PT_SETREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_registers, 0);
ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
(PTRACE_ARG3_TYPE) & inferior_fpregisters, 0);
}
/* XXX - Add this to machine/regs.h instead? */
struct coreregs
{
struct reg intreg;
struct fpreg freg;
};
/* Get registers from a core file. REG_ADDR is unused. */
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
unsigned int reg_addr)
{
struct coreregs *core_reg;
core_reg = (struct coreregs *) core_reg_sect;
/*
* We have *all* registers
* in the first core section.
* Ignore which.
*/
if (core_reg_size < sizeof (*core_reg))
{
fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
return;
}
/* Integer registers */
RF (R0_REGNUM + 0, core_reg->intreg.r_r0);
RF (R0_REGNUM + 1, core_reg->intreg.r_r1);
RF (R0_REGNUM + 2, core_reg->intreg.r_r2);
RF (R0_REGNUM + 3, core_reg->intreg.r_r3);
RF (R0_REGNUM + 4, core_reg->intreg.r_r4);
RF (R0_REGNUM + 5, core_reg->intreg.r_r5);
RF (R0_REGNUM + 6, core_reg->intreg.r_r6);
RF (R0_REGNUM + 7, core_reg->intreg.r_r7);
RF (SP_REGNUM, core_reg->intreg.r_sp);
RF (FP_REGNUM, core_reg->intreg.r_fp);
RF (PC_REGNUM, core_reg->intreg.r_pc);
RF (PS_REGNUM, core_reg->intreg.r_psr);
/* Floating point registers */
RF (FPS_REGNUM, core_reg->freg.r_fsr);
RF (FP0_REGNUM + 0, core_reg->freg.r_freg[0]);
RF (FP0_REGNUM + 2, core_reg->freg.r_freg[2]);
RF (FP0_REGNUM + 4, core_reg->freg.r_freg[4]);
RF (FP0_REGNUM + 6, core_reg->freg.r_freg[6]);
RF (LP0_REGNUM + 1, core_reg->freg.r_freg[1]);
RF (LP0_REGNUM + 3, core_reg->freg.r_freg[3]);
RF (LP0_REGNUM + 5, core_reg->freg.r_freg[5]);
RF (LP0_REGNUM + 7, core_reg->freg.r_freg[7]);
registers_fetched ();
}
/* Register that we are able to handle ns32knbsd core file formats.
FIXME: is this really bfd_target_unknown_flavour? */
static struct core_fns nat_core_fns =
{
bfd_target_unknown_flavour, /* core_flavour */
default_check_format, /* check_format */
default_core_sniffer, /* core_sniffer */
fetch_core_registers, /* core_read_registers */
NULL /* next */
};
void
_initialize_ns32knbsd_nat (void)
{
add_core_fns (&nat_core_fns);
}
/*
* kernel_u_size() is not helpful on NetBSD because
* the "u" struct is NOT in the core dump file.
*/
#ifdef FETCH_KCORE_REGISTERS
/*
* Get registers from a kernel crash dump or live kernel.
* Called by kcore-nbsd.c:get_kcore_registers().
*/
void
fetch_kcore_registers (struct pcb *pcb)
{
struct switchframe sf;
struct reg intreg;
int dummy;
/* Integer registers */
if (target_read_memory ((CORE_ADDR) pcb->pcb_ksp, (char *) &sf, sizeof sf))
error ("Cannot read integer registers.");
/* We use the psr at kernel entry */
if (target_read_memory ((CORE_ADDR) pcb->pcb_onstack, (char *) &intreg, sizeof intreg))
error ("Cannot read processor status register.");
dummy = 0;
RF (R0_REGNUM + 0, dummy);
RF (R0_REGNUM + 1, dummy);
RF (R0_REGNUM + 2, dummy);
RF (R0_REGNUM + 3, sf.sf_r3);
RF (R0_REGNUM + 4, sf.sf_r4);
RF (R0_REGNUM + 5, sf.sf_r5);
RF (R0_REGNUM + 6, sf.sf_r6);
RF (R0_REGNUM + 7, sf.sf_r7);
dummy = pcb->pcb_kfp + 8;
RF (SP_REGNUM, dummy);
RF (FP_REGNUM, sf.sf_fp);
RF (PC_REGNUM, sf.sf_pc);
RF (PS_REGNUM, intreg.r_psr);
/* Floating point registers */
RF (FPS_REGNUM, pcb->pcb_fsr);
RF (FP0_REGNUM + 0, pcb->pcb_freg[0]);
RF (FP0_REGNUM + 2, pcb->pcb_freg[2]);
RF (FP0_REGNUM + 4, pcb->pcb_freg[4]);
RF (FP0_REGNUM + 6, pcb->pcb_freg[6]);
RF (LP0_REGNUM + 1, pcb->pcb_freg[1]);
RF (LP0_REGNUM + 3, pcb->pcb_freg[3]);
RF (LP0_REGNUM + 5, pcb->pcb_freg[5]);
RF (LP0_REGNUM + 7, pcb->pcb_freg[7]);
registers_fetched ();
}
#endif /* FETCH_KCORE_REGISTERS */
void
clear_regs (void)
{
double zero = 0.0;
int null = 0;
/* Integer registers */
RF (R0_REGNUM + 0, null);
RF (R0_REGNUM + 1, null);
RF (R0_REGNUM + 2, null);
RF (R0_REGNUM + 3, null);
RF (R0_REGNUM + 4, null);
RF (R0_REGNUM + 5, null);
RF (R0_REGNUM + 6, null);
RF (R0_REGNUM + 7, null);
RF (SP_REGNUM, null);
RF (FP_REGNUM, null);
RF (PC_REGNUM, null);
RF (PS_REGNUM, null);
/* Floating point registers */
RF (FPS_REGNUM, zero);
RF (FP0_REGNUM + 0, zero);
RF (FP0_REGNUM + 2, zero);
RF (FP0_REGNUM + 4, zero);
RF (FP0_REGNUM + 6, zero);
RF (LP0_REGNUM + 0, zero);
RF (LP0_REGNUM + 1, zero);
RF (LP0_REGNUM + 2, zero);
RF (LP0_REGNUM + 3, zero);
return;
}
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
int
frame_num_args (struct frame_info *fi)
{
CORE_ADDR enter_addr;
CORE_ADDR argp;
int inst;
int args;
int i;
if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000)
{
/* main is always called with three args */
return (3);
}
enter_addr = ns32k_get_enter_addr (fi->pc);
if (enter_addr = 0)
return (-1);
argp = enter_addr == 1 ? SAVED_PC_AFTER_CALL (fi) : FRAME_SAVED_PC (fi);
for (i = 0; i < 16; i++)
{
/*
* After a bsr gcc may emit the following instructions
* to remove the arguments from the stack:
* cmpqd 0,tos - to remove 4 bytes from the stack
* cmpd tos,tos - to remove 8 bytes from the stack
* adjsp[bwd] -n - to remove n bytes from the stack
* Gcc sometimes delays emitting these instructions and
* may even throw a branch between our feet.
*/
inst = read_memory_integer (argp, 4);
args = read_memory_integer (argp + 2, 4);
if ((inst & 0xff) == 0xea)
{ /* br */
args = ((inst >> 8) & 0xffffff) | (args << 24);
if (args & 0x80)
{
if (args & 0x40)
{
args = ntohl (args);
}
else
{
args = ntohs (args & 0xffff);
if (args & 0x2000)
args |= 0xc000;
}
}
else
{
args = args & 0xff;
if (args & 0x40)
args |= 0x80;
}
argp += args;
continue;
}
if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
return (1);
else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
return (2);
else if ((inst & 0xfffc) == 0xa57c)
{ /* adjsp[bwd] */
switch (inst & 3)
{
case 0:
args = ((args & 0xff) + 0x80);
break;
case 1:
args = ((ntohs (args) & 0xffff) + 0x8000);
break;
case 3:
args = -ntohl (args);
break;
default:
return (-1);
}
if (args / 4 > 10 || (args & 3) != 0)
continue;
return (args / 4);
}
argp += 1;
}
return (-1);
}

View File

@ -1,142 +0,0 @@
/* Remote target glue for the Oki op50n based eval board.
Copyright 1995, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
static void op50n_open (char *args, int from_tty);
/*
* this array of registers need to match the indexes used by GDB. The
* whole reason this exists is cause the various ROM monitors use
* different strings than GDB does, and doesn't support all the
* registers either. So, typing "info reg sp" becomes a "r30".
*/
static char *op50n_regnames[NUM_REGS] =
{
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
"cr11", "p", NULL, NULL, NULL, "cr15", "cr19", "cr20",
"cr21", "cr22", NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "cr0", "cr8", "cr9", "cr10", "cr12",
"cr13", "cr24", "cr25", "cr26",
};
/*
* Define the monitor command strings. Since these are passed directly
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
static struct target_ops op50n_ops;
static char *op50n_inits[] =
{".\r", NULL};
static struct monitor_ops op50n_cmds;
static void
init_op50n_cmds (void)
{
op50n_cmds.flags = MO_CLR_BREAK_USES_ADDR /*| MO_GETMEM_READ_SINGLE */ ; /* flags */
op50n_cmds.init = op50n_inits; /* Init strings */
op50n_cmds.cont = "g\r"; /* continue command */
op50n_cmds.step = "t\r"; /* single step */
op50n_cmds.stop = "\003.\r"; /* Interrupt char */
op50n_cmds.set_break = "b %x\r"; /* set a breakpoint */
op50n_cmds.clr_break = "b %x;0\r"; /* clear breakpoint at addr */
op50n_cmds.clr_all_break = "bx\r"; /* clear all breakpoints */
op50n_cmds.fill = "fx %x s%x %x\r"; /* memory fill cmd (addr, len, val) */
op50n_cmds.setmem.cmdb = "sx %x %x\r"; /* setmem.cmdb (addr, value) */
op50n_cmds.setmem.cmdw = "sh %x %x\r"; /* setmem.cmdw (addr, value) */
op50n_cmds.setmem.cmdl = "s %x %x\r"; /* setmem.cmdl (addr, value) */
op50n_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
op50n_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */
op50n_cmds.setmem.term = NULL; /* setmem.term */
op50n_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */
#if 0
{
"sx %x\r", /* getmem.cmdb (addr, len) */
"sh %x\r", /* getmem.cmdw (addr, len) */
"s %x\r", /* getmem.cmdl (addr, len) */
NULL, /* getmem.cmdll (addr, len) */
" : ", /* getmem.resp_delim */
" ", /* getmem.term */
".\r", /* getmem.term_cmd */
};
#else
op50n_cmds.getmem.cmdb = "dx %x s%x\r"; /* getmem.cmdb (addr, len) */
op50n_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */
op50n_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */
op50n_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
op50n_cmds.getmem.resp_delim = " : "; /* getmem.resp_delim */
op50n_cmds.getmem.term = NULL; /* getmem.term */
op50n_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
#endif
op50n_cmds.setreg.cmd = "x %s %x\r"; /* setreg.cmd (name, value) */
op50n_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
op50n_cmds.setreg.term = NULL; /* setreg.term */
op50n_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
op50n_cmds.getreg.cmd = "x %s\r"; /* getreg.cmd (name) */
op50n_cmds.getreg.resp_delim = "="; /* getreg.resp_delim */
op50n_cmds.getreg.term = " "; /* getreg.term */
op50n_cmds.getreg.term_cmd = ".\r"; /* getreg.term_cmd */
op50n_cmds.dump_registers = NULL; /* dump_registers */
op50n_cmds.register_pattern = NULL; /* register_pattern */
op50n_cmds.supply_register = NULL; /* supply_register */
op50n_cmds.load_routine = NULL; /* load routine */
op50n_cmds.load = "r 0\r"; /* download command */
op50n_cmds.loadresp = NULL; /* load response */
op50n_cmds.prompt = "\n#"; /* monitor command prompt */
op50n_cmds.line_term = "\r"; /* end-of-command delimitor */
op50n_cmds.cmd_end = NULL; /* optional command terminator */
op50n_cmds.target = &op50n_ops; /* target operations */
op50n_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
op50n_cmds.regnames = op50n_regnames; /* register names */
op50n_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
};
static void
op50n_open (char *args, int from_tty)
{
monitor_open (args, &op50n_cmds, from_tty);
}
void
_initialize_op50n (void)
{
init_op50n_cmds ();
init_monitor_ops (&op50n_ops);
op50n_ops.to_shortname = "op50n";
op50n_ops.to_longname = "Oki's debug monitor for the Op50n Eval board";
op50n_ops.to_doc = "Debug on a Oki OP50N eval board.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
op50n_ops.to_open = op50n_open;
add_target (&op50n_ops);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,812 +0,0 @@
/* Shared code to pre-read a stab (dbx-style), when building a psymtab.
Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* The following need to be defined:
SET_NAMESTRING() --Set namestring to name of symbol.
CUR_SYMBOL_TYPE --Type code of current symbol.
CUR_SYMBOL_VALUE --Value field of current symbol. May be adjusted here.
namestring - variable pointing to the name of the stab.
section_offsets - variable pointing to the section offsets.
pst - the partial symbol table being built.
psymtab_include_list, includes_used, includes_allocated - list of include
file names (N_SOL) seen so far.
dependency_list, dependencies_used, dependencies_allocated - list of
N_EXCL stabs seen so far.
END_PSYMTAB -- end a partial symbol table.
START_PSYMTAB -- start a partial symbol table.
*/
/* End of macro definitions, now let's handle them symbols! */
switch (CUR_SYMBOL_TYPE)
{
char *p;
/*
* Standard, external, non-debugger, symbols
*/
case N_TEXT | N_EXT:
case N_NBTEXT | N_EXT:
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
goto record_it;
case N_DATA | N_EXT:
case N_NBDATA | N_EXT:
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA);
goto record_it;
case N_BSS:
case N_BSS | N_EXT:
case N_NBBSS | N_EXT:
case N_SETV | N_EXT: /* FIXME, is this in BSS? */
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_BSS);
goto record_it;
case N_ABS | N_EXT:
record_it:
#ifdef DBXREAD_ONLY
SET_NAMESTRING();
bss_ext_symbol:
record_minimal_symbol (namestring, CUR_SYMBOL_VALUE,
CUR_SYMBOL_TYPE, objfile); /* Always */
#endif /* DBXREAD_ONLY */
continue;
/* Standard, local, non-debugger, symbols */
case N_NBTEXT:
/* We need to be able to deal with both N_FN or N_TEXT,
because we have no way of knowing whether the sys-supplied ld
or GNU ld was used to make the executable. Sequents throw
in another wrinkle -- they renumbered N_FN. */
case N_FN:
case N_FN_SEQ:
case N_TEXT:
#ifdef DBXREAD_ONLY
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
SET_NAMESTRING();
if ((namestring[0] == '-' && namestring[1] == 'l')
|| (namestring [(nsl = strlen (namestring)) - 1] == 'o'
&& namestring [nsl - 2] == '.'))
{
if (objfile -> ei.entry_point < CUR_SYMBOL_VALUE &&
objfile -> ei.entry_point >= last_o_file_start)
{
objfile -> ei.entry_file_lowpc = last_o_file_start;
objfile -> ei.entry_file_highpc = CUR_SYMBOL_VALUE;
}
if (past_first_source_file && pst
/* The gould NP1 uses low values for .o and -l symbols
which are not the address. */
&& CUR_SYMBOL_VALUE >= pst->textlow)
{
END_PSYMTAB (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
CUR_SYMBOL_VALUE > pst->texthigh
? CUR_SYMBOL_VALUE : pst->texthigh,
dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
else
past_first_source_file = 1;
last_o_file_start = CUR_SYMBOL_VALUE;
}
else
goto record_it;
#endif /* DBXREAD_ONLY */
continue;
case N_DATA:
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA);
goto record_it;
case N_UNDF | N_EXT:
#ifdef DBXREAD_ONLY
if (CUR_SYMBOL_VALUE != 0) {
/* This is a "Fortran COMMON" symbol. See if the target
environment knows where it has been relocated to. */
CORE_ADDR reladdr;
SET_NAMESTRING();
if (target_lookup_symbol (namestring, &reladdr)) {
continue; /* Error in lookup; ignore symbol for now. */
}
CUR_SYMBOL_TYPE ^= (N_BSS^N_UNDF); /* Define it as a bss-symbol */
CUR_SYMBOL_VALUE = reladdr;
goto bss_ext_symbol;
}
#endif /* DBXREAD_ONLY */
continue; /* Just undefined, not COMMON */
case N_UNDF:
#ifdef DBXREAD_ONLY
if (processing_acc_compilation && CUR_SYMBOL_STRX == 1) {
/* Deal with relative offsets in the string table
used in ELF+STAB under Solaris. If we want to use the
n_strx field, which contains the name of the file,
we must adjust file_string_table_offset *before* calling
SET_NAMESTRING(). */
past_first_source_file = 1;
file_string_table_offset = next_file_string_table_offset;
next_file_string_table_offset =
file_string_table_offset + CUR_SYMBOL_VALUE;
if (next_file_string_table_offset < file_string_table_offset)
error ("string table offset backs up at %d", symnum);
/* FIXME -- replace error() with complaint. */
continue;
}
#endif /* DBXREAD_ONLY */
continue;
/* Lots of symbol types we can just ignore. */
case N_ABS:
case N_NBDATA:
case N_NBBSS:
continue;
/* Keep going . . .*/
/*
* Special symbol types for GNU
*/
case N_INDR:
case N_INDR | N_EXT:
case N_SETA:
case N_SETA | N_EXT:
case N_SETT:
case N_SETT | N_EXT:
case N_SETD:
case N_SETD | N_EXT:
case N_SETB:
case N_SETB | N_EXT:
case N_SETV:
continue;
/*
* Debugger symbols
*/
case N_SO: {
unsigned long valu;
static int prev_so_symnum = -10;
static int first_so_symnum;
char *p;
int prev_textlow_not_set;
valu = CUR_SYMBOL_VALUE + ANOFFSET (section_offsets, SECT_OFF_TEXT);
prev_textlow_not_set = textlow_not_set;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* A zero value is probably an indication for the SunPRO 3.0
compiler. end_psymtab explicitly tests for zero, so
don't relocate it. */
if (CUR_SYMBOL_VALUE == 0)
{
textlow_not_set = 1;
valu = 0;
}
else
textlow_not_set = 0;
#else
textlow_not_set = 0;
#endif
past_first_source_file = 1;
if (prev_so_symnum != symnum - 1)
{ /* Here if prev stab wasn't N_SO */
first_so_symnum = symnum;
if (pst)
{
END_PSYMTAB (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
valu > pst->texthigh ? valu : pst->texthigh,
dependency_list, dependencies_used,
prev_textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
}
prev_so_symnum = symnum;
/* End the current partial symtab and start a new one */
SET_NAMESTRING();
/* Null name means end of .o file. Don't start a new one. */
if (*namestring == '\000')
continue;
/* Some compilers (including gcc) emit a pair of initial N_SOs.
The first one is a directory name; the second the file name.
If pst exists, is empty, and has a filename ending in '/',
we assume the previous N_SO was a directory name. */
p = strrchr (namestring, '/');
if (p && *(p+1) == '\000')
continue; /* Simply ignore directory name SOs */
/* Some other compilers (C++ ones in particular) emit useless
SOs for non-existant .c files. We ignore all subsequent SOs that
immediately follow the first. */
if (!pst)
pst = START_PSYMTAB (objfile, section_offsets,
namestring, valu,
first_so_symnum * symbol_size,
objfile -> global_psymbols.next,
objfile -> static_psymbols.next);
continue;
}
case N_BINCL:
{
#ifdef DBXREAD_ONLY
enum language tmp_language;
/* Add this bincl to the bincl_list for future EXCLs. No
need to save the string; it'll be around until
read_dbx_symtab function returns */
SET_NAMESTRING();
tmp_language = deduce_language_from_filename (namestring);
/* Only change the psymtab's language if we've learned
something useful (eg. tmp_language is not language_unknown).
In addition, to match what start_subfile does, never change
from C++ to C. */
if (tmp_language != language_unknown
&& (tmp_language != language_c
|| psymtab_language != language_cplus))
psymtab_language = tmp_language;
if (pst == NULL)
{
/* FIXME: we should not get here without a PST to work on.
Attempt to recover. */
complain (&unclaimed_bincl_complaint, namestring, symnum);
continue;
}
add_bincl_to_list (pst, namestring, CUR_SYMBOL_VALUE);
/* Mark down an include file in the current psymtab */
goto record_include_file;
#else /* DBXREAD_ONLY */
continue;
#endif
}
case N_SOL:
{
enum language tmp_language;
/* Mark down an include file in the current psymtab */
SET_NAMESTRING();
tmp_language = deduce_language_from_filename (namestring);
/* Only change the psymtab's language if we've learned
something useful (eg. tmp_language is not language_unknown).
In addition, to match what start_subfile does, never change
from C++ to C. */
if (tmp_language != language_unknown
&& (tmp_language != language_c
|| psymtab_language != language_cplus))
psymtab_language = tmp_language;
/* In C++, one may expect the same filename to come round many
times, when code is coming alternately from the main file
and from inline functions in other files. So I check to see
if this is a file we've seen before -- either the main
source file, or a previously included file.
This seems to be a lot of time to be spending on N_SOL, but
things like "break c-exp.y:435" need to work (I
suppose the psymtab_include_list could be hashed or put
in a binary tree, if profiling shows this is a major hog). */
if (pst && STREQ (namestring, pst->filename))
continue;
{
register int i;
for (i = 0; i < includes_used; i++)
if (STREQ (namestring, psymtab_include_list[i]))
{
i = -1;
break;
}
if (i == -1)
continue;
}
#ifdef DBXREAD_ONLY
record_include_file:
#endif
psymtab_include_list[includes_used++] = namestring;
if (includes_used >= includes_allocated)
{
char **orig = psymtab_include_list;
psymtab_include_list = (char **)
alloca ((includes_allocated *= 2) *
sizeof (char *));
memcpy ((PTR)psymtab_include_list, (PTR)orig,
includes_used * sizeof (char *));
}
continue;
}
case N_LSYM: /* Typedef or automatic variable. */
case N_STSYM: /* Data seg var -- static */
case N_LCSYM: /* BSS " */
case N_ROSYM: /* Read-only data seg var -- static. */
case N_NBSTS: /* Gould nobase. */
case N_NBLCS: /* symbols. */
case N_FUN:
case N_GSYM: /* Global (extern) variable; can be
data or bss (sigh FIXME). */
/* Following may probably be ignored; I'll leave them here
for now (until I do Pascal and Modula 2 extensions). */
case N_PC: /* I may or may not need this; I
suspect not. */
case N_M2C: /* I suspect that I can ignore this here. */
case N_SCOPE: /* Same. */
SET_NAMESTRING();
#ifdef DBXREAD_ONLY
/* See if this is an end of function stab. */
if (CUR_SYMBOL_TYPE == N_FUN && *namestring == '\000')
{
unsigned long valu;
/* It's value is the size (in bytes) of the function for
function relative stabs, or the address of the function's
end for old style stabs. */
valu = CUR_SYMBOL_VALUE + last_function_start;
if (pst->texthigh == 0 || valu > pst->texthigh)
pst->texthigh = valu;
break;
}
#endif
p = (char *) strchr (namestring, ':');
if (!p)
continue; /* Not a debugging symbol. */
/* Main processing section for debugging symbols which
the initial read through the symbol tables needs to worry
about. If we reach this point, the symbol which we are
considering is definitely one we are interested in.
p must also contain the (valid) index into the namestring
which indicates the debugging type symbol. */
switch (p[1])
{
case 'S':
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA);
#ifdef STATIC_TRANSFORM_NAME
namestring = STATIC_TRANSFORM_NAME (namestring);
#endif
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
&objfile->static_psymbols,
0, CUR_SYMBOL_VALUE,
psymtab_language, objfile);
continue;
case 'G':
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_DATA);
/* The addresses in these entries are reported to be
wrong. See the code that reads 'G's for symtabs. */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_STATIC,
&objfile->global_psymbols,
0, CUR_SYMBOL_VALUE,
psymtab_language, objfile);
continue;
case 'T':
if (p != namestring) /* a name is there, not just :T... */
{
add_psymbol_to_list (namestring, p - namestring,
STRUCT_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
CUR_SYMBOL_VALUE, 0,
psymtab_language, objfile);
if (p[2] == 't')
{
/* Also a typedef with the same name. */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
CUR_SYMBOL_VALUE, 0,
psymtab_language, objfile);
p += 1;
}
/* The semantics of C++ state that "struct foo { ... }"
also defines a typedef for "foo". Unfortuantely, cfront
never makes the typedef when translating from C++ to C.
We make the typedef here so that "ptype foo" works as
expected for cfront translated code. */
else if (psymtab_language == language_cplus)
{
/* Also a typedef with the same name. */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
CUR_SYMBOL_VALUE, 0,
psymtab_language, objfile);
}
}
goto check_enum;
case 't':
if (p != namestring) /* a name is there, not just :T... */
{
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_TYPEDEF,
&objfile->static_psymbols,
CUR_SYMBOL_VALUE, 0,
psymtab_language, objfile);
}
check_enum:
/* If this is an enumerated type, we need to
add all the enum constants to the partial symbol
table. This does not cover enums without names, e.g.
"enum {a, b} c;" in C, but fortunately those are
rare. There is no way for GDB to find those from the
enum type without spending too much time on it. Thus
to solve this problem, the compiler needs to put out the
enum in a nameless type. GCC2 does this. */
/* We are looking for something of the form
<name> ":" ("t" | "T") [<number> "="] "e"
{<constant> ":" <value> ","} ";". */
/* Skip over the colon and the 't' or 'T'. */
p += 2;
/* This type may be given a number. Also, numbers can come
in pairs like (0,26). Skip over it. */
while ((*p >= '0' && *p <= '9')
|| *p == '(' || *p == ',' || *p == ')'
|| *p == '=')
p++;
if (*p++ == 'e')
{
/* The aix4 compiler emits extra crud before the members. */
if (*p == '-')
{
/* Skip over the type (?). */
while (*p != ':')
p++;
/* Skip over the colon. */
p++;
}
/* We have found an enumerated type. */
/* According to comments in read_enum_type
a comma could end it instead of a semicolon.
I don't know where that happens.
Accept either. */
while (*p && *p != ';' && *p != ',')
{
char *q;
/* Check for and handle cretinous dbx symbol name
continuation! */
if (*p == '\\' || (*p == '?' && p[1] == '\0'))
p = next_symbol_text (objfile);
/* Point to the character after the name
of the enum constant. */
for (q = p; *q && *q != ':'; q++)
;
/* Note that the value doesn't matter for
enum constants in psymtabs, just in symtabs. */
add_psymbol_to_list (p, q - p,
VAR_NAMESPACE, LOC_CONST,
&objfile->static_psymbols, 0,
0, psymtab_language, objfile);
/* Point past the name. */
p = q;
/* Skip over the value. */
while (*p && *p != ',')
p++;
/* Advance past the comma. */
if (*p)
p++;
}
}
continue;
case 'c':
/* Constant, e.g. from "const" in Pascal. */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_CONST,
&objfile->static_psymbols, CUR_SYMBOL_VALUE,
0, psymtab_language, objfile);
continue;
case 'f':
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
#ifdef DBXREAD_ONLY
/* Keep track of the start of the last function so we
can handle end of function symbols. */
last_function_start = CUR_SYMBOL_VALUE;
/* Kludges for ELF/STABS with Sun ACC */
last_function_name = namestring;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
value for the bottom of the text seg in those cases. */
if (pst && textlow_not_set)
{
pst->textlow =
find_stab_function_addr (namestring, pst, objfile);
textlow_not_set = 0;
}
#endif
#if 0
if (startup_file_end == 0)
startup_file_end = CUR_SYMBOL_VALUE;
#endif
/* End kludge. */
/* In reordered executables this function may lie outside
the bounds created by N_SO symbols. If that's the case
use the address of this function as the low bound for
the partial symbol table. */
if (textlow_not_set
|| (CUR_SYMBOL_VALUE < pst->textlow
&& CUR_SYMBOL_VALUE
!= ANOFFSET (section_offsets, SECT_OFF_TEXT)))
{
pst->textlow = CUR_SYMBOL_VALUE;
textlow_not_set = 0;
}
#endif /* DBXREAD_ONLY */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
&objfile->static_psymbols,
0, CUR_SYMBOL_VALUE,
psymtab_language, objfile);
continue;
/* Global functions were ignored here, but now they
are put into the global psymtab like one would expect.
They're also in the minimal symbol table. */
case 'F':
CUR_SYMBOL_VALUE += ANOFFSET (section_offsets, SECT_OFF_TEXT);
#ifdef DBXREAD_ONLY
/* Keep track of the start of the last function so we
can handle end of function symbols. */
last_function_start = CUR_SYMBOL_VALUE;
/* Kludges for ELF/STABS with Sun ACC */
last_function_name = namestring;
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
value for the bottom of the text seg in those cases. */
if (pst && textlow_not_set)
{
pst->textlow =
find_stab_function_addr (namestring, pst, objfile);
textlow_not_set = 0;
}
#endif
#if 0
if (startup_file_end == 0)
startup_file_end = CUR_SYMBOL_VALUE;
#endif
/* End kludge. */
/* In reordered executables this function may lie outside
the bounds created by N_SO symbols. If that's the case
use the address of this function as the low bound for
the partial symbol table. */
if (textlow_not_set
|| (CUR_SYMBOL_VALUE < pst->textlow
&& CUR_SYMBOL_VALUE
!= ANOFFSET (section_offsets, SECT_OFF_TEXT)))
{
pst->textlow = CUR_SYMBOL_VALUE;
textlow_not_set = 0;
}
#endif /* DBXREAD_ONLY */
add_psymbol_to_list (namestring, p - namestring,
VAR_NAMESPACE, LOC_BLOCK,
&objfile->global_psymbols,
0, CUR_SYMBOL_VALUE,
psymtab_language, objfile);
continue;
/* Two things show up here (hopefully); static symbols of
local scope (static used inside braces) or extensions
of structure symbols. We can ignore both. */
case 'V':
case '(':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
case '#': /* for symbol identification (used in live ranges) */
/* added to support cfront stabs strings */
case 'Z': /* for definition continuations */
case 'P': /* for prototypes */
continue;
case ':':
/* It is a C++ nested symbol. We don't need to record it
(I don't think); if we try to look up foo::bar::baz,
then symbols for the symtab containing foo should get
read in, I think. */
/* Someone says sun cc puts out symbols like
/foo/baz/maclib::/usr/local/bin/maclib,
which would get here with a symbol type of ':'. */
continue;
default:
/* Unexpected symbol descriptor. The second and subsequent stabs
of a continued stab can show up here. The question is
whether they ever can mimic a normal stab--it would be
nice if not, since we certainly don't want to spend the
time searching to the end of every string looking for
a backslash. */
complain (&unknown_symchar_complaint, p[1]);
/* Ignore it; perhaps it is an extension that we don't
know about. */
continue;
}
case N_EXCL:
#ifdef DBXREAD_ONLY
SET_NAMESTRING();
/* Find the corresponding bincl and mark that psymtab on the
psymtab dependency list */
{
struct partial_symtab *needed_pst =
find_corresponding_bincl_psymtab (namestring, CUR_SYMBOL_VALUE);
/* If this include file was defined earlier in this file,
leave it alone. */
if (needed_pst == pst) continue;
if (needed_pst)
{
int i;
int found = 0;
for (i = 0; i < dependencies_used; i++)
if (dependency_list[i] == needed_pst)
{
found = 1;
break;
}
/* If it's already in the list, skip the rest. */
if (found) continue;
dependency_list[dependencies_used++] = needed_pst;
if (dependencies_used >= dependencies_allocated)
{
struct partial_symtab **orig = dependency_list;
dependency_list =
(struct partial_symtab **)
alloca ((dependencies_allocated *= 2)
* sizeof (struct partial_symtab *));
memcpy ((PTR)dependency_list, (PTR)orig,
(dependencies_used
* sizeof (struct partial_symtab *)));
#ifdef DEBUG_INFO
fprintf_unfiltered (gdb_stderr, "Had to reallocate dependency list.\n");
fprintf_unfiltered (gdb_stderr, "New dependencies allocated: %d\n",
dependencies_allocated);
#endif
}
}
}
#endif /* DBXREAD_ONLY */
continue;
case N_ENDM:
#ifdef SOFUN_ADDRESS_MAYBE_MISSING
/* Solaris 2 end of module, finish current partial symbol table.
END_PSYMTAB will set pst->texthigh to the proper value, which
is necessary if a module compiled without debugging info
follows this module. */
if (pst)
{
END_PSYMTAB (pst, psymtab_include_list, includes_used,
symnum * symbol_size,
(CORE_ADDR) 0,
dependency_list, dependencies_used, textlow_not_set);
pst = (struct partial_symtab *) 0;
includes_used = 0;
dependencies_used = 0;
}
#endif
continue;
case N_RBRAC:
#ifdef HANDLE_RBRAC
HANDLE_RBRAC(CUR_SYMBOL_VALUE);
continue;
#endif
case N_EINCL:
case N_DSLINE:
case N_BSLINE:
case N_SSYM: /* Claim: Structure or union element.
Hopefully, I can ignore this. */
case N_ENTRY: /* Alternate entry point; can ignore. */
case N_MAIN: /* Can definitely ignore this. */
case N_CATCH: /* These are GNU C++ extensions */
case N_EHDECL: /* that can safely be ignored here. */
case N_LENG:
case N_BCOMM:
case N_ECOMM:
case N_ECOML:
case N_FNAME:
case N_SLINE:
case N_RSYM:
case N_PSYM:
case N_LBRAC:
case N_NSYMS: /* Ultrix 4.0: symbol count */
case N_DEFD: /* GNU Modula-2 */
case N_ALIAS: /* SunPro F77: alias name, ignore for now. */
case N_OBJ: /* useless types from Solaris */
case N_OPT:
/* These symbols aren't interesting; don't worry about them */
continue;
default:
/* If we haven't found it yet, ignore it. It's probably some
new type we don't know about yet. */
complain (&unknown_symtype_complaint,
local_hex_string (CUR_SYMBOL_TYPE));
continue;
}

View File

@ -1,211 +0,0 @@
/* Native-dependent code for ptx 4.0
Copyright 1988, 1989, 1991, 1992, 1994, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "inferior.h"
#include "gdbcore.h"
#include "regcache.h"
#include <sys/procfs.h>
#include <sys/ptrace.h>
#include <sys/param.h>
#include <fcntl.h>
/* Prototypes for supply_gregset etc. */
#include "gregset.h"
/* Given a pointer to a general register set in /proc format (gregset_t *),
unpack the register contents and supply them as gdb's idea of the current
register values. */
void
supply_gregset (gregset_t *gregsetp)
{
supply_register (EAX_REGNUM, (char *) &(*gregsetp)[EAX]);
supply_register (EDX_REGNUM, (char *) &(*gregsetp)[EDX]);
supply_register (ECX_REGNUM, (char *) &(*gregsetp)[ECX]);
supply_register (EBX_REGNUM, (char *) &(*gregsetp)[EBX]);
supply_register (ESI_REGNUM, (char *) &(*gregsetp)[ESI]);
supply_register (EDI_REGNUM, (char *) &(*gregsetp)[EDI]);
supply_register (ESP_REGNUM, (char *) &(*gregsetp)[UESP]);
supply_register (EBP_REGNUM, (char *) &(*gregsetp)[EBP]);
supply_register (EIP_REGNUM, (char *) &(*gregsetp)[EIP]);
supply_register (EFLAGS_REGNUM, (char *) &(*gregsetp)[EFL]);
}
void
fill_gregset (gregset_t *gregsetp, int regno)
{
int regi;
for (regi = 0; regi < NUM_REGS; regi++)
{
if ((regno == -1) || (regno == regi))
{
(*gregsetp)[regi] = *(greg_t *) & registers[REGISTER_BYTE (regi)];
}
}
}
/* Given a pointer to a floating point register set in /proc format
(fpregset_t *), unpack the register contents and supply them as gdb's
idea of the current floating point register values. */
void
supply_fpregset (fpregset_t *fpregsetp)
{
supply_fpu_registers ((struct fpusave *) &fpregsetp->fp_reg_set);
supply_fpa_registers ((struct fpasave *) &fpregsetp->f_wregs);
}
/* Given a pointer to a floating point register set in /proc format
(fpregset_t *), update the register specified by REGNO from gdb's idea
of the current floating point register set. If REGNO is -1, update
them all. */
void
fill_fpregset (fpregset_t *fpregsetp, int regno)
{
int regi;
char *to;
char *from;
/* FIXME: see m68k-tdep.c for an example, for the m68k. */
}
/*
* This doesn't quite do the same thing as the procfs.c version, but give
* it the same name so we don't have to put an ifdef in solib.c.
*/
/* this could use elf_interpreter() from elfread.c */
int
proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
{
vaddr_t curseg, memptr;
pt_vseg_t pv;
int rv, cmperr;
sec_ptr interp_sec;
char *interp_content;
int interp_fd, funcstat;
unsigned int size;
char buf1[NBPG], buf2[NBPG];
/*
* The following is really vile. We can get the name of the
* shared library from the exec_bfd, and we can get a list of
* each virtual memory segment, but there is no simple way to
* find the mapped segment from the shared library (ala
* procfs's PIOCOPENMEM). As a pretty nasty kludge, we
* compare the virtual memory segment to the contents of the
* .interp file. If they match, we assume that we've got the
* right one.
*/
/*
* TODO: for attach, use XPT_OPENT to get the executable, in
* case we're attached without knowning the executable's
* filename.
*/
#ifdef VERBOSE_DEBUG
printf ("proc_iter\n");
#endif
interp_sec = bfd_get_section_by_name (exec_bfd, ".interp");
if (!interp_sec)
{
return 0;
}
size = bfd_section_size (exec_bfd, interp_sec);
interp_content = alloca (size);
if (0 == bfd_get_section_contents (exec_bfd, interp_sec,
interp_content, (file_ptr) 0, size))
{
return 0;
}
#ifdef VERBOSE_DEBUG
printf ("proc_iter: \"%s\"\n", interp_content);
#endif
interp_fd = open (interp_content, O_RDONLY, 0);
if (-1 == interp_fd)
{
return 0;
}
curseg = 0;
while (1)
{
rv = ptrace (PT_NEXT_VSEG, PIDGET (inferior_ptid), &pv, curseg);
#ifdef VERBOSE_DEBUG
printf ("PT_NEXT_VSEG: rv %d errno %d\n", rv, errno);
#endif
if (-1 == rv)
break;
if (0 == rv)
break;
#ifdef VERBOSE_DEBUG
printf ("pv.pv_start 0x%x pv_size 0x%x pv_prot 0x%x\n",
pv.pv_start, pv.pv_size, pv.pv_prot);
#endif
curseg = pv.pv_start + pv.pv_size;
rv = lseek (interp_fd, 0, SEEK_SET);
if (-1 == rv)
{
perror ("lseek");
close (interp_fd);
return 0;
}
for (memptr = pv.pv_start; memptr < pv.pv_start + pv.pv_size;
memptr += NBPG)
{
#ifdef VERBOSE_DEBUG
printf ("memptr 0x%x\n", memptr);
#endif
rv = read (interp_fd, buf1, NBPG);
if (-1 == rv)
{
perror ("read");
close (interp_fd);
return 0;
}
rv = ptrace (PT_RDATA_PAGE, PIDGET (inferior_ptid), buf2,
memptr);
if (-1 == rv)
{
perror ("ptrace");
close (interp_fd);
return 0;
}
cmperr = memcmp (buf1, buf2, NBPG);
if (cmperr)
break;
}
if (0 == cmperr)
{
/* this is it */
funcstat = (*func) (interp_fd, pv.pv_start);
break;
}
}
close (interp_fd);
return 0;
}

View File

@ -1,452 +0,0 @@
/* Pyramid target-dependent code for GDB.
Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
/*** Prettier register printing. ***/
/* Print registers in the same format as pyramid's dbx, adb, sdb. */
pyr_print_registers(reg_buf, regnum)
long *reg_buf[];
{
register int regno;
int usp, ksp;
struct user u;
for (regno = 0; regno < 16; regno++) {
printf_unfiltered/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n",
REGISTER_NAME (regno), reg_buf[regno],
REGISTER_NAME (regno+16), reg_buf[regno+16],
REGISTER_NAME (regno+32), reg_buf[regno+32],
REGISTER_NAME (regno+48), reg_buf[regno+48]);
}
usp = ptrace (3, inferior_pid,
(PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_usp) -
((char *)&u), 0);
ksp = ptrace (3, inferior_pid,
(PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_ksp) -
((char *)&u), 0);
printf_unfiltered/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n",
REGISTER_NAME (CSP_REGNUM),reg_buf[CSP_REGNUM],
REGISTER_NAME (KSP_REGNUM), reg_buf[KSP_REGNUM], ksp,
"usp", usp);
}
/* Print the register regnum, or all registers if regnum is -1.
fpregs is currently ignored. */
pyr_do_registers_info (regnum, fpregs)
int regnum;
int fpregs;
{
/* On a pyr, we know a virtual register can always fit in an long.
Here (and elsewhere) we take advantage of that. Yuk. */
long raw_regs[MAX_REGISTER_RAW_SIZE*NUM_REGS];
register int i;
for (i = 0 ; i < 64 ; i++) {
read_relative_register_raw_bytes(i, raw_regs+i);
}
if (regnum == -1)
pyr_print_registers (raw_regs, regnum);
else
for (i = 0; i < NUM_REGS; i++)
if (i == regnum) {
long val = raw_regs[i];
fputs_filtered (REGISTER_NAME (i), gdb_stdout);
printf_filtered(":");
print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout);
if (val == 0)
printf_filtered ("0");
else
printf_filtered ("%s %d", local_hex_string_custom(val,"08"), val);
printf_filtered("\n");
}
}
/*** Debugging editions of various macros from m-pyr.h ****/
CORE_ADDR frame_locals_address (frame)
struct frame_info *frame;
{
register int addr = find_saved_register (frame,CFP_REGNUM);
register int result = read_memory_integer (addr, 4);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
fprintf_unfiltered (gdb_stderr,
"\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
frame->frame,
REGISTER_NAME (CFP_REGNUM),
result, addr,
frame->frame_cfp, (CFP_REGNUM),
read_register(13), read_register(29), read_register(61),
find_saved_register(frame, 61));
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
/* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
or at least CFP_REGNUM relative to FRAME (ie, result).
There seems to be a bug in the way the innermost frame is set up. */
return ((frame->next) ? result: frame->frame_cfp);
}
CORE_ADDR frame_args_addr (frame)
struct frame_info *frame;
{
register int addr = find_saved_register (frame,CFP_REGNUM);
register int result = read_memory_integer (addr, 4);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
fprintf_unfiltered (gdb_stderr,
"\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
frame->frame,
REGISTER_NAME (CFP_REGNUM),
result, addr,
frame->frame_cfp, read_register(CFP_REGNUM),
read_register(13), read_register(29), read_register(61),
find_saved_register(frame, 61));
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
/* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
or at least CFP_REGNUM relative to FRAME (ie, result).
There seems to be a bug in the way the innermost frame is set up. */
return ((frame->next) ? result: frame->frame_cfp);
}
#include "symtab.h"
#include "opcode/pyr.h"
#include "gdbcore.h"
/* A couple of functions used for debugging frame-handling on
Pyramids. (The Pyramid-dependent handling of register values for
windowed registers is known to be buggy.)
When debugging, these functions can supplant the normal definitions of some
of the macros in tm-pyramid.h The quantity of information produced
when these functions are used makes the gdb unusable as a
debugger for user programs. */
extern unsigned pyr_saved_pc(), pyr_frame_chain();
CORE_ADDR pyr_frame_chain(frame)
CORE_ADDR frame;
{
int foo=frame - CONTROL_STACK_FRAME_SIZE;
/* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/
return foo;
}
CORE_ADDR pyr_saved_pc(frame)
CORE_ADDR frame;
{
int foo=0;
foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
frame, 60/4, foo);
return foo;
}
/* Pyramid instructions are never longer than this many bytes. */
#define MAXLEN 24
/* Number of elements in the opcode table. */
/*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
#define NOPCODES (nopcodes)
/* Let's be byte-independent so we can use this as a cross-assembler. */
#define NEXTLONG(p) \
(p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
/* Print one instruction at address MEMADDR in debugged memory,
on STREAM. Returns length of the instruction, in bytes. */
int
pyr_print_insn (memaddr, stream)
CORE_ADDR memaddr;
GDB_FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i, nargs, insn_size =4;
register unsigned char *p;
register char *d;
register int insn_opcode, operand_mode;
register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ;
long insn; /* first word of the insn, not broken down. */
pyr_insn_format insn_decode; /* the same, broken out into op{code,erands} */
long extra_1, extra_2;
read_memory (memaddr, buffer, MAXLEN);
insn_decode = *((pyr_insn_format *) buffer);
insn = * ((int *) buffer);
insn_opcode = insn_decode.operator;
operand_mode = insn_decode.mode;
index_multiplier = insn_decode.index_scale;
index_reg_regno = insn_decode.index_reg;
op_1_regno = insn_decode.operand_1;
op_2_regno = insn_decode.operand_2;
if (*((int *)buffer) == 0x0) {
/* "halt" looks just like an invalid "jump" to the insn decoder,
so is dealt with as a special case */
fprintf_unfiltered (stream, "halt");
return (4);
}
for (i = 0; i < NOPCODES; i++)
if (pyr_opcodes[i].datum.code == insn_opcode)
break;
if (i == NOPCODES)
/* FIXME: Handle unrecognised instructions better. */
fprintf_unfiltered (stream, "???\t#%08x\t(op=%x mode =%x)",
insn, insn_decode.operator, insn_decode.mode);
else
{
/* Print the mnemonic for the instruction. Pyramid insn operands
are so regular that we can deal with almost all of them
separately.
Unconditional branches are an exception: they are encoded as
conditional branches (branch if false condition, I think)
with no condition specified. The average user will not be
aware of this. To maintain their illusion that an
unconditional branch insn exists, we will have to FIXME to
treat the insn mnemnonic of all branch instructions here as a
special case: check the operands of branch insn and print an
appropriate mnemonic. */
fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name);
/* Print the operands of the insn (as specified in
insn.operand_mode).
Branch operands of branches are a special case: they are a word
offset, not a byte offset. */
if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
register int bit_codes=(insn >> 16)&0xf;
register int i;
register int displacement = (insn & 0x0000ffff) << 2;
static char cc_bit_names[] = "cvzn"; /* z,n,c,v: strange order? */
/* Is bfc and no bits specified an unconditional branch?*/
for (i=0;i<4;i++) {
if ((bit_codes) & 0x1)
fputc_unfiltered (cc_bit_names[i], stream);
bit_codes >>= 1;
}
fprintf_unfiltered (stream, ",%0x",
displacement + memaddr);
return (insn_size);
}
switch (operand_mode) {
case 0:
fprintf_unfiltered (stream, "%s,%s",
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno));
break;
case 1:
fprintf_unfiltered (stream, " 0x%0x,%s",
op_1_regno,
REGISTER_NAME (op_2_regno));
break;
case 2:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream, " $0x%0x,%s",
extra_1,
REGISTER_NAME (op_2_regno));
break;
case 3:
fprintf_unfiltered (stream, " (%s),%s",
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno));
break;
case 4:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream, " 0x%0x(%s),%s",
extra_1,
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno));
break;
/* S1 destination mode */
case 5:
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 6:
fprintf_unfiltered (stream,
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
: " $%#0x,(%s)"),
op_1_regno,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 7:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
: " $%#0x,(%s)"),
extra_1,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 8:
fprintf_unfiltered (stream,
((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 9:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno)
? "%#0x(%s),(%s)[%s*%1d]"
: "%#0x(%s),(%s)"),
extra_1,
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
/* S2 destination mode */
case 10:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
REGISTER_NAME (op_1_regno),
extra_1,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 11:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ?
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
op_1_regno,
extra_1,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 12:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
read_memory (memaddr+8, buffer, MAXLEN);
insn_size += 4;
extra_2 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ?
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
extra_1,
extra_2,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 13:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno)
? " (%s),%#0x(%s)[%s*%1d]"
: " (%s),%#0x(%s)"),
REGISTER_NAME (op_1_regno),
extra_1,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
case 14:
read_memory (memaddr+4, buffer, MAXLEN);
insn_size += 4;
extra_1 = * ((int *) buffer);
read_memory (memaddr+8, buffer, MAXLEN);
insn_size += 4;
extra_2 = * ((int *) buffer);
fprintf_unfiltered (stream,
((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
: "%#0x(%s),%#0x(%s) "),
extra_1,
REGISTER_NAME (op_1_regno),
extra_2,
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
break;
default:
fprintf_unfiltered (stream,
((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
REGISTER_NAME (op_1_regno),
REGISTER_NAME (op_2_regno),
REGISTER_NAME (index_reg_regno),
index_multiplier);
fprintf_unfiltered (stream,
"\t\t# unknown mode in %08x",
insn);
break;
} /* switch */
}
{
return insn_size;
}
abort ();
}

View File

@ -1,370 +0,0 @@
/* Low level Pyramid interface to ptrace, for GDB when running under Unix.
Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/ioctl.h>
/* #include <fcntl.h> Can we live without this? */
#include "gdbcore.h"
#include <sys/user.h> /* After a.out.h */
#include <sys/file.h>
#include "gdb_stat.h"
void
fetch_inferior_registers (regno)
int regno;
{
register int datum;
register unsigned int regaddr;
int reg_buf[NUM_REGS+1];
struct user u;
register int skipped_frames = 0;
registers_fetched ();
for (regno = 0; regno < 64; regno++) {
reg_buf[regno] = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) regno, 0);
#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
printf_unfiltered ("Fetching register %s, got %0x\n",
REGISTER_NAME (regno),
reg_buf[regno]);
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
if (reg_buf[regno] == -1 && errno == EIO) {
printf_unfiltered("fetch_interior_registers: fetching register %s\n",
REGISTER_NAME (regno));
errno = 0;
}
supply_register (regno, reg_buf+regno);
}
/* that leaves regs 64, 65, and 66 */
datum = ptrace (3, inferior_pid,
(PTRACE_ARG3_TYPE) (((char *)&u.u_pcb.pcb_csp) -
((char *)&u)), 0);
/* FIXME: Find the Current Frame Pointer (CFP). CFP is a global
register (ie, NOT windowed), that gets saved in a frame iff
the code for that frame has a prologue (ie, "adsf N"). If
there is a prologue, the adsf insn saves the old cfp in
pr13, cfp is set to sp, and N bytes of locals are allocated
(sp is decremented by n).
This makes finding CFP hard. I guess the right way to do it
is:
- If this is the innermost frame, believe ptrace() or
the core area.
- Otherwise:
Find the first insn of the current frame.
- find the saved pc;
- find the call insn that saved it;
- figure out where the call is to;
- if the first insn is an adsf, we got a frame
pointer. */
/* Normal processors have separate stack pointers for user and
kernel mode. Getting the last user mode frame on such
machines is easy: the kernel context of the ptrace()'d
process is on the kernel stack, and the USP points to what
we want. But Pyramids only have a single cfp for both user and
kernel mode. And processes being ptrace()'d have some
kernel-context control frames on their stack.
To avoid tracing back into the kernel context of an inferior,
we skip 0 or more contiguous control frames where the pc is
in the kernel. */
while (1) {
register int inferior_saved_pc;
inferior_saved_pc = ptrace (1, inferior_pid,
(PTRACE_ARG3_TYPE) (datum+((32+15)*4)), 0);
if (inferior_saved_pc > 0) break;
#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
printf_unfiltered("skipping kernel frame %08x, pc=%08x\n", datum,
inferior_saved_pc);
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
skipped_frames++;
datum -= CONTROL_STACK_FRAME_SIZE;
}
reg_buf[CSP_REGNUM] = datum;
supply_register(CSP_REGNUM, reg_buf+CSP_REGNUM);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
if (skipped_frames) {
fprintf_unfiltered (gdb_stderr,
"skipped %d frames from %x to %x; cfp was %x, now %x\n",
skipped_frames, reg_buf[CSP_REGNUM]);
}
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
}
/* 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). */
void
store_inferior_registers (regno)
int regno;
{
register unsigned int regaddr;
char buf[80];
if (regno >= 0)
{
if ((0 <= regno) && (regno < 64)) {
/*regaddr = register_addr (regno, offset);*/
regaddr = regno;
errno = 0;
ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) 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);*/
regaddr = regno;
errno = 0;
ptrace (6, inferior_pid, (PTRACE_ARG3_TYPE) regaddr,
read_register (regno));
if (errno != 0)
{
sprintf (buf, "writing all regs, number %d", regno);
perror_with_name (buf);
}
}
}
/*** Extensions to core and dump files, for GDB. */
extern unsigned int last_frame_offset;
#ifdef PYRAMID_CORE
/* Can't make definitions here static, since corefile.c needs them
to do bounds checking on the core-file areas. O well. */
/* have two stacks: one for data, one for register windows. */
extern CORE_ADDR reg_stack_start;
extern CORE_ADDR reg_stack_end;
/* need this so we can find the global registers: they never get saved. */
CORE_ADDR global_reg_offset;
static CORE_ADDR last_frame_address;
CORE_ADDR last_frame_offset;
/* Address in core file of start of register window stack area.
Don't know if is this any of meaningful, useful or necessary. */
extern int reg_stack_offset;
#endif /* PYRAMID_CORE */
/* Work with core dump and executable files, for GDB.
This code would be in corefile.c if it weren't machine-dependent. */
void
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;
#ifdef PYRAMID_CORE
reg_stack_start = CONTROL_STACK_ADDR;
reg_stack_end = CONTROL_STACK_ADDR; /* this isn't strictly true...*/
#endif /* PYRAMID_CORE */
/* Now, if a new core file was specified, open it and digest it. */
if (filename)
{
filename = tilde_expand (filename);
make_cleanup (free, filename);
if (have_inferior_p ())
error ("To look at a core file, you must kill the program 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;
unsigned int reg_offset;
val = myread (corechan, &u, sizeof u);
if (val < 0)
perror_with_name ("Not a core file: reading upage");
if (val != sizeof u)
error ("Not a core file: could only read %d bytes", val);
data_start = exec_data_start;
data_end = data_start + NBPG * u.u_dsize;
data_offset = NBPG * UPAGES;
stack_offset = NBPG * (UPAGES + u.u_dsize);
/* find registers in core file */
#ifdef PYRAMID_PTRACE
stack_start = stack_end - NBPG * u.u_ussize;
reg_stack_offset = stack_offset + (NBPG *u.u_ussize);
reg_stack_end = reg_stack_start + NBPG * u.u_cssize;
last_frame_address = ((int) u.u_pcb.pcb_csp);
last_frame_offset = reg_stack_offset + last_frame_address
- CONTROL_STACK_ADDR ;
global_reg_offset = (char *)&u - (char *)&u.u_pcb.pcb_gr0 ;
/* skip any control-stack frames that were executed in the
kernel. */
while (1) {
char buf[4];
val = lseek (corechan, last_frame_offset+(47*4), 0);
if (val < 0)
perror_with_name (filename);
val = myread (corechan, buf, sizeof buf);
if (val < 0)
perror_with_name (filename);
if (*(int *)buf >= 0)
break;
printf_unfiltered ("skipping frame %s\n", local_hex_string (last_frame_address));
last_frame_offset -= CONTROL_STACK_FRAME_SIZE;
last_frame_address -= CONTROL_STACK_FRAME_SIZE;
}
reg_offset = last_frame_offset;
#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
printf_unfiltered ("Control stack pointer = %s\n",
local_hex_string (u.u_pcb.pcb_csp));
printf_unfiltered ("offset to control stack %d outermost frame %d (%s)\n",
reg_stack_offset, reg_offset, local_hex_string (last_frame_address));
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
#else /* not PYRAMID_CORE */
stack_start = stack_end - NBPG * u.u_ssize;
reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
#endif /* not PYRAMID_CORE */
#ifdef __not_on_pyr_yet
/* Some machines put an absolute address in here and some put
the offset in the upage of the regs. */
reg_offset = (int) u.u_ar0;
if (reg_offset > NBPG * UPAGES)
reg_offset -= KERNEL_U_ADDR;
#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 < 64; regno++)
{
char buf[MAX_REGISTER_RAW_SIZE];
val = lseek (corechan, register_addr (regno, reg_offset), 0);
if (val < 0
|| (val = myread (corechan, buf, sizeof buf)) < 0)
{
char * buffer = (char *) alloca (strlen (REGISTER_NAME (regno))
+ 30);
strcpy (buffer, "Reading register ");
strcat (buffer, REGISTER_NAME (regno));
perror_with_name (buffer);
}
if (val < 0)
perror_with_name (filename);
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
printf_unfiltered ("[reg %s(%d), offset in file %s=0x%0x, addr =0x%0x, =%0x]\n",
REGISTER_NAME (regno), regno, filename,
register_addr(regno, reg_offset),
regno * 4 + last_frame_address,
*((int *)buf));
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
supply_register (regno, buf);
}
}
}
if (filename[0] == '/')
corefile = savestring (filename, strlen (filename));
else
{
corefile = concat (current_directory, "/", filename, NULL);
}
#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
printf_unfiltered ("Providing CSP (%s) as nominal address of current frame.\n",
local_hex_string(last_frame_address));
#endif PYRAMID_CONTROL_FRAME_DEBUGGING
/* FIXME: Which of the following is correct? */
#if 0
set_current_frame ( create_new_frame (read_register (FP_REGNUM),
read_pc ()));
#else
set_current_frame ( create_new_frame (last_frame_address,
read_pc ()));
#endif
select_frame (get_current_frame (), 0);
validate_files ();
}
else if (from_tty)
printf_unfiltered ("No core file now.\n");
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,228 +0,0 @@
/* Remote target communications for d10v connected via a serial line.
Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free
Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdb_string.h"
#include <fcntl.h>
#include "frame.h"
#include "inferior.h"
#include "bfd.h"
#include "symfile.h"
#include "target.h"
#include "wait.h"
/*#include "terminal.h"*/
#include "gdbcmd.h"
#include "objfiles.h"
#include "gdb-stabs.h"
#include "gdbthread.h"
#include "dcache.h"
#ifdef USG
#include <sys/types.h>
#endif
#include <signal.h>
#include "serial.h"
/* Prototypes for local functions */
static void remote_d10v_open PARAMS ((char *name, int from_tty));
/* Define the target subroutine names */
static struct target_ops remote_d10v_ops;
/* Open a connection to a remote debugger.
NAME is the filename used for communication. */
static void
remote_d10v_open (name, from_tty)
char *name;
int from_tty;
{
pop_target ();
push_remote_target (name, from_tty);
}
/* Translate a GDB virtual ADDR/LEN into a format the remote target
understands. Returns number of bytes that can be transfered
starting at taddr, ZERO if no bytes can be transfered. */
int
remote_d10v_translate_xfer_address (memaddr, nr_bytes, taddr)
CORE_ADDR memaddr;
int nr_bytes;
CORE_ADDR *taddr;
{
CORE_ADDR phys;
CORE_ADDR seg;
CORE_ADDR off;
char *from = "unknown";
char *to = "unknown";
unsigned short imap0 = read_register (IMAP0_REGNUM);
unsigned short imap1 = read_register (IMAP1_REGNUM);
unsigned short dmap = read_register (DMAP_REGNUM);
/* GDB interprets addresses as:
0x00xxxxxx: Logical data address segment (DMAP translated memory)
0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
0x10xxxxxx: Physical data memory segment (On-chip data memory)
0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
0x12xxxxxx: Phisical unified memory segment (Unified memory)
The remote d10v board interprets addresses as:
0x00xxxxxx: Phisical unified memory segment (Unified memory)
0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)
0x02xxxxxx: Physical data memory segment (On-chip data memory)
Translate according to current IMAP/dmap registers */
enum {
targ_unified = 0x00000000,
targ_insn = 0x01000000,
targ_data = 0x02000000,
};
seg = (memaddr >> 24);
off = (memaddr & 0xffffffL);
switch (seg)
{
case 0x00: /* in logical data address segment */
{
from = "logical-data";
if (off <= 0x7fffL)
{
/* On chip data */
phys = targ_data + off;
if (off + nr_bytes > 0x7fffL)
/* don't cross VM boundary */
nr_bytes = 0x7fffL - off + 1;
to = "chip-data";
}
else if (off <= 0xbfffL)
{
short map = dmap;
if (map & 0x1000)
{
/* Instruction memory */
phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff);
to = "chip-insn";
}
else
{
/* Unified memory */
phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff);
to = "unified";
}
if (off + nr_bytes > 0xbfffL)
/* don't cross VM boundary */
nr_bytes = (0xbfffL - off + 1);
}
else
{
/* Logical address out side of data segments, not supported */
return (0);
}
break;
}
case 0x01: /* in logical instruction address segment */
{
short map;
from = "logical-insn";
if (off <= 0x1ffffL)
{
map = imap0;
}
else if (off <= 0x3ffffL)
{
map = imap1;
}
else
{
/* Logical address outside of IMAP[01] segment, not
supported */
return (0);
}
if ((off & 0x1ffff) + nr_bytes > 0x1ffffL)
{
/* don't cross VM boundary */
nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1;
}
if (map & 0x1000)
/* Instruction memory */
{
phys = targ_insn | off;
to = "chip-insn";
}
else
{
phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
if (phys > 0xffffffL)
/* Address outside of unified address segment */
return (0);
phys |= targ_unified;
to = "unified";
}
break;
}
case 0x10: /* Physical data memory segment */
from = "phys-data";
phys = targ_data | off;
to = "chip-data";
break;
case 0x11: /* Physical instruction memory */
from = "phys-insn";
phys = targ_insn | off;
to = "chip-insn";
break;
case 0x12: /* Physical unified memory */
from = "phys-unified";
phys = targ_unified | off;
to = "unified";
break;
default:
return (0);
}
*taddr = phys;
return nr_bytes;
}
void
_initialize_remote_d10v ()
{
remote_d10v_ops.to_shortname = "d10v";
remote_d10v_ops.to_longname = "Remote d10v serial target in gdb-specific protocol";
remote_d10v_ops.to_doc = "Use a remote d10v via a serial line, using a gdb-specific protocol.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_d10v_ops.to_open = remote_d10v_open;
add_target (&remote_d10v_ops);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,169 +0,0 @@
/* Remote debugging interface for EST-300 ICE, for GDB
Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Contributed by Cygnus Support.
Written by Steve Chamberlain for Cygnus Support.
Re-written by Stu Grossman of Cygnus Support
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "regcache.h"
static void est_open (char *args, int from_tty);
static void
est_supply_register (char *regname, int regnamelen, char *val, int vallen)
{
int regno;
if (regnamelen != 2)
return;
switch (regname[0])
{
case 'S':
if (regname[1] != 'R')
return;
regno = PS_REGNUM;
break;
case 'P':
if (regname[1] != 'C')
return;
regno = PC_REGNUM;
break;
case 'D':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + D0_REGNUM;
break;
case 'A':
if (regname[1] < '0' || regname[1] > '7')
return;
regno = regname[1] - '0' + A0_REGNUM;
break;
default:
return;
}
monitor_supply_register (regno, val);
}
/*
* This array of registers needs to match the indexes used by GDB. The
* whole reason this exists is because the various ROM monitors use
* different names than GDB does, and don't support all the
* registers either. So, typing "info reg sp" becomes a "r30".
*/
static char *est_regnames[NUM_REGS] =
{
"D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
"A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
"SR", "PC",
};
/*
* Define the monitor command strings. Since these are passed directly
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
static struct target_ops est_ops;
static char *est_inits[] =
{"he\r", /* Resets the prompt, and clears repeated cmds */
NULL};
static struct monitor_ops est_cmds;
static void
init_est_cmds (void)
{
est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT |
MO_SREC_ACK | MO_SREC_ACK_PLUS;
est_cmds.init = est_inits; /* Init strings */
est_cmds.cont = "go\r"; /* continue command */
est_cmds.step = "sidr\r"; /* single step */
est_cmds.stop = "\003"; /* ^C interrupts the program */
est_cmds.set_break = "sb %x\r"; /* set a breakpoint */
est_cmds.clr_break = "rb %x\r"; /* clear a breakpoint */
est_cmds.clr_all_break = "rb\r"; /* clear all breakpoints */
est_cmds.fill = "bfb %x %x %x\r"; /* fill (start end val) */
est_cmds.setmem.cmdb = "smb %x %x\r"; /* setmem.cmdb (addr, value) */
est_cmds.setmem.cmdw = "smw %x %x\r"; /* setmem.cmdw (addr, value) */
est_cmds.setmem.cmdl = "sml %x %x\r"; /* setmem.cmdl (addr, value) */
est_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
est_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
est_cmds.setmem.term = NULL; /* setreg.term */
est_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
est_cmds.getmem.cmdb = "dmb %x %x\r"; /* getmem.cmdb (addr, len) */
est_cmds.getmem.cmdw = "dmw %x %x\r"; /* getmem.cmdw (addr, len) */
est_cmds.getmem.cmdl = "dml %x %x\r"; /* getmem.cmdl (addr, len) */
est_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */
est_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
est_cmds.getmem.term = NULL; /* getmem.term */
est_cmds.getmem.term_cmd = NULL; /* getmem.term_cmd */
est_cmds.setreg.cmd = "sr %s %x\r"; /* setreg.cmd (name, value) */
est_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
est_cmds.setreg.term = NULL; /* setreg.term */
est_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
est_cmds.getreg.cmd = "dr %s\r"; /* getreg.cmd (name) */
est_cmds.getreg.resp_delim = " = "; /* getreg.resp_delim */
est_cmds.getreg.term = NULL; /* getreg.term */
est_cmds.getreg.term_cmd = NULL; /* getreg.term_cmd */
est_cmds.dump_registers = "dr\r"; /* dump_registers */
est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)"; /* register_pattern */
est_cmds.supply_register = est_supply_register; /* supply_register */
est_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
est_cmds.load = "dl\r"; /* download command */
est_cmds.loadresp = "+"; /* load response */
est_cmds.prompt = ">BKM>"; /* monitor command prompt */
est_cmds.line_term = "\r"; /* end-of-line terminator */
est_cmds.cmd_end = NULL; /* optional command terminator */
est_cmds.target = &est_ops; /* target operations */
est_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
est_cmds.regnames = est_regnames; /* registers names */
est_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
} /* init_est_cmds */
static void
est_open (char *args, int from_tty)
{
monitor_open (args, &est_cmds, from_tty);
}
void
_initialize_est (void)
{
init_est_cmds ();
init_monitor_ops (&est_ops);
est_ops.to_shortname = "est";
est_ops.to_longname = "EST background debug monitor";
est_ops.to_doc = "Debug via the EST BDM.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
est_ops.to_open = est_open;
add_target (&est_ops);
}

View File

@ -1,157 +0,0 @@
/* Remote debugging interface for Hitachi HMS Monitor Version 1.0
Copyright 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Steve Chamberlain
(sac@cygnus.com).
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include "defs.h"
#include "gdbcore.h"
#include "target.h"
#include "monitor.h"
#include "serial.h"
#include "regcache.h"
static void hms_open (char *args, int from_tty);
static void
hms_supply_register (char *regname, int regnamelen, char *val, int vallen)
{
int regno;
if (regnamelen != 2)
return;
if (regname[0] != 'P')
return;
/* We scan off all the registers in one go */
val = monitor_supply_register (PC_REGNUM, val);
/* Skip the ccr string */
while (*val != '=' && *val)
val++;
val = monitor_supply_register (CCR_REGNUM, val + 1);
/* Skip up to rest of regs */
while (*val != '=' && *val)
val++;
for (regno = 0; regno < 7; regno++)
{
val = monitor_supply_register (regno, val + 1);
}
}
/*
* This array of registers needs to match the indexes used by GDB. The
* whole reason this exists is because the various ROM monitors use
* different names than GDB does, and don't support all the
* registers either. So, typing "info reg sp" becomes a "r30".
*/
static char *hms_regnames[NUM_REGS] =
{
"R0", "R1", "R2", "R3", "R4", "R5", "R6", "R7", "CCR", "PC"
};
/*
* Define the monitor command strings. Since these are passed directly
* through to a printf style function, we need can include formatting
* strings. We also need a CR or LF on the end.
*/
static struct target_ops hms_ops;
static char *hms_inits[] =
{"\003", /* Resets the prompt, and clears repeated cmds */
NULL};
static struct monitor_ops hms_cmds;
static void
init_hms_cmds (void)
{
hms_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_GETMEM_NEEDS_RANGE;
hms_cmds.init = hms_inits; /* Init strings */
hms_cmds.cont = "g\r"; /* continue command */
hms_cmds.step = "s\r"; /* single step */
hms_cmds.stop = "\003"; /* ^C interrupts the program */
hms_cmds.set_break = "b %x\r"; /* set a breakpoint */
hms_cmds.clr_break = "b - %x\r"; /* clear a breakpoint */
hms_cmds.clr_all_break = "b -\r"; /* clear all breakpoints */
hms_cmds.fill = "f %x %x %x\r"; /* fill (start end val) */
hms_cmds.setmem.cmdb = "m.b %x=%x\r"; /* setmem.cmdb (addr, value) */
hms_cmds.setmem.cmdw = "m.w %x=%x\r"; /* setmem.cmdw (addr, value) */
hms_cmds.setmem.cmdl = NULL; /* setmem.cmdl (addr, value) */
hms_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */
hms_cmds.setmem.resp_delim = NULL; /* setreg.resp_delim */
hms_cmds.setmem.term = NULL; /* setreg.term */
hms_cmds.setmem.term_cmd = NULL; /* setreg.term_cmd */
hms_cmds.getmem.cmdb = "m.b %x %x\r"; /* getmem.cmdb (addr, addr) */
hms_cmds.getmem.cmdw = "m.w %x %x\r"; /* getmem.cmdw (addr, addr) */
hms_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, addr) */
hms_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, addr) */
hms_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */
hms_cmds.getmem.term = ">"; /* getmem.term */
hms_cmds.getmem.term_cmd = "\003"; /* getmem.term_cmd */
hms_cmds.setreg.cmd = "r %s=%x\r"; /* setreg.cmd (name, value) */
hms_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */
hms_cmds.setreg.term = NULL; /* setreg.term */
hms_cmds.setreg.term_cmd = NULL; /* setreg.term_cmd */
hms_cmds.getreg.cmd = "r %s\r"; /* getreg.cmd (name) */
hms_cmds.getreg.resp_delim = " ("; /* getreg.resp_delim */
hms_cmds.getreg.term = ":"; /* getreg.term */
hms_cmds.getreg.term_cmd = "\003"; /* getreg.term_cmd */
hms_cmds.dump_registers = "r\r"; /* dump_registers */
hms_cmds.register_pattern = "\\(\\w+\\)=\\([0-9a-fA-F]+\\)"; /* register_pattern */
hms_cmds.supply_register = hms_supply_register; /* supply_register */
hms_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */
hms_cmds.load = "tl\r"; /* download command */
hms_cmds.loadresp = NULL; /* load response */
hms_cmds.prompt = ">"; /* monitor command prompt */
hms_cmds.line_term = "\r"; /* end-of-command delimitor */
hms_cmds.cmd_end = NULL; /* optional command terminator */
hms_cmds.target = &hms_ops; /* target operations */
hms_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
hms_cmds.regnames = hms_regnames; /* registers names */
hms_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
} /* init_hms-cmds */
static void
hms_open (char *args, int from_tty)
{
monitor_open (args, &hms_cmds, from_tty);
}
int write_dos_tick_delay;
void
_initialize_remote_hms (void)
{
init_hms_cmds ();
init_monitor_ops (&hms_ops);
hms_ops.to_shortname = "hms";
hms_ops.to_longname = "Hitachi Microsystems H8/300 debug monitor";
hms_ops.to_doc = "Debug via the HMS monitor.\n\
Specify the serial device it is connected to (e.g. /dev/ttya).";
hms_ops.to_open = hms_open;
/* By trial and error I've found that this delay doesn't break things */
write_dos_tick_delay = 1;
add_target (&hms_ops);
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More