New style core dumps.

This commit is contained in:
pk 1994-05-25 10:56:56 +00:00
parent d9c1fc92c6
commit 7672b8b95b
13 changed files with 511 additions and 32 deletions

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1 1994/01/28 12:37:29 pk Exp $
# $Id: Makefile,v 1.2 1994/05/25 11:23:47 pk Exp $
LIB= bfd
NOPROFILE=
@ -11,7 +11,7 @@ CFLAGS+= -I$(.CURDIR)/arch/$(MACHINE_ARCH) -I$(.CURDIR) \
SRCS= archive.c archures.c bfd.c cache.c coffgen.c core.c ctor.c \
format.c init.c libbfd.c opncls.c reloc.c seclet.c section.c \
syms.c targets.c ecoff.c elf.c srec.c aout32.c \
stab-syms.c trad-core.c
stab-syms.c netbsd-core.c trad-core.c
.include "arch/$(MACHINE_ARCH)/Makefile.inc"

View File

@ -17,7 +17,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: aout-target.h,v 1.2 1994/04/29 20:46:50 pk Exp $
$Id: aout-target.h,v 1.3 1994/05/25 11:23:50 pk Exp $
*/
#include "aout/aout64.h"
@ -50,13 +50,16 @@ DEFUN(MY(callback),(abfd),
/*
* XXX - A few hacks to be able to read .o files and kernels.
* should probably be done in `netbsd.h' by better macro
* definitions (see also `include/aout/aout64.h')
*/
if ((execp->a_entry & ~(N_SEGSIZE(x)-1)) > obj_textsec (abfd)->vma) {
obj_textsec (abfd)->vma += (execp->a_entry & ~(N_SEGSIZE(x)-1)) - N_TXTADDR(*execp);
obj_datasec (abfd)->vma += (execp->a_entry & ~(N_SEGSIZE(x)-1)) - N_TXTADDR(*execp);
obj_bsssec (abfd)->vma += (execp->a_entry & ~(N_SEGSIZE(x)-1)) - N_TXTADDR(*execp);
}
if (execp->a_entry == 0 && N_MAGIC(*execp) == OMAGIC) {
if (execp->a_entry == 0 && N_MAGIC(*execp) == OMAGIC ||
execp->a_entry < N_SEGSIZE(x) && N_MAGIC(*execp) == ZMAGIC ) {
obj_textsec (abfd)->vma -= N_TXTADDR(*execp);
obj_datasec (abfd)->vma -= N_TXTADDR(*execp);
obj_bsssec (abfd)->vma -= N_TXTADDR(*execp);

View File

@ -1,8 +1,8 @@
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:17 pk Exp $
# $Id: Makefile.inc,v 1.2 1994/05/25 11:24:10 pk Exp $
SRCS+= netbsd386.c cpu-i386.c
CFLAGS+= -DTRAD_CORE
CFLAGS+= -DNETBSD_CORE -DTRAD_CORE
VECTORS= -DDEFAULT_VECTOR=netbsd_386_vec \
-DSELECT_ARCHITECTURES=bfd_i386_arch \

View File

@ -1,8 +1,8 @@
# $Id: Makefile.inc,v 1.1 1994/01/28 12:38:28 pk Exp $
# $Id: Makefile.inc,v 1.2 1994/05/25 11:24:14 pk Exp $
SRCS+= netbsd_sparc.c cpu-sparc.c
CFLAGS+= -DTRAD_CORE
CFLAGS+= -DNETBSD_CORE -DTRAD_CORE
VECTORS= -DDEFAULT_VECTOR=netbsd_sparc_vec \
-DSELECT_ARCHITECTURES=bfd_sparc_arch \

View File

@ -1,4 +1,4 @@
/* $Id: sysdep.h,v 1.2 1994/05/19 15:56:29 pk Exp $ */
/* $Id: sysdep.h,v 1.3 1994/05/25 11:24:16 pk Exp $ */
#ifndef hosts_sparc_H
#define hosts_sparc_H
@ -37,6 +37,9 @@
#define TRAD_UNIX_CORE_FILE_FAILING_SIGNAL(core_bfd) \
((core_bfd)->tdata.trad_core_data->u.u_sig)
#define u_comm u_kproc.kp_proc.p_comm
#define TRAD_CORE_REGPOS(core_bfd) ((bfd_vma)(core_bfd)->tdata.trad_core_data->u.u_kproc.kp_proc.p_md.md_tf)
#define TRAD_CORE_REGPOS(core_bfd) \
((bfd_vma)(core_bfd)->tdata.trad_core_data->u.u_kproc.kp_proc.p_md.md_tf)
#define CORE_FPU_OFFSET (sizeof(struct trapframe))
#endif

View File

@ -22,7 +22,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: bfd.h,v 1.2 1994/04/28 17:10:42 phil Exp $
$Id: bfd.h,v 1.3 1994/05/25 11:23:52 pk Exp $
*/
/* bfd.h -- The only header file required by users of the bfd library
@ -1562,6 +1562,7 @@ struct _bfd
struct sgi_core_struct *sgi_core_data;
struct lynx_core_struct *lynx_core_data;
struct osf_core_struct *osf_core_data;
struct netbsd_core_struct *netbsd_core_data;
PTR any;
} tdata;

View File

@ -0,0 +1,306 @@
/* BFD back end for NetBSD style core files
Copyright 1988, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
Written by Paul Kranenburg, EUR
This file is part of BFD, the Binary File Descriptor library.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: netbsd-core.c,v 1.1 1994/05/25 11:23:54 pk Exp $
*/
/* To use this file on a particular host, configure the host with these
parameters in the config/h-HOST file:
HDEFINES=-DNETBSD_CORE
HDEPFILES=netbsd-core.o
*/
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "libaout.h" /* BFD a.out internal data structures */
#include <stdio.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/core.h>
#include <errno.h>
struct netbsd_core_struct {
struct core core;
} *rawptr;
/* forward declarations */
bfd_target * netbsd_core_file_p PARAMS ((bfd *abfd));
char * netbsd_core_file_failing_command PARAMS ((bfd *abfd));
int netbsd_core_file_failing_signal PARAMS ((bfd *abfd));
boolean netbsd_core_file_matches_executable_p
PARAMS ((bfd *core_bfd, bfd *exec_bfd));
/* Handle NetBSD-style core dump file. */
/* ARGSUSED */
bfd_target *
netbsd_core_file_p (abfd)
bfd *abfd;
{
int i, val, offset;
asection *asect, *asect2;
struct core core;
struct coreseg coreseg;
val = bfd_read ((void *)&core, 1, sizeof core, abfd);
if (val != sizeof core) {
/* Too small to be a core file */
bfd_error = wrong_format;
return 0;
}
if (CORE_GETMAGIC(core) != COREMAGIC) {
bfd_error = wrong_format;
return 0;
}
rawptr = (struct netbsd_core_struct *)
bfd_zalloc (abfd, sizeof (struct netbsd_core_struct));
if (rawptr == NULL) {
bfd_error = no_memory;
return 0;
}
rawptr->core = core;
abfd->tdata.netbsd_core_data = rawptr;
offset = core.c_hdrsize;
for (i = 0; i < core.c_nseg; i++) {
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
goto punt;
val = bfd_read ((void *)&coreseg, 1, sizeof coreseg, abfd);
if (val != sizeof coreseg) {
bfd_error = file_truncated;
goto punt;
}
if (CORE_GETMAGIC(coreseg) != CORESEGMAGIC) {
bfd_error = wrong_format;
goto punt;
}
offset += core.c_seghdrsize;
asect = (asection *) zalloc (sizeof (asection));
if (asect == NULL) {
bfd_error = no_memory;
goto punt;
}
asect->_raw_size = coreseg.c_size;
asect->vma = coreseg.c_addr;
asect->filepos = offset;
asect->alignment_power = 2;
asect->next = abfd->sections;
abfd->sections = asect;
abfd->section_count++;
offset += coreseg.c_size;
switch (CORE_GETFLAG(coreseg)) {
case CORE_CPU:
asect->name = ".reg";
asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
#ifdef CORE_FPU_OFFSET
/* Hackish... */
asect->_raw_size = CORE_FPU_OFFSET;
asect2 = (asection *)zalloc (sizeof (asection));
if (asect2 == NULL) {
bfd_error = no_memory;
goto punt;
}
asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET;
asect2->vma = 0;
asect2->filepos = asect->filepos + CORE_FPU_OFFSET;
asect2->alignment_power = 2;
asect2->next = abfd->sections;
asect2->name = ".reg2";
asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
abfd->sections = asect2;
abfd->section_count++;
#endif
break;
case CORE_DATA:
asect->name = ".data";
asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
break;
case CORE_STACK:
asect->name = ".stack";
asect->flags = SEC_ALLOC+SEC_LOAD+SEC_HAS_CONTENTS;
break;
}
}
/* OK, we believe you. You're a core file (sure, sure). */
return abfd->xvec;
punt: {
asection *anext;
for (asect = abfd->sections; asect; asect = anext) {
anext = asect->next;
free((void *)asect);
}
}
free ((void *)rawptr);
abfd->tdata.netbsd_core_data = NULL;
abfd->sections = NULL;
abfd->section_count = 0;
return 0;
}
char *
netbsd_core_file_failing_command (abfd)
bfd *abfd;
{
return abfd->tdata.netbsd_core_data->core.c_name;
}
/* ARGSUSED */
int
netbsd_core_file_failing_signal (abfd)
bfd *abfd;
{
return abfd->tdata.netbsd_core_data->core.c_signo;
}
/* ARGSUSED */
boolean
netbsd_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd, *exec_bfd;
{
return true; /* FIXME, We have no way of telling at this point */
}
/* No archive file support via this BFD */
#define netbsd_openr_next_archived_file bfd_generic_openr_next_archived_file
#define netbsd_generic_stat_arch_elt bfd_generic_stat_arch_elt
#define netbsd_slurp_armap bfd_false
#define netbsd_slurp_extended_name_table bfd_true
#define netbsd_write_armap (boolean (*) PARAMS \
((bfd *arch, unsigned int elength, struct orl *map, \
unsigned int orl_count, int stridx))) bfd_false
#define netbsd_truncate_arname bfd_dont_truncate_arname
#define aout_32_openr_next_archived_file bfd_generic_openr_next_archived_file
#define netbsd_close_and_cleanup bfd_generic_close_and_cleanup
#define netbsd_set_section_contents (boolean (*) PARAMS \
((bfd *abfd, asection *section, PTR data, file_ptr offset, \
bfd_size_type count))) bfd_false
#define netbsd_get_section_contents bfd_generic_get_section_contents
#define netbsd_new_section_hook (boolean (*) PARAMS \
((bfd *, sec_ptr))) bfd_true
#define netbsd_get_symtab_upper_bound bfd_0u
#define netbsd_get_symtab (unsigned int (*) PARAMS \
((bfd *, struct symbol_cache_entry **))) bfd_0u
#define netbsd_get_reloc_upper_bound (unsigned int (*) PARAMS \
((bfd *, sec_ptr))) bfd_0u
#define netbsd_canonicalize_reloc (unsigned int (*) PARAMS \
((bfd *, sec_ptr, arelent **, struct symbol_cache_entry**))) bfd_0u
#define netbsd_make_empty_symbol (struct symbol_cache_entry * \
(*) PARAMS ((bfd *))) bfd_false
#define netbsd_print_symbol (void (*) PARAMS \
((bfd *, PTR, struct symbol_cache_entry *, \
bfd_print_symbol_type))) bfd_false
#define netbsd_get_symbol_info (void (*) PARAMS \
((bfd *, struct symbol_cache_entry *, \
symbol_info *))) bfd_false
#define netbsd_get_lineno (alent * (*) PARAMS \
((bfd *, struct symbol_cache_entry *))) bfd_nullvoidptr
#define netbsd_set_arch_mach (boolean (*) PARAMS \
((bfd *, enum bfd_architecture, unsigned long))) bfd_false
#define netbsd_find_nearest_line (boolean (*) PARAMS \
((bfd *abfd, struct sec *section, \
struct symbol_cache_entry **symbols,bfd_vma offset, \
CONST char **file, CONST char **func, unsigned int *line))) bfd_false
#define netbsd_sizeof_headers (int (*) PARAMS \
((bfd *, boolean))) bfd_0
#define netbsd_bfd_debug_info_start bfd_void
#define netbsd_bfd_debug_info_end bfd_void
#define netbsd_bfd_debug_info_accumulate (void (*) PARAMS \
((bfd *, struct sec *))) bfd_void
#define netbsd_bfd_get_relocated_section_contents bfd_generic_get_relocated_section_contents
#define netbsd_bfd_relax_section bfd_generic_relax_section
#define netbsd_bfd_seclet_link \
((boolean (*) PARAMS ((bfd *, PTR, boolean))) bfd_false)
#define netbsd_bfd_reloc_type_lookup \
((CONST struct reloc_howto_struct *(*) PARAMS ((bfd *, bfd_reloc_code_real_type))) bfd_nullvoidptr)
#define netbsd_bfd_make_debug_symbol \
((asymbol *(*) PARAMS ((bfd *, void *, unsigned long))) bfd_nullvoidptr)
/* If somebody calls any byte-swapping routines, shoot them. */
void
netbsd_swap_abort()
{
abort(); /* This way doesn't require any declaration for ANSI to fuck up */
}
#define NO_GET ((bfd_vma (*) PARAMS (( bfd_byte *))) netbsd_swap_abort )
#define NO_PUT ((void (*) PARAMS ((bfd_vma, bfd_byte *))) netbsd_swap_abort )
#define NO_SIGNED_GET ((bfd_signed_vma (*) PARAMS ((bfd_byte *))) netbsd_swap_abort )
bfd_target netbsd_core_vec =
{
"netbsd-core",
bfd_target_unknown_flavour,
true, /* target byte order */
true, /* target headers byte order */
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | DYNAMIC | WP_TEXT | D_PAGED),
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
0, /* symbol prefix */
' ', /* ar_pad_char */
16, /* ar_max_namelen */
3, /* minimum alignment power */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit data */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit data */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit data */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 64 bit hdrs */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 32 bit hdrs */
NO_GET, NO_SIGNED_GET, NO_PUT, /* 16 bit hdrs */
{ /* bfd_check_format */
_bfd_dummy_target, /* unknown format */
_bfd_dummy_target, /* object file */
_bfd_dummy_target, /* archive */
netbsd_core_file_p /* a core file */
},
{ /* bfd_set_format */
bfd_false, bfd_false,
bfd_false, bfd_false
},
{ /* bfd_write_contents */
bfd_false, bfd_false,
bfd_false, bfd_false
},
JUMP_TABLE(netbsd),
(PTR) 0 /* backend_data */
};

View File

@ -18,7 +18,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: targets.c,v 1.3 1994/04/28 17:10:45 phil Exp $
$Id: targets.c,v 1.4 1994/05/25 11:23:56 pk Exp $
*/
#include "bfd.h"
@ -396,6 +396,7 @@ extern bfd_target aix386_core_vec;
extern bfd_target hpux_core_vec;
extern bfd_target osf_core_vec;
extern bfd_target sco_core_vec;
extern bfd_target netbsd_core_vec;
extern bfd_target trad_core_vec;
bfd_target *target_vector[] = {
@ -529,6 +530,9 @@ bfd_target *target_vector[] = {
#ifdef SCO_CORE
&sco_core_vec,
#endif
#ifdef NETBSD_CORE
&netbsd_core_vec,
#endif
#ifdef TRAD_CORE
&trad_core_vec,
#endif

View File

@ -17,7 +17,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: solib.c,v 1.1 1994/01/28 12:40:39 pk Exp $
$Id: solib.c,v 1.2 1994/05/25 11:24:26 pk Exp $
*/
@ -703,7 +703,8 @@ find_solib (so_list_ptr)
{
if (!target_read_string((CORE_ADDR) LM_NAME (new), new -> so_name,
MAX_PATH_SIZE - 1))
error ("find_solib: Can't read pathname for load map\n");
error ("find_solib: Can't read pathname for load map at %#x\n",
(u_long)LM_NAME (new));
new -> so_name[MAX_PATH_SIZE - 1] = 0;
solib_map_sections (new);
}

View File

@ -50,14 +50,20 @@
#include <sys/vnode.h>
#include <sys/buf.h>
#include <sys/user.h>
#include <sys/core.h>
#include <sys/exec.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
#include <machine/reg.h>
#include "npx.h"
#if NNPX > 0
extern struct proc *npxproc;
#endif
/*
* Finish a fork operation, with process p2 nearly set up.
@ -124,9 +130,8 @@ cpu_exit(p)
{
extern int _default_ldt, currentldt;
struct vmspace *vm;
#if NNPX > 0
extern struct proc *npxproc;
if (npxproc == p)
npxexit();
#endif
@ -147,17 +152,54 @@ cpu_exit(p)
}
/*
* Dump the machine specific header information at the start of a core dump.
* Dump the machine specific segment at the start of a core dump.
*/
cpu_coredump(p, vp, cred)
int
cpu_coredump(p, vp, cred, chdr)
struct proc *p;
struct vnode *vp;
struct ucred *cred;
struct core *chdr;
{
int error;
register struct user *up = p->p_addr;
struct cpustate {
struct trapframe regs;
struct save87 fpstate;
} cpustate;
struct coreseg cseg;
return (vn_rdwr(UIO_WRITE, vp, (caddr_t) p->p_addr, ctob(UPAGES),
(off_t)0, UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL,
p));
CORE_SETMAGIC(*chdr, COREMAGIC, MID_I386, 0);
chdr->c_hdrsize = ALIGN(sizeof(*chdr));
chdr->c_seghdrsize = ALIGN(sizeof(cseg));
chdr->c_cpusize = sizeof(cpustate);
cpustate.regs = *(struct trapframe *)p->p_md.md_regs;
#if NNPX > 0
if (p == npxproc)
npxsave(&cpustate.fpstate); /* ??? */
else
#endif
bzero((caddr_t)&cpustate.fpstate, sizeof(cpustate.fpstate));
CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_I386, CORE_CPU);
cseg.c_addr = 0;
cseg.c_size = chdr->c_cpusize;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
(off_t)chdr->c_hdrsize, UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cpustate, sizeof(cpustate),
(off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
if (!error)
chdr->c_nseg++;
return error;
}
/*

View File

@ -42,13 +42,14 @@
* @(#)vm_machdep.c 8.1 (Berkeley) 6/11/93
*
* from: Header: vm_machdep.c,v 1.10 92/11/26 03:05:11 torek Exp (LBL)
* $Id: vm_machdep.c,v 1.6 1994/05/24 03:33:38 deraadt Exp $
* $Id: vm_machdep.c,v 1.7 1994/05/25 10:59:09 pk Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/core.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/exec.h>
@ -271,18 +272,44 @@ cpu_exit(p)
* (should this be defined elsewhere? machdep.c?)
*/
int
cpu_coredump(p, vp, cred)
cpu_coredump(p, vp, cred, chdr)
struct proc *p;
struct vnode *vp;
struct ucred *cred;
struct core *chdr;
{
int error;
register struct user *up = p->p_addr;
struct md_coredump md_core;
struct coreseg cseg;
up->u_md.md_tf = *p->p_md.md_tf;
if (p->p_md.md_fpstate)
up->u_md.md_fpstate = *p->p_md.md_fpstate;
else
bzero((caddr_t)&up->u_md.md_fpstate, sizeof(struct fpstate));
return (vn_rdwr(UIO_WRITE, vp, (caddr_t)up, ctob(UPAGES), (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p));
CORE_SETMAGIC(*chdr, COREMAGIC, MID_SPARC, 0);
chdr->c_hdrsize = ALIGN(sizeof(*chdr));
chdr->c_seghdrsize = ALIGN(sizeof(cseg));
chdr->c_cpusize = sizeof(md_core);
md_core.md_tf = *p->p_md.md_tf;
if (p->p_md.md_fpstate) {
if (p == fpproc)
savefpstate(p->p_md.md_fpstate);
md_core.md_fpstate = *p->p_md.md_fpstate;
} else
bzero((caddr_t)&md_core.md_fpstate, sizeof(struct fpstate));
CORE_SETMAGIC(cseg, CORESEGMAGIC, MID_SPARC, CORE_CPU);
cseg.c_addr = 0;
cseg.c_size = chdr->c_cpusize;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&cseg, chdr->c_seghdrsize,
(off_t)chdr->c_hdrsize, UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t)&md_core, sizeof(md_core),
(off_t)(chdr->c_hdrsize + chdr->c_seghdrsize), UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *)NULL, p);
if (!error)
chdr->c_nseg++;
return error;
}

View File

@ -1 +1 @@
revision 1.26 intentionally removed
revision 1.27 intentionally removed

View File

@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_unix.c 1.1 89/11/07$
*
* from: @(#)vm_unix.c 8.1 (Berkeley) 6/11/93
* $Id: vm_unix.c,v 1.10 1994/05/23 03:12:09 cgd Exp $
* $Id: vm_unix.c,v 1.11 1994/05/25 10:56:56 pk Exp $
*/
/*
@ -48,6 +48,8 @@
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/vnode.h>
#include <sys/core.h>
#include <vm/vm.h>
@ -136,3 +138,93 @@ ovadvise(p, uap, retval)
return (EINVAL);
}
int
vm_coredump(p, vp, cred, chdr)
struct proc *p;
struct vnode *vp;
struct ucred *cred;
struct core *chdr;
{
register struct vmspace *vm = p->p_vmspace;
register vm_map_t map = &vm->vm_map;
register vm_map_entry_t entry;
vm_offset_t start, end;
struct coreseg cseg;
off_t offset;
int flag, error = 0;
if (!map->is_main_map) {
#ifdef DEBUG
uprintf(
"vm_coredump: %s map 0x%x: pmap=0x%x,ref=%d,nentries=%d,version=%d\n",
(map->is_main_map ? "Task" : "Share"),
(int)map, (int)(map->pmap),
map->ref_count, map->nentries,
map->timestamp);
#endif
return EIO;
}
offset = chdr->c_hdrsize + chdr->c_seghdrsize + chdr->c_cpusize;
for (entry = map->header.next; entry != &map->header;
entry = entry->next) {
if (entry->is_a_map || entry->is_sub_map) {
#ifdef DEBUG
uprintf("vm_coredump: entry: share=0x%x, offset=0x%x\n",
(int) entry->object.share_map,
(int) entry->offset);
#endif
continue;
}
if (!(entry->protection & VM_PROT_WRITE))
continue;
start = entry->start;
end = entry->end;
if (start >= VM_MAXUSER_ADDRESS)
continue;
if (end > VM_MAXUSER_ADDRESS)
end = VM_MAXUSER_ADDRESS;
if (start >= (vm_offset_t)vm->vm_maxsaddr) {
flag = CORE_STACK;
start = trunc_page(USRSTACK - ctob(vm->vm_ssize));
if (start >= end)
continue;
} else
flag = CORE_DATA;
/*
* Set up a new core file segment.
*/
CORE_SETMAGIC(cseg, CORESEGMAGIC, CORE_GETMID(*chdr), flag);
cseg.c_addr = start;
cseg.c_size = end - start;
error = vn_rdwr(UIO_WRITE, vp,
(caddr_t)&cseg, chdr->c_seghdrsize,
offset, UIO_SYSSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
if (error)
break;
offset += chdr->c_seghdrsize;
error = vn_rdwr(UIO_WRITE, vp,
(caddr_t)cseg.c_addr, (int)cseg.c_size,
offset, UIO_USERSPACE,
IO_NODELOCKED|IO_UNIT, cred, (int *) NULL, p);
if (error)
break;
offset += cseg.c_size;
chdr->c_nseg++;
}
return error;
}