Write segments to core dump files in maximally-sized chunks that neither

exceed vn_rdwr_inchunks()'s INT_MAX length limitation nor span a block
boundary. This fixes dumping segments larger than 2GB.

PR:	67546
This commit is contained in:
tjr 2004-06-04 06:30:16 +00:00
parent ea3e28a2d3
commit 85aaf94278

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
@ -961,23 +962,35 @@ __elfN(coredump)(td, vp, limit)
/* Write the contents of all of the writable segments. */
if (error == 0) {
Elf_Phdr *php;
off_t offset;
off_t chunksize, offset, segofs;
int i;
php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1;
offset = hdrsize;
for (i = 0; i < seginfo.count; i++) {
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t)(uintptr_t)php->p_vaddr,
php->p_filesz, offset, UIO_USERSPACE,
IO_UNIT | IO_DIRECT, cred, NOCRED, (int *)NULL,
curthread); /* XXXKSE */
if (error != 0)
break;
/*
* Write the segment in maximally-sized chunks that
* neither exceed vn_rdwr_inchunks()'s INT_MAX
* length limitation nor span a block boundary.
*/
segofs = 0;
while (segofs < php->p_filesz) {
chunksize = MIN(php->p_filesz - segofs,
INT_MAX - MAXBSIZE + 1);
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t)(uintptr_t)php->p_vaddr + segofs,
chunksize, offset + segofs, UIO_USERSPACE,
IO_UNIT | IO_DIRECT, cred, NOCRED,
(int *)NULL, curthread); /* XXXKSE */
if (error != 0)
goto done;
segofs += chunksize;
}
offset += php->p_filesz;
php++;
}
}
done:
free(hdr, M_TEMP);
return (error);