Annotation of src/usr.bin/pmdb/core.c, Revision 1.3
1.3 ! art 1: /* $OpenBSD: core.c,v 1.2 2002/07/22 01:20:50 art Exp $ */
1.1 fgsch 2: /*
3: * Copyright (c) 2002 Jean-Francois Brousseau <krapht@secureops.com>
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. The name of the author may not be used to endorse or promote products
13: * derived from this software without specific prior written permission.
14: *
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: #include <sys/param.h>
28: #include <sys/stat.h>
29: #include <sys/mman.h>
30:
31: #include <err.h>
32: #include <stdio.h>
33: #include <fcntl.h>
34: #include <string.h>
35: #include <stdlib.h>
36: #include <signal.h>
37: #include <unistd.h>
38:
39: #include "core.h"
40: #include "pmdb.h"
41:
42: int
43: read_core(const char *path, struct pstate *ps)
44: {
45: struct corefile *cf;
46: void *core_map;
47: off_t c_off;
48: int i, cfd;
49:
50: cf = (struct corefile *)malloc(sizeof(*cf));
51: if (cf == NULL)
52: err(1, "malloc");
53:
54: cfd = open(path, O_RDONLY, 0600);
55: if (cfd < 0)
56: err(1, "open() failed on core file");
57:
58: if (fstat(cfd, &(cf->cfstat)) < 0)
59: err(1, "fstat() failed on core");
60:
61: if (cf->cfstat.st_mtimespec.tv_sec < ps->exec_stat.st_mtimespec.tv_sec)
62: warnx("executable is more recent than core file!");
63:
1.3 ! art 64: core_map = mmap(NULL, cf->cfstat.st_size, PROT_READ, MAP_PRIVATE,
1.1 fgsch 65: cfd, 0);
66: if (core_map == MAP_FAILED)
67: err(1, "mmap() failed on core");
68:
69: cf->chdr = (struct core *)core_map;
70: c_off = cf->chdr->c_hdrsize;
71: if (CORE_GETMAGIC(*(cf->chdr)) != COREMAGIC)
72: errx(1, "hey, that's not a core file");
73:
74: printf("Core file generated from '%s' by signal %d (SIG%s)\n",
75: cf->chdr->c_name, cf->chdr->c_signo,
76: sys_signame[cf->chdr->c_signo]);
77:
78: #ifdef DEBUG
79: printf("Core: text=0x%lx, data=0x%lx, stack=0x%lx\n",
80: cf->chdr->c_tsize, cf->chdr->c_dsize, cf->chdr->c_ssize);
81: #endif
82:
83: cf->segs = (struct coreseg **)calloc(cf->chdr->c_nseg,
84: sizeof(cf->segs));
85: if (cf->segs == NULL)
86: err(1, "calloc");
87:
88: for (i = 0; i < cf->chdr->c_nseg; i++) {
89: cf->segs[i] = (struct coreseg *)(core_map + c_off);
90: if (CORE_GETMAGIC(*(cf->segs[i])) != CORESEGMAGIC)
91: errx(1, "invalid segment hdr for segment %d", i);
92:
93: if (CORE_GETFLAG(*(cf->segs[i])) & CORE_CPU) {
94: cf->regs = (struct reg *)
95: ((long) cf->segs[i] + cf->chdr->c_seghdrsize);
96: }
97:
98: if (CORE_GETFLAG(*(cf->segs[i])) & CORE_STACK)
99: cf->c_stack = cf->segs[i] + cf->chdr->c_seghdrsize;
100:
101: c_off += cf->chdr->c_seghdrsize + cf->segs[i]->c_size;
102:
103: #ifdef DEBUG
104: (void)printf("seg[%d]: midmag=0x%lx addr=0x%lx size=0x%lx\n",
105: i, cf->segs[i]->c_midmag, cf->segs[i]->c_addr,
106: cf->segs[i]->c_size);
107: #endif
108: }
109:
110: cf->path = (char *)path;
111: ps->ps_flags |= PSF_CORE;
112: ps->ps_core = cf;
113:
114: return (0);
115: }
116:
117: void
118: free_core(struct pstate *ps)
119: {
120: struct corefile *cf = ps->ps_core;
121:
122: if (cf == NULL)
123: return;
124:
125: if (cf->segs != NULL) {
126: free(cf->segs);
127: cf->segs = NULL;
128: }
129: }
130:
131: void
132: core_printregs(struct corefile *cf)
133: {
134: reg *rg;
135: int i;
136:
137: rg = (reg *)cf->regs;
138: for (i = 0; i < md_def.nregs; i++)
139: printf("%s:\t0x%.*lx\n", md_def.md_reg_names[i],
140: (int)(sizeof(reg) * 2), (long) rg[i]);
1.2 art 141: }
142:
143:
144: ssize_t
145: core_read(struct pstate *ps, off_t from, void *to, size_t size)
146: {
1.3 ! art 147: struct coreseg *cs;
1.2 art 148: size_t read;
149: void *fp;
1.3 ! art 150: int i;
1.2 art 151:
152: for (i = 0; i < ps->ps_core->chdr->c_nseg; i++) {
153: cs = ps->ps_core->segs[i];
154: if ((from >= cs->c_addr) && (from < (cs->c_addr + cs->c_size))) {
155: read = size;
1.3 ! art 156: fp = cs + sizeof(*cs) + ((u_long)from - cs->c_addr);
1.2 art 157: memcpy(to, fp, read);
1.3 ! art 158: return (read);
1.2 art 159: }
160: }
161:
162: return (-1);
163: }
164:
165:
166: ssize_t
167: core_write(struct pstate *ps, off_t to, void *from, size_t size)
168: {
1.3 ! art 169: struct coreseg *cs;
1.2 art 170: size_t written;
171: void *fp;
1.3 ! art 172: int i;
1.2 art 173:
174: for (i = 0; i < ps->ps_core->chdr->c_nseg; i++) {
175: cs = ps->ps_core->segs[i];
176: if ((to > cs->c_addr) && (to < (cs->c_addr + cs->c_size))) {
177: written = size;
178: fp = cs + sizeof(*cs) + (to - cs->c_addr);
179: memcpy(fp, from, written);
1.3 ! art 180: return (written);
1.2 art 181: }
182: }
183:
184: return (-1);
1.1 fgsch 185: }