Annotation of src/usr.bin/pmdb/core.c, Revision 1.7
1.7 ! deraadt 1: /* $OpenBSD: core.c,v 1.6 2003/08/17 23:43:45 mickey 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"
1.4 mickey 41: #include "symbol.h"
1.1 fgsch 42:
43: int
44: read_core(const char *path, struct pstate *ps)
45: {
46: struct corefile *cf;
47: void *core_map;
48: off_t c_off;
49: int i, cfd;
50:
51: cf = (struct corefile *)malloc(sizeof(*cf));
52: if (cf == NULL)
53: err(1, "malloc");
54:
55: cfd = open(path, O_RDONLY, 0600);
56: if (cfd < 0)
57: err(1, "open() failed on core file");
58:
59: if (fstat(cfd, &(cf->cfstat)) < 0)
60: err(1, "fstat() failed on core");
61:
62: if (cf->cfstat.st_mtimespec.tv_sec < ps->exec_stat.st_mtimespec.tv_sec)
63: warnx("executable is more recent than core file!");
64:
1.3 art 65: core_map = mmap(NULL, cf->cfstat.st_size, PROT_READ, MAP_PRIVATE,
1.1 fgsch 66: cfd, 0);
67: if (core_map == MAP_FAILED)
68: err(1, "mmap() failed on core");
1.7 ! deraadt 69: close(cfd);
1.1 fgsch 70:
71: cf->chdr = (struct core *)core_map;
72: c_off = cf->chdr->c_hdrsize;
73: if (CORE_GETMAGIC(*(cf->chdr)) != COREMAGIC)
74: errx(1, "hey, that's not a core file");
75:
76: printf("Core file generated from '%s' by signal %d (SIG%s)\n",
77: cf->chdr->c_name, cf->chdr->c_signo,
78: sys_signame[cf->chdr->c_signo]);
79:
80: #ifdef DEBUG
81: printf("Core: text=0x%lx, data=0x%lx, stack=0x%lx\n",
82: cf->chdr->c_tsize, cf->chdr->c_dsize, cf->chdr->c_ssize);
83: #endif
84:
85: cf->segs = (struct coreseg **)calloc(cf->chdr->c_nseg,
86: sizeof(cf->segs));
87: if (cf->segs == NULL)
88: err(1, "calloc");
89:
90: for (i = 0; i < cf->chdr->c_nseg; i++) {
91: cf->segs[i] = (struct coreseg *)(core_map + c_off);
92: if (CORE_GETMAGIC(*(cf->segs[i])) != CORESEGMAGIC)
93: errx(1, "invalid segment hdr for segment %d", i);
94:
95: if (CORE_GETFLAG(*(cf->segs[i])) & CORE_CPU) {
96: cf->regs = (struct reg *)
97: ((long) cf->segs[i] + cf->chdr->c_seghdrsize);
98: }
99:
100: if (CORE_GETFLAG(*(cf->segs[i])) & CORE_STACK)
101: cf->c_stack = cf->segs[i] + cf->chdr->c_seghdrsize;
102:
103: c_off += cf->chdr->c_seghdrsize + cf->segs[i]->c_size;
104:
105: #ifdef DEBUG
106: (void)printf("seg[%d]: midmag=0x%lx addr=0x%lx size=0x%lx\n",
107: i, cf->segs[i]->c_midmag, cf->segs[i]->c_addr,
108: cf->segs[i]->c_size);
109: #endif
110: }
111:
112: cf->path = (char *)path;
113: ps->ps_flags |= PSF_CORE;
114: ps->ps_core = cf;
115:
116: return (0);
117: }
118:
119: void
120: free_core(struct pstate *ps)
121: {
122: struct corefile *cf = ps->ps_core;
123:
124: if (cf == NULL)
125: return;
126:
127: if (cf->segs != NULL) {
128: free(cf->segs);
129: cf->segs = NULL;
130: }
131: }
132:
133: void
1.4 mickey 134: core_printregs(struct pstate *ps)
1.1 fgsch 135: {
1.4 mickey 136: struct corefile *cf = ps->ps_core;
1.1 fgsch 137: reg *rg;
1.4 mickey 138: char buf[256];
1.1 fgsch 139: int i;
140:
141: rg = (reg *)cf->regs;
142: for (i = 0; i < md_def.nregs; i++)
1.4 mickey 143: printf("%s:\t0x%.*lx\t%s\n", md_def.md_reg_names[i],
144: (int)(sizeof(reg) * 2), (long) rg[i],
145: sym_print(ps, rg[i], buf, sizeof(buf)));
1.2 art 146: }
147:
148:
149: ssize_t
150: core_read(struct pstate *ps, off_t from, void *to, size_t size)
151: {
1.3 art 152: struct coreseg *cs;
1.2 art 153: size_t read;
154: void *fp;
1.3 art 155: int i;
1.2 art 156:
157: for (i = 0; i < ps->ps_core->chdr->c_nseg; i++) {
158: cs = ps->ps_core->segs[i];
1.5 mickey 159: if ((from >= cs->c_addr) &&
160: (from < (cs->c_addr + cs->c_size))) {
1.2 art 161: read = size;
1.5 mickey 162: if ((from + size) > (cs->c_addr + cs->c_size))
163: read = (cs->c_addr + cs->c_size) - from;
164: fp = (void *)cs + sizeof(*cs) +
165: ((u_long)from - cs->c_addr);
1.2 art 166: memcpy(to, fp, read);
1.3 art 167: return (read);
1.2 art 168: }
169: }
170:
171: return (-1);
172: }
173:
174:
175: ssize_t
176: core_write(struct pstate *ps, off_t to, void *from, size_t size)
177: {
1.3 art 178: struct coreseg *cs;
1.2 art 179: size_t written;
180: void *fp;
1.3 art 181: int i;
1.2 art 182:
183: for (i = 0; i < ps->ps_core->chdr->c_nseg; i++) {
184: cs = ps->ps_core->segs[i];
185: if ((to > cs->c_addr) && (to < (cs->c_addr + cs->c_size))) {
186: written = size;
1.6 mickey 187: fp = (void *)cs + sizeof(*cs) + (to - cs->c_addr);
1.2 art 188: memcpy(fp, from, written);
1.3 art 189: return (written);
1.2 art 190: }
191: }
192:
193: return (-1);
1.1 fgsch 194: }