xref: /llvm-project/lldb/test/API/functionalities/postmortem/FreeBSDKernel/tools/libfbsdvmcore-hacks.patch (revision 9b1d27b2fa727a3a6f53a803d75beed50a1be999)
1diff --git a/CMakeLists.txt b/CMakeLists.txt
2index 53b401a..ccb289e 100644
3--- a/CMakeLists.txt
4+++ b/CMakeLists.txt
5@@ -94,6 +94,7 @@ install(
6     man/fvc_kerndisp.3
7     man/fvc_open.3
8     man/fvc_read.3
9+    man/fvc_write.3
10     DESTINATION "${CMAKE_INSTALL_MANDIR}/man3")
11
12 install(
13diff --git a/lib/fvc.c b/lib/fvc.c
14index e6b96c1..cac7158 100644
15--- a/lib/fvc.c
16+++ b/lib/fvc.c
17@@ -154,7 +154,7 @@ _fvc_open(fvc_t *kd, const char *uf, const char *mf, char *errout)
18 		goto failed;
19 	}
20
21-	if ((kd->pmfd = open(mf, O_RDONLY | O_CLOEXEC, 0)) < 0) {
22+	if ((kd->pmfd = open(mf, O_RDWR | O_CLOEXEC, 0)) < 0) {
23 		_fvc_syserr(kd, kd->program, "%s", mf);
24 		goto failed;
25 	}
26@@ -297,6 +297,47 @@ fvc_read(fvc_t *kd, fvc_addr_t kva, void *buf, size_t len)
27 			_fvc_syserr(kd, kd->program, "fvc_read");
28 			break;
29 		}
30+		printf("%% RD: %zu %d\n", pa, cc);
31+		/*
32+		 * If ka_kvatop returns a bogus value or our core file is
33+		 * truncated, we might wind up seeking beyond the end of the
34+		 * core file in which case the read will return 0 (EOF).
35+		 */
36+		if (cr == 0)
37+			break;
38+		cp += cr;
39+		kva += cr;
40+		len -= cr;
41+	}
42+
43+	return (cp - (char *)buf);
44+}
45+
46+ssize_t
47+fvc_write(fvc_t *kd, fvc_addr_t kva, const void *buf, size_t len)
48+{
49+	int cc;
50+	ssize_t cr;
51+	off_t pa;
52+	const char *cp;
53+
54+	cp = buf;
55+	while (len > 0) {
56+		cc = kd->arch->ka_kvatop(kd, kva, &pa);
57+		if (cc == 0)
58+			return (-1);
59+		if (cc > (ssize_t)len)
60+			cc = len;
61+		errno = 0;
62+		if (lseek(kd->pmfd, pa, 0) == -1 && errno != 0) {
63+			_fvc_syserr(kd, 0, _PATH_MEM);
64+			break;
65+		}
66+		cr = write(kd->pmfd, cp, cc);
67+		if (cr < 0) {
68+			_fvc_syserr(kd, kd->program, "fvc_write");
69+			break;
70+		}
71 		/*
72 		 * If ka_kvatop returns a bogus value or our core file is
73 		 * truncated, we might wind up seeking beyond the end of the
74@@ -331,3 +372,8 @@ fvc_kerndisp(fvc_t *kd)
75
76 	return (kd->arch->ka_kerndisp(kd));
77 }
78+
79+ssize_t xpread(int fd, void *buf, size_t count, off_t offset) {
80+	printf("%% RD: %zu %zu\n", offset, count);
81+	return pread(fd, buf, count, offset);
82+}
83diff --git a/lib/fvc.h b/lib/fvc.h
84index 8680079..8cff17c 100644
85--- a/lib/fvc.h
86+++ b/lib/fvc.h
87@@ -54,6 +54,8 @@ typedef unsigned char fvc_vm_prot_t;
88 #define	FVC_VM_PROT_WRITE		((fvc_vm_prot_t) 0x02)
89 #define	FVC_VM_PROT_EXECUTE		((fvc_vm_prot_t) 0x04)
90
91+ssize_t xpread(int fd, void *buf, size_t count, off_t offset);
92+
93 struct fvc_page {
94 	unsigned int	kp_version;
95 	fvc_addr_t	kp_paddr;
96@@ -76,6 +78,7 @@ fvc_t	 *fvc_open
97 	    (const char *, const char *, char *,
98 	    int (*)(const char *, fvc_addr_t *, void *), void *);
99 ssize_t	  fvc_read(fvc_t *, fvc_addr_t, void *, size_t);
100+ssize_t	  fvc_write(fvc_t *, fvc_addr_t, const void *, size_t);
101 ssize_t   fvc_kerndisp(fvc_t *);
102
103 typedef int fvc_walk_pages_cb_t(struct fvc_page *, void *);
104diff --git a/lib/fvc_amd64.c b/lib/fvc_amd64.c
105index 4d27998..69f1807 100644
106--- a/lib/fvc_amd64.c
107+++ b/lib/fvc_amd64.c
108@@ -205,7 +205,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
109 		_fvc_err(kd, kd->program, "_amd64_vatop: pdpe_pa not found");
110 		goto invalid;
111 	}
112-	if (pread(kd->pmfd, &pdpe, sizeof(pdpe), ofs) != sizeof(pdpe)) {
113+	if (xpread(kd->pmfd, &pdpe, sizeof(pdpe), ofs) != sizeof(pdpe)) {
114 		_fvc_syserr(kd, kd->program, "_amd64_vatop: read pdpe");
115 		goto invalid;
116 	}
117@@ -237,7 +237,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
118 		_fvc_syserr(kd, kd->program, "_amd64_vatop: pde_pa not found");
119 		goto invalid;
120 	}
121-	if (pread(kd->pmfd, &pde, sizeof(pde), ofs) != sizeof(pde)) {
122+	if (xpread(kd->pmfd, &pde, sizeof(pde), ofs) != sizeof(pde)) {
123 		_fvc_syserr(kd, kd->program, "_amd64_vatop: read pde");
124 		goto invalid;
125 	}
126@@ -269,7 +269,7 @@ _amd64_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
127 		_fvc_err(kd, kd->program, "_amd64_vatop: pte_pa not found");
128 		goto invalid;
129 	}
130-	if (pread(kd->pmfd, &pte, sizeof(pte), ofs) != sizeof(pte)) {
131+	if (xpread(kd->pmfd, &pte, sizeof(pte), ofs) != sizeof(pte)) {
132 		_fvc_syserr(kd, kd->program, "_amd64_vatop: read");
133 		goto invalid;
134 	}
135diff --git a/lib/fvc_minidump_aarch64.c b/lib/fvc_minidump_aarch64.c
136index 4b8477a..a1c5b42 100644
137--- a/lib/fvc_minidump_aarch64.c
138+++ b/lib/fvc_minidump_aarch64.c
139@@ -86,7 +86,7 @@ _aarch64_minidump_initvtop(fvc_t *kd)
140 		return (-1);
141 	}
142 	kd->vmst = vmst;
143-	if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
144+	if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
145 	    sizeof(vmst->hdr)) {
146 		_fvc_err(kd, kd->program, "cannot read dump header");
147 		return (-1);
148diff --git a/lib/fvc_minidump_amd64.c b/lib/fvc_minidump_amd64.c
149index 93e8238..0d2237f 100644
150--- a/lib/fvc_minidump_amd64.c
151+++ b/lib/fvc_minidump_amd64.c
152@@ -126,7 +126,7 @@ _amd64_minidump_initvtop(fvc_t *kd)
153 		return (-1);
154 	}
155 	kd->vmst = vmst;
156-	if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
157+	if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
158 	    sizeof(vmst->hdr)) {
159 		_fvc_err(kd, kd->program, "cannot read dump header");
160 		return (-1);
161@@ -269,7 +269,7 @@ _amd64_minidump_vatop(fvc_t *kd, fvc_addr_t va, off_t *pa)
162 				    (uintmax_t)a);
163 				goto invalid;
164 			}
165-			if (pread(kd->pmfd, &pt, AMD64_PAGE_SIZE, ofs) !=
166+			if (xpread(kd->pmfd, &pt, AMD64_PAGE_SIZE, ofs) !=
167 			    AMD64_PAGE_SIZE) {
168 				_fvc_err(kd, kd->program,
169 				    "cannot read page table entry for %ju",
170diff --git a/lib/fvc_minidump_i386.c b/lib/fvc_minidump_i386.c
171index 61cc3db..b3ab955 100644
172--- a/lib/fvc_minidump_i386.c
173+++ b/lib/fvc_minidump_i386.c
174@@ -94,7 +94,7 @@ _i386_minidump_initvtop(fvc_t *kd)
175 		return (-1);
176 	}
177 	kd->vmst = vmst;
178-	if (pread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
179+	if (xpread(kd->pmfd, &vmst->hdr, sizeof(vmst->hdr), 0) !=
180 	    sizeof(vmst->hdr)) {
181 		_fvc_err(kd, kd->program, "cannot read dump header");
182 		return (-1);
183diff --git a/lib/fvc_private.c b/lib/fvc_private.c
184index 0069a54..fc798fe 100644
185--- a/lib/fvc_private.c
186+++ b/lib/fvc_private.c
187@@ -130,7 +130,7 @@ _fvc_is_minidump(fvc_t *kd)
188 {
189 	char minihdr[8];
190
191-	if (pread(kd->pmfd, &minihdr, 8, 0) == 8 &&
192+	if (xpread(kd->pmfd, &minihdr, 8, 0) == 8 &&
193 	    memcmp(&minihdr, "minidump", 8) == 0)
194 		return (1);
195 	return (0);
196@@ -256,6 +256,7 @@ _fvc_pmap_get(fvc_t *kd, u_long idx, size_t len)
197
198 	if ((off_t)off >= kd->pt_sparse_off)
199 		return (NULL);
200+	printf("%% RD: %zu %zu\n", kd->page_map_off+off, len);
201 	return (void *)((uintptr_t)kd->page_map + off);
202 }
203
204@@ -270,8 +271,13 @@ _fvc_map_get(fvc_t *kd, u_long pa, unsigned int page_size)
205 		return NULL;
206
207 	addr = (uintptr_t)kd->page_map + off;
208-	if (off >= kd->pt_sparse_off)
209+	if (off >= kd->pt_sparse_off) {
210+
211 		addr = (uintptr_t)kd->sparse_map + (off - kd->pt_sparse_off);
212+		printf("%% RD: %zu %u\n", off, page_size);
213+	}
214+	else
215+		printf("%% RD: %zu %u\n", kd->page_map_off+off, page_size);
216 	return (void *)addr;
217 }
218
219@@ -289,6 +295,7 @@ _fvc_pt_init(fvc_t *kd, size_t dump_avail_size, off_t dump_avail_off,
220 	if (dump_avail_size > 0) {
221 		kd->dump_avail = mmap(NULL, kd->dump_avail_size, PROT_READ,
222 		    MAP_PRIVATE, kd->pmfd, dump_avail_off);
223+		printf("%% RD: %zu %zu\n", dump_avail_off, dump_avail_size);
224 	} else {
225 		/*
226 		 * Older version minidumps don't provide dump_avail[],
227@@ -309,7 +316,7 @@ _fvc_pt_init(fvc_t *kd, size_t dump_avail_size, off_t dump_avail_off,
228 		    map_len);
229 		return (-1);
230 	}
231-	rd = pread(kd->pmfd, kd->pt_map, map_len, map_off);
232+	rd = xpread(kd->pmfd, kd->pt_map, map_len, map_off);
233 	if (rd < 0 || rd != (ssize_t)map_len) {
234 		_fvc_err(kd, kd->program, "cannot read %zu bytes for bitmap",
235 		    map_len);
236diff --git a/man/fbsdvmcore.3 b/man/fbsdvmcore.3
237index 4285ba2..c0d760c 100644
238--- a/man/fbsdvmcore.3
239+++ b/man/fbsdvmcore.3
240@@ -89,4 +89,5 @@ etc.
241 .Xr fvc_geterr 3 ,
242 .Xr fvc_kerndisp 3 ,
243 .Xr fvc_open 3 ,
244-.Xr fvc_read 3
245+.Xr fvc_read 3 ,
246+.Xr fvc_write 3
247diff --git a/man/fvc_geterr.3 b/man/fvc_geterr.3
248index 964a097..7d74c25 100644
249--- a/man/fvc_geterr.3
250+++ b/man/fvc_geterr.3
251@@ -66,7 +66,8 @@ or an error has not been captured for
252 .Sh SEE ALSO
253 .Xr fvc 3 ,
254 .Xr fvc_close 3 ,
255-.Xr fvc_read 3
256+.Xr fvc_read 3 ,
257+.Xr fvc_write 3
258 .Sh BUGS
259 This routine cannot be used to access error conditions due to a failed
260 .Fn fvc_open
261diff --git a/man/fvc_open.3 b/man/fvc_open.3
262index 1f8e3be..4ea93ed 100644
263--- a/man/fvc_open.3
264+++ b/man/fvc_open.3
265@@ -166,5 +166,6 @@ was
266 .Xr fvc_geterr 3 ,
267 .Xr fvc_native 3 ,
268 .Xr fvc_read 3 ,
269+.Xr fvc_write 3 ,
270 .Xr kmem 4 ,
271 .Xr mem 4
272diff --git a/man/fvc_read.3 b/man/fvc_read.3
273index 7413d59..c18dadc 100644
274--- a/man/fvc_read.3
275+++ b/man/fvc_read.3
276@@ -36,18 +36,24 @@
277 .Dt FVC_READ 3
278 .Os
279 .Sh NAME
280-.Nm fvc_read
281-.Nd read kernel virtual memory
282+.Nm fvc_read ,
283+.Nm fvc_write
284+.Nd read or write kernel virtual memory
285 .Sh LIBRARY
286 .Lb libfbsdvmcore
287 .Sh SYNOPSIS
288 .In fvc.h
289 .Ft ssize_t
290 .Fn fvc_read "fvc_t *kd" "kvaddr_t addr" "void *buf" "size_t nbytes"
291+.Ft ssize_t
292+.Fn fvc_write "fvc_t *kd" "kvaddr_t addr" "void *buf" "size_t nbytes"
293 .Sh DESCRIPTION
294 The
295 .Fn fvc_read
296 function is used to read a crash dump file.
297+.Fn fvc_write
298+function is used to overwrite parts of a crash dump file.
299+Note that only the fragments already present can be written.
300 See
301 .Fn fvc_open 3
302 for information regarding opening kernel crash dumps.
303@@ -63,6 +69,13 @@ to
304 .Fa buf .
305 .Pp
306 The
307+.Fn fvc_write
308+function transfers
309+.Fa nbytes
310+bytes of data from
311+.Fa buf
312+to the kernel space address
313+.Fa addr .
314 .Sh RETURN VALUES
315 Upon success, the number of bytes actually transferred is returned.
316 Otherwise, -1 is returned.
317diff --git a/man/fvc_write.3 b/man/fvc_write.3
318new file mode 100644
319index 0000000..f25fc74
320--- /dev/null
321+++ b/man/fvc_write.3
322@@ -0,0 +1 @@
323+.so man3/fvc_read.3
324