rs6000-core.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 726 行 · 第 1/2 页

C
726
字号
  if (bfd_stat (abfd, &statbuf) < 0)    {      bfd_set_error (bfd_error_system_call);      return NULL;    }  /* If the core file ulimit is too small, the system will first     omit the data segment, then omit the stack, then decline to     dump core altogether (as far as I know UBLOCK_VALID and LE_VALID     are always set) (this is based on experimentation on AIX 3.2).     Now, the thing is that GDB users will be surprised     if segments just silently don't appear (well, maybe they would     think to check "info files", I don't know).     For the data segment, we have no choice but to keep going if it's     not there, since the default behavior is not to dump it (regardless     of the ulimit, it's based on SA_FULLDUMP).  But for the stack segment,     if it's not there, we refuse to have anything to do with this core     file.  The usefulness of a core dump without a stack segment is pretty     limited anyway.  */  if (!(c_flag & UBLOCK_VALID)      || !(c_flag & LE_VALID))    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  if (!(c_flag & USTACK_VALID))    {      bfd_set_error (bfd_error_file_truncated);      return NULL;    }  /* Don't check the core file size for a full core, AIX 4.1 includes     additional shared library sections in a full core.  */  if (!(c_flag & (FULL_CORE | CORE_TRUNC)))    {      /* If the size is wrong, it means we're misinterpreting something.  */      if (c_stack + (file_ptr) c_size != statbuf.st_size)	{	  bfd_set_error (bfd_error_wrong_format);	  return NULL;	}    }  /* Sanity check on the c_tab field.  */  if (!CORE_NEW (core) && (c_loader < (file_ptr) sizeof core.old ||			   c_loader >= statbuf.st_size ||			   c_loader >= c_stack))    {      bfd_set_error (bfd_error_wrong_format);      return NULL;    }  /* Issue warning if the core file was truncated during writing.  */  if (c_flag & CORE_TRUNC)    (*_bfd_error_handler) (_("%s: warning core file truncated"),			   bfd_get_filename (abfd));  /* Allocate core file header.  */  size = CORE_NEW (core) ? sizeof (core.new) : sizeof (core.old);  tmpptr = (char *) bfd_zalloc (abfd, size);  if (!tmpptr)    return NULL;  /* Copy core file header.  */  memcpy (tmpptr, &core, size);  set_tdata (abfd, tmpptr);  /* Set architecture.  */  if (CORE_NEW (core))    {      enum bfd_architecture arch;      unsigned long mach;      switch (CNEW_IMPL (core.new))	{	case POWER_RS1:	case POWER_RSC:	case POWER_RS2:	  arch = bfd_arch_rs6000;	  mach = bfd_mach_rs6k;	  break;	default:	  arch = bfd_arch_powerpc;	  mach = bfd_mach_ppc;	  break;	}      bfd_default_set_arch_mach (abfd, arch, mach);    }  /* .stack section.  */  if (!make_bfd_asection (abfd, ".stack",			  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,			  c_size, c_stackend - c_size, c_stack))    return NULL;  /* .reg section for all registers.  */  if (!make_bfd_asection (abfd, ".reg",			  SEC_HAS_CONTENTS,			  c_regsize, (bfd_vma) 0, c_regoff))    return NULL;  /* .ldinfo section.     To actually find out how long this section is in this particular     core dump would require going down the whole list of struct ld_info's.     See if we can just fake it.  */  if (!make_bfd_asection (abfd, ".ldinfo",			  SEC_HAS_CONTENTS,			  c_lsize, (bfd_vma) 0, c_loader))    return NULL;#ifndef CORE_VERSION_1  /* .data section if present.     AIX 3 dumps the complete data section and sets FULL_CORE if the     ulimit is large enough, otherwise the data section is omitted.     AIX 4 sets FULL_CORE even if the core file is truncated, we have     to examine core.c_datasize below to find out the actual size of     the .data section.  */  if (c_flag & FULL_CORE)    {      if (!make_bfd_asection (abfd, ".data",			      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,			      (bfd_size_type) core.old.c_u.u_dsize,			      (bfd_vma)				CDATA_ADDR (core.old.c_u.u_dsize),			      c_stack + c_size))	return NULL;    }#endif#ifdef CORE_VERSION_1  /* AIX 4 adds data sections from loaded objects to the core file,     which can be found by examining ldinfo, and anonymously mmapped     regions.  */  {    LdInfo ldinfo;    bfd_size_type ldi_datasize;    file_ptr ldi_core;    uint ldi_next;    bfd_vma ldi_dataorg;    /* Fields from new and old core structures.  */    bfd_size_type c_datasize, c_vmregions;    file_ptr c_data, c_vmm;    if (CORE_NEW (core))      {	c_datasize = CNEW_DATASIZE (core.new);	c_data = (file_ptr) core.new.c_data;	c_vmregions = core.new.c_vmregions;	c_vmm = (file_ptr) core.new.c_vmm;      }    else      {	c_datasize = core.old.c_datasize;	c_data = (file_ptr) core.old.c_data;	c_vmregions = core.old.c_vmregions;	c_vmm = (file_ptr) core.old.c_vmm;      }    /* .data section from executable.  */    if (c_datasize)      {	if (!make_bfd_asection (abfd, ".data",				SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,				c_datasize,				(bfd_vma) CDATA_ADDR (c_datasize),				c_data))	  return NULL;      }    /* .data sections from loaded objects.  */    if (proc64)      size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;    else      size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;    while (1)      {	if (bfd_seek (abfd, c_loader, SEEK_SET) != 0)	  return NULL;	if (bfd_read (&ldinfo, size, 1, abfd) != size)	  return NULL;	if (proc64)	  {	    ldi_core = ldinfo.l64.ldinfo_core;	    ldi_datasize = ldinfo.l64.ldinfo_datasize;	    ldi_dataorg = (bfd_vma) ldinfo.l64.ldinfo_dataorg;	    ldi_next = ldinfo.l64.ldinfo_next;	  }	else	  {	    ldi_core = ldinfo.l32.ldinfo_core;	    ldi_datasize = ldinfo.l32.ldinfo_datasize;	    ldi_dataorg = (bfd_vma) (long) ldinfo.l32.ldinfo_dataorg;	    ldi_next = ldinfo.l32.ldinfo_next;	  }	if (ldi_core)	  if (!make_bfd_asection (abfd, ".data",				  SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,				  ldi_datasize, ldi_dataorg, ldi_core))	    return NULL;	if (ldi_next == 0)	  break;	c_loader += ldi_next;      }    /* .vmdata sections from anonymously mmapped regions.  */    if (c_vmregions)      {	bfd_size_type i;	if (bfd_seek (abfd, c_vmm, SEEK_SET) != 0)	  return NULL;	for (i = 0; i < c_vmregions; i++)	  {	    VmInfo vminfo;	    bfd_size_type vminfo_size;	    file_ptr vminfo_offset;	    bfd_vma vminfo_addr;	    size = CORE_NEW (core) ? sizeof (vminfo.new) : sizeof (vminfo.old);	    if (bfd_read (&vminfo, size, 1, abfd) != size)	      return NULL;	    if (CORE_NEW (core))	      {		vminfo_addr = (bfd_vma) vminfo.new.vminfo_addr;		vminfo_size = vminfo.new.vminfo_size;		vminfo_offset = vminfo.new.vminfo_offset;	      }	    else	      {		vminfo_addr = (bfd_vma) (long) vminfo.old.vminfo_addr;		vminfo_size = vminfo.old.vminfo_size;		vminfo_offset = vminfo.old.vminfo_offset;	      }	    if (vminfo_offset)	      if (!make_bfd_asection (abfd, ".vmdata",				      SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS,				      vminfo_size, vminfo_addr,				      vminfo_offset))		return NULL;	  }      }  }#endif  return abfd->xvec;		/* This is garbage for now.  */}/* Return `true' if given core is from the given executable.  */booleanrs6000coff_core_file_matches_executable_p (core_bfd, exec_bfd)     bfd *core_bfd;     bfd *exec_bfd;{  CoreHdr core;  bfd_size_type size;  char *path, *s;  size_t alloc;  const char *str1, *str2;  boolean ret;  file_ptr c_loader;  if (!read_hdr (core_bfd, &core))    return false;  if (CORE_NEW (core))    c_loader = CNEW_LOADER (core.new);  else    c_loader = (file_ptr) COLD_LOADER (core.old);  if (CORE_NEW (core) && CNEW_PROC64 (core.new))    size = (int) ((LdInfo *) 0)->l64.ldinfo_filename;  else    size = (int) ((LdInfo *) 0)->l32.ldinfo_filename;  if (bfd_seek (core_bfd, c_loader + size, SEEK_SET) != 0)    return false;  alloc = 100;  path = bfd_malloc (alloc);  if (path == NULL)    return false;  s = path;  while (1)    {      if (bfd_read (s, 1, 1, core_bfd) != 1)	{	  free (path);	  return false;	}      if (*s == '\0')	break;      ++s;      if (s == path + alloc)	{	  char *n;	  alloc *= 2;	  n = bfd_realloc (path, alloc);	  if (n == NULL)	    {	      free (path);	      return false;	    }	  s = n + (path - s);	  path = n;	}    }  str1 = strrchr (path, '/');  str2 = strrchr (exec_bfd->filename, '/');  /* step over character '/' */  str1 = str1 != NULL ? str1 + 1 : path;  str2 = str2 != NULL ? str2 + 1 : exec_bfd->filename;  if (strcmp (str1, str2) == 0)    ret = true;  else    ret = false;  free (path);  return ret;}char *rs6000coff_core_file_failing_command (abfd)     bfd *abfd;{  CoreHdr *core = core_hdr (abfd);  char *com = CORE_NEW (*core) ?    CNEW_COMM (core->new) : COLD_COMM (core->old);  if (*com)    return com;  else    return 0;}intrs6000coff_core_file_failing_signal (abfd)     bfd *abfd;{  CoreHdr *core = core_hdr (abfd);  return CORE_NEW (*core) ? core->new.c_signo : core->old.c_signo;}#endif /* AIX_CORE */

⌨️ 快捷键说明

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