Ejemplo n.º 1
0
static const bfd_target *
netbsd_core_file_p (bfd *abfd)
{
  int val;
  unsigned i;
  file_ptr offset;
  asection *asect;
  struct core core;
  struct coreseg coreseg;
  bfd_size_type amt = sizeof core;

  val = bfd_bread (&core, amt, abfd);
  if (val != sizeof core)
    {
      /* Too small to be a core file.  */
      bfd_set_error (bfd_error_wrong_format);
      return 0;
    }

  if (CORE_GETMAGIC (core) != COREMAGIC)
    {
      bfd_set_error (bfd_error_wrong_format);
      return 0;
    }

  amt = sizeof (struct netbsd_core_struct);
  rawptr = (struct netbsd_core_struct *) bfd_zalloc (abfd, amt);
  if (rawptr == NULL)
    return 0;

  rawptr->core = core;
  abfd->tdata.netbsd_core_data = rawptr;

  offset = core.c_hdrsize;
  for (i = 0; i < core.c_nseg; i++)
    {
      const char *sname;
      flagword flags;

      if (bfd_seek (abfd, offset, SEEK_SET) != 0)
	goto punt;

      val = bfd_bread (&coreseg, sizeof coreseg, abfd);
      if (val != sizeof coreseg)
	{
	  bfd_set_error (bfd_error_file_truncated);
	  goto punt;
	}
      if (CORE_GETMAGIC (coreseg) != CORESEGMAGIC)
	{
	  bfd_set_error (bfd_error_wrong_format);
	  goto punt;
	}

      offset += core.c_seghdrsize;

      switch (CORE_GETFLAG (coreseg))
	{
	case CORE_CPU:
	  sname = ".reg";
	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
	  break;
	case CORE_DATA:
	  sname = ".data";
	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
	  break;
	case CORE_STACK:
	  sname = ".stack";
	  flags = SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS;
	  break;
	default:
	  sname = ".unknown";
	  flags = SEC_ALLOC + SEC_HAS_CONTENTS;
	  break;
	}
      asect = bfd_make_section_anyway_with_flags (abfd, sname, flags);
      if (asect == NULL)
	goto punt;

      asect->size = coreseg.c_size;
      asect->vma = coreseg.c_addr;
      asect->filepos = offset;
      asect->alignment_power = 2;

      if (CORE_GETFLAG (coreseg) == CORE_CPU)
	{
	  bfd_size_type wcookie_offset;

	  switch (CORE_GETMID (core))
	    {
	    case M_SPARC_NETBSD:
	      wcookie_offset = SPARC_WCOOKIE_OFFSET;
	      break;
	    case M_SPARC64_OPENBSD:
	      wcookie_offset = SPARC64_WCOOKIE_OFFSET;
	      break;
	    default:
	      wcookie_offset = 0;
	      break;
	    }

	  if (wcookie_offset > 0 && coreseg.c_size > wcookie_offset)
	    {
	      /* Truncate the .reg section.  */
	      asect->size = wcookie_offset;

	      /* And create the .wcookie section.  */
	      flags = SEC_ALLOC + SEC_HAS_CONTENTS;
	      asect = bfd_make_section_anyway_with_flags (abfd, ".wcookie",
							  flags);
	      if (asect == NULL)
		goto punt;

	      asect->size = coreseg.c_size - wcookie_offset;
	      asect->vma = 0;
	      asect->filepos = offset + wcookie_offset;
	      asect->alignment_power = 2;
	    }
	}

      offset += coreseg.c_size;
    }

  /* Set architecture from machine ID.  */
  switch (CORE_GETMID (core))
    {
    case M_ALPHA_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_alpha, 0);
      break;

    case M_ARM6_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_arm, bfd_mach_arm_3);
      break;

    case M_X86_64_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
      break;

    case M_386_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
      break;

    case M_68K_NETBSD:
    case M_68K4K_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_m68k, 0);
      break;

    case M_88K_OPENBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_m88k, 0);
      break;

    case M_HPPA_OPENBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_hppa, bfd_mach_hppa11);
      break;

    case M_POWERPC_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
      break;

    case M_SPARC_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
      break;

    case M_SPARC64_NETBSD:
    case M_SPARC64_OPENBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
      break;

    case M_VAX_NETBSD:
    case M_VAX4K_NETBSD:
      bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
      break;
    }

  /* OK, we believe you.  You're a core file (sure, sure).  */
  return abfd->xvec;

 punt:
  bfd_release (abfd, abfd->tdata.any);
  abfd->tdata.any = NULL;
  bfd_section_list_clear (abfd);
  return 0;
}
Ejemplo n.º 2
0
int
read_core(const char *path, struct pstate *ps)
{
	struct corefile *cf;
	void *core_map;
	off_t c_off;
	int i, cfd;

	cf = (struct corefile *)malloc(sizeof(*cf));
	if (cf == NULL)
		err(1, "malloc");

	cfd = open(path, O_RDONLY, 0600);
	if (cfd < 0)
		err(1, "open() failed on core file");

	if (fstat(cfd, &(cf->cfstat)) < 0)
		err(1, "fstat() failed on core");

	if (cf->cfstat.st_mtimespec.tv_sec < ps->exec_stat.st_mtimespec.tv_sec)
		warnx("executable is more recent than core file!");

	core_map = mmap(NULL, cf->cfstat.st_size, PROT_READ, MAP_PRIVATE,
	    cfd, 0);
	if (core_map == MAP_FAILED)
		err(1, "mmap() failed on core");
	close(cfd);

	cf->chdr = (struct core *)core_map;
	c_off = cf->chdr->c_hdrsize;
	if (CORE_GETMAGIC(*(cf->chdr)) != COREMAGIC)
		errx(1, "hey, that's not a core file");

	printf("Core file generated from '%s' by signal %d (SIG%s)\n",
	    cf->chdr->c_name, cf->chdr->c_signo,
	    sys_signame[cf->chdr->c_signo]);

#ifdef DEBUG
	printf("Core: text=0x%lx, data=0x%lx, stack=0x%lx\n",
	    cf->chdr->c_tsize, cf->chdr->c_dsize, cf->chdr->c_ssize);
#endif

	cf->segs = (struct coreseg **)calloc(cf->chdr->c_nseg,
	    sizeof(cf->segs));
	if (cf->segs == NULL)
		err(1, "calloc");

	for (i = 0; i < cf->chdr->c_nseg; i++) {
		cf->segs[i] = (struct coreseg *)(core_map + c_off);
		if (CORE_GETMAGIC(*(cf->segs[i])) != CORESEGMAGIC)
			errx(1, "invalid segment hdr for segment %d", i);

		if (CORE_GETFLAG(*(cf->segs[i])) & CORE_CPU) {
			cf->regs = (struct reg *)
			    ((long) cf->segs[i] + cf->chdr->c_seghdrsize);
		}

		if (CORE_GETFLAG(*(cf->segs[i])) & CORE_STACK)
			cf->c_stack = cf->segs[i] + cf->chdr->c_seghdrsize;

		c_off += cf->chdr->c_seghdrsize + cf->segs[i]->c_size;

#ifdef DEBUG
		(void)printf("seg[%d]: midmag=0x%lx  addr=0x%lx  size=0x%lx\n",
		    i, cf->segs[i]->c_midmag, cf->segs[i]->c_addr,
		    cf->segs[i]->c_size);
#endif
	}

	cf->path = (char *)path;
	ps->ps_flags |= PSF_CORE;
	ps->ps_core = cf;

	return (0);
}