⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convex-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Convex stuff for GDB.   Copyright (C) 1990, 1991 Free Software Foundation, Inc.This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "command.h"#include "symtab.h"#include "value.h"#include "frame.h"#include "inferior.h"#include "wait.h"#include <signal.h>#include <fcntl.h>#include "gdbcore.h"#include <sys/param.h>#include <sys/dir.h>#include <sys/user.h>#include <sys/ioctl.h>#include <sys/pcntl.h>#include <sys/thread.h>#include <sys/proc.h>#include <sys/file.h>#include <sys/stat.h>#include <sys/mman.h>#include "gdbcmd.h"exec_file_command (filename, from_tty)     char *filename;     int from_tty;{  int val;  int n;  struct stat st_exec;  /* Eliminate all traces of old exec file.     Mark text segment as empty.  */  if (execfile)    free (execfile);  execfile = 0;  data_start = 0;  data_end = 0;  text_start = 0;  text_end = 0;  exec_data_start = 0;  exec_data_end = 0;  if (execchan >= 0)    close (execchan);  execchan = -1;  n_exec = 0;  /* Now open and digest the file the user requested, if any.  */  if (filename)    {      filename = tilde_expand (filename);      make_cleanup (free, filename);            execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,			&execfile);      if (execchan < 0)	perror_with_name (filename);      if (myread (execchan, &filehdr, sizeof filehdr) < 0)	perror_with_name (filename);      if (! IS_SOFF_MAGIC (filehdr.h_magic))	error ("%s: not an executable file.", filename);      if (myread (execchan, &opthdr, filehdr.h_opthdr) <= 0)	perror_with_name (filename);      /* Read through the section headers.	 For text, data, etc, record an entry in the exec file map.	 Record text_start and text_end.  */      lseek (execchan, (long) filehdr.h_scnptr, 0);      for (n = 0; n < filehdr.h_nscns; n++)	{	  if (myread (execchan, &scnhdr, sizeof scnhdr) < 0)	    perror_with_name (filename);	  if ((scnhdr.s_flags & S_TYPMASK) >= S_TEXT	      && (scnhdr.s_flags & S_TYPMASK) <= S_COMON)	    {	      exec_map[n_exec].mem_addr = scnhdr.s_vaddr;	      exec_map[n_exec].mem_end = scnhdr.s_vaddr + scnhdr.s_size;	      exec_map[n_exec].file_addr = scnhdr.s_scnptr;	      exec_map[n_exec].type = scnhdr.s_flags & S_TYPMASK;	      n_exec++;	      if ((scnhdr.s_flags & S_TYPMASK) == S_TEXT)		{		  text_start = scnhdr.s_vaddr;		  text_end =  scnhdr.s_vaddr + scnhdr.s_size;		}	    }	}      fstat (execchan, &st_exec);      exec_mtime = st_exec.st_mtime;            validate_files ();    }  else if (from_tty)    printf_filtered ("No exec file now.\n");  /* Tell display code (if any) about the changed file name.  */  if (exec_file_display_hook)    (*exec_file_display_hook) (filename);}/* Read data from SOFF exec or core file.   Return 0 on success, EIO if address out of bounds. */intxfer_core_file (memaddr, myaddr, len)     CORE_ADDR memaddr;     char *myaddr;     int len;{  register int i;  register int n;  register int val;  int xferchan;  char **xferfile;  int fileptr;  int returnval = 0;  while (len > 0)    {      xferfile = 0;      xferchan = 0;      /* Determine which file the next bunch of addresses reside in,	 and where in the file.  Set the file's read/write pointer	 to point at the proper place for the desired address	 and set xferfile and xferchan for the correct file.	 If desired address is nonexistent, leave them zero.	 i is set to the number of bytes that can be handled	 along with the next address.  */      i = len;      for (n = 0; n < n_core; n++)	{	  if (memaddr >= core_map[n].mem_addr && memaddr < core_map[n].mem_end	      && (core_map[n].thread == -1		  || core_map[n].thread == inferior_thread))	    {	      i = min (len, core_map[n].mem_end - memaddr);	      fileptr = core_map[n].file_addr + memaddr - core_map[n].mem_addr;	      if (core_map[n].file_addr)		{		  xferfile = &corefile;		  xferchan = corechan;		}	      break;	    }	  else if (core_map[n].mem_addr >= memaddr		   && core_map[n].mem_addr < memaddr + i) 	    i = core_map[n].mem_addr - memaddr;        }      if (!xferfile) 	for (n = 0; n < n_exec; n++)	  {	    if (memaddr >= exec_map[n].mem_addr		&& memaddr < exec_map[n].mem_end)	      {		i = min (len, exec_map[n].mem_end - memaddr);		fileptr = exec_map[n].file_addr + memaddr		  - exec_map[n].mem_addr;		if (exec_map[n].file_addr)		  {		    xferfile = &execfile;		    xferchan = execchan;		  }		break;	      }	    else if (exec_map[n].mem_addr >= memaddr		     && exec_map[n].mem_addr < memaddr + i)	      i = exec_map[n].mem_addr - memaddr;	  }      /* Now we know which file to use.	 Set up its pointer and transfer the data.  */      if (xferfile)	{	  if (*xferfile == 0)	    if (xferfile == &execfile)	      error ("No program file to examine.");	    else	      error ("No core dump file or running program to examine.");	  val = lseek (xferchan, fileptr, 0);	  if (val < 0)	    perror_with_name (*xferfile);	  val = myread (xferchan, myaddr, i);	  if (val < 0)	    perror_with_name (*xferfile);	}      /* If this address is for nonexistent memory,	 read zeros if reading, or do nothing if writing.  */      else	{	  bzero (myaddr, i);	  returnval = EIO;	}      memaddr += i;      myaddr += i;      len -= i;    }  return returnval;}/* Here from info files command to print an address map.  */print_maps (){  struct pmap ptrs[200];  int n;  /* ID strings for core and executable file sections */  static char *idstr[] =    {      "0", "text", "data", "tdata", "bss", "tbss",       "common", "ttext", "ctx", "tctx", "10", "11", "12",    };  for (n = 0; n < n_core; n++)    {      core_map[n].which = 0;      ptrs[n] = core_map[n];    }  for (n = 0; n < n_exec; n++)    {      exec_map[n].which = 1;      ptrs[n_core+n] = exec_map[n];    }  qsort (ptrs, n_core + n_exec, sizeof *ptrs, ptr_cmp);  for (n = 0; n < n_core + n_exec; n++)    {      struct pmap *p = &ptrs[n];      if (n > 0)	{	  if (p->mem_addr < ptrs[n-1].mem_end)	    p->mem_addr = ptrs[n-1].mem_end;	  if (p->mem_addr >= p->mem_end)	    continue;	}      printf_filtered ("%08x .. %08x  %-6s  %s\n",		       p->mem_addr, p->mem_end, idstr[p->type],		       p->which ? execfile : corefile);    }}/* Compare routine to put file sections in order.   Sort into increasing order on address, and put core file sections   before exec file sections if both files contain the same addresses.  */static ptr_cmp (a, b)     struct pmap *a, *b;{  if (a->mem_addr != b->mem_addr) return a->mem_addr - b->mem_addr;  return a->which - b->which;}/* Trapped internal variables are used to handle special registers.   A trapped i.v. calls a hook here every time it is dereferenced,   to provide a new value for the variable, and it calls a hook here   when a new value is assigned, to do something with the value.      The vector registers are $vl, $vs, $vm, $vN, $VN (N in 0..7).   The communication registers are $cN, $CN (N in 0..63).   They not handled as regular registers because it's expensive to   read them, and their size varies, and they have too many names.  *//* Return 1 if NAME is a trapped internal variable, else 0. */intis_trapped_internalvar (name)     char *name;{    if ((name[0] == 'c' || name[0] == 'C')	&& name[1] >= '0' && name[1] <= '9'	&& (name[2] == '\0'	    || (name[2] >= '0' && name[2] <= '9'		&& name[3] == '\0' && name[1] != '0'))	&& atoi (&name[1]) < 64) return 1;  if ((name[0] == 'v' || name[0] == 'V')      && (((name[1] & -8) == '0' && name[2] == '\0')	  || !strcmp (name, "vl")	  || !strcmp (name, "vs") 	  || !strcmp (name, "vm")))    return 1;  else return 0;}/* Return the value of trapped internal variable VAR */valuevalue_of_trapped_internalvar (var)     struct internalvar *var;{  char *name = var->name;  value val;  struct type *type;  long len = *read_vector_register (VL_REGNUM);  if (len <= 0 || len > 128) len = 128;  if (!strcmp (name, "vl"))    {      val = value_from_longest (builtin_type_int,			     (LONGEST) *read_vector_register_1 (VL_REGNUM));    }  else if (!strcmp (name, "vs"))    {      val = value_from_longest (builtin_type_int,			     (LONGEST) *read_vector_register_1 (VS_REGNUM));    }  else if (!strcmp (name, "vm"))    {      long vm[4];      long i, *p;      bcopy (read_vector_register_1 (VM_REGNUM), vm, sizeof vm);      type = vector_type (builtin_type_int, len);      val = allocate_value (type);      p = (long *) VALUE_CONTENTS (val);      for (i = 0; i < len; i++) 	*p++ = !! (vm[3 - (i >> 5)] & (1 << (i & 037)));    }  else if (name[0] == 'V')    {      type = vector_type (builtin_type_long_long, len);      val = allocate_value (type);      bcopy (read_vector_register_1 (name[1] - '0'),	     VALUE_CONTENTS (val), TYPE_LENGTH (type));    }  else if (name[0] == 'v')    {      long *p1, *p2;      type = vector_type (builtin_type_long, len);      val = allocate_value (type);      p1 = read_vector_register_1 (name[1] - '0');      p2 = (long *) VALUE_CONTENTS (val);      while (--len >= 0) {p1++; *p2++ = *p1++;}    }  else if (name[0] == 'c')    val = value_from_longest (builtin_type_int,			   read_comm_register (atoi (&name[1])));  else if (name[0] == 'C')    val = value_from_longest (builtin_type_long_long,			   read_comm_register (atoi (&name[1])));  VALUE_LVAL (val) = lval_internalvar;  VALUE_INTERNALVAR (val) = var;  return val;}/* Construct the type for a vector register's value --   array[LENGTH] of ELEMENT_TYPE.  */static struct type *vector_type (element_type, length)     struct type *element_type;     long length;{  struct type *type = (struct type *) xmalloc (sizeof (struct type));  bzero (type, sizeof type);  TYPE_CODE (type) = TYPE_CODE_ARRAY;  TYPE_TARGET_TYPE (type) = element_type;  TYPE_LENGTH (type) = length * TYPE_LENGTH (TYPE_TARGET_TYPE (type));  return type;}/* Handle a new value assigned to a trapped internal variable */voidset_trapped_internalvar (var, val, bitpos, bitsize, offset)     struct internalvar *var;     value val;     int bitpos, bitsize, offset;{   char *name = var->name;  long long newval = value_as_long (val);  if (!strcmp (name, "vl"))     write_vector_register (VL_REGNUM, 0, newval);  else if (!strcmp (name, "vs"))    write_vector_register (VS_REGNUM, 0, newval);  else if (name[0] == 'c' || name[0] == 'C')    write_comm_register (atoi (&name[1]), newval);  else if (!strcmp (name, "vm"))    error ("can't assign to $vm");  else    {      offset /= bitsize / 8;      write_vector_register (name[1] - '0', offset, newval);    }}/* Print an integer value when no format was specified.  gdb normally   prints these values in decimal, but the the leading 0x80000000 of   pointers produces intolerable 10-digit negative numbers.   If it looks like an address, print it in hex instead.  */decout (stream, type, val)     FILE *stream;     struct type *type;     LONGEST val;{  long lv = val;  switch (output_radix)    {    case 0:      if ((lv == val || (unsigned) lv == val)	  && ((lv & 0xf0000000) == 0x80000000	      || ((lv & 0xf0000000) == 0xf0000000 && lv < STACK_END_ADDR)))	{	  fprintf_filtered (stream, "%#x", lv);	  return;	}    case 10:      fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%llu" : "%lld", val);      return;    case 8:      if (TYPE_LENGTH (type) <= sizeof lv)	fprintf_filtered (stream, "%#o", lv);      else	fprintf_filtered (stream, "%#llo", val);      return;    case 16:      if (TYPE_LENGTH (type) <= sizeof lv)	fprintf_filtered (stream, "%#x", lv);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -