コード例 #1
0
ファイル: dumper.c プロジェクト: vocho/openqnx
static int writenote(struct memelfnote *men, FILE *core_fp, long *size)
{
Elf32_Nhdr en;

    en.n_namesz = strlen(men->name)+1;
    en.n_descsz = men->datasz;
    en.n_type = men->type;

    if(dump_write( core_fp, &en, sizeof(en), size) == -1)
		return 1;

    if(dump_write( core_fp, men->name, en.n_namesz, size) == -1)
		return 1;
	
    dump_seek( core_fp, roundup(dump_tell(core_fp), sizeof (Elf32_Word)));  /* XXX */

    if(dump_write( core_fp, men->data, men->datasz, size) == -1)
		return 1;

    dump_seek( core_fp, roundup(dump_tell(core_fp), sizeof (Elf32_Word)));  /* XXX */

    dump_seek( core_fp, roundup(dump_tell(core_fp), sizeof (Elf32_Word)));

    return 1;
}
コード例 #2
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static int
llcallchain_bufinfo_show(dyn_llcallchain_t *dyn, track_proc_t *proc,
	track_lwp_t *lwp)
{
	char content[WIN_LINECHAR_MAX];
	lat_line_t *lat_buf, *line;
	win_reg_t *reg;
	int lwpid = 0, nlines, lat;
	
	/*
	 * Display the caption of data table:
	 * "ADDR SIZE ACCESS% LAT(ns) DESC"
	 */
	reg = &dyn->buf_caption;
	reg_erase(reg);	
	(void) snprintf(content, sizeof (content),
	    "%16s%8s%11s%11s%34s",
	    CAPTION_ADDR, CAPTION_SIZE, CAPTION_BUFHIT,
	    CAPTION_AVGLAT, CAPTION_DESC);
	reg_line_write(&dyn->buf_caption, 1, ALIGN_LEFT, content);
	dump_write("%s\n", content);
	reg_refresh_nout(reg);
	
	/*
	 * Get the stat of buffer.
	 */	
	reg = &dyn->buf_data;
	reg_erase(reg);	

	if (lwp != NULL) {
		lwpid = lwp->id;	
	}
	 
	if ((lat_buf = win_lat_buf_create(proc, lwpid, &nlines)) == NULL) {
		return (-1);
	}

	/*
	 * Fill in the memory access information.
	 */
	win_lat_buf_fill(lat_buf, nlines, proc, lwp, &lat);
	
	/*
	 * Check if the linear address is located in a buffer in
	 * process address space.
	 */ 
	if ((line = bsearch((void *)(dyn->addr), lat_buf, nlines,
		sizeof (lat_line_t), bufaddr_cmp)) != NULL) {
		win_lat_str_build(content, WIN_LINECHAR_MAX, 0, line);
		reg_line_write(reg, 0, ALIGN_LEFT, content);
		dump_write("%s\n", content);
	}
	
	reg_refresh_nout(reg);
	free(lat_buf);
	return (0);
}
コード例 #3
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static boolean_t
latnode_data_show(track_proc_t *proc, dyn_latnode_t *dyn, map_entry_t *entry,
	boolean_t *note_out)
{
	win_reg_t *reg;
	track_lwp_t *lwp = NULL;
	char content[WIN_LINECHAR_MAX], intval_buf[16], size_str[32];

	*note_out = B_FALSE;

	if ((dyn->lwpid != 0) &&
	    (lwp = proc_lwp_find(proc, dyn->lwpid)) == NULL) {
		win_warn_msg(WARN_INVALID_LWPID);
		win_note_show(NOTE_INVALID_LWPID);
		*note_out = B_TRUE;
		return (B_FALSE);
	}

	reg = &dyn->msg;
	reg_erase(reg);
	disp_intval(intval_buf, 16);
	(void) snprintf(content, sizeof (content),
	    "Break down of memory area for physical memory on node (interval: %s)",
	    intval_buf);
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("\n*** %s\n", content);
	reg_refresh_nout(reg);

	reg = &dyn->note;
	reg_erase(reg);	
	win_size2str(dyn->size, size_str, sizeof (size_str));
	if (lwp != NULL) {
		(void) snprintf(content, sizeof (content),
		    "Memory area(%"PRIX64", %s), thread(%d)",
		    dyn->addr, size_str, lwp->id);
	} else {
		(void) snprintf(content, sizeof (content),
		    "Memory area(%"PRIX64", %s), process(%d)",
		    dyn->addr, size_str, proc->pid);
	}

	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("\n*** %s\n", content);
	reg_refresh_nout(reg);

	latnode_data_get(proc, lwp, dyn);

	if (lwp != NULL) {
		lwp_refcount_dec(lwp);
	}

	return (B_TRUE);
}
コード例 #4
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static int
llcallchain_list_show(dyn_llcallchain_t *dyn, track_proc_t *proc,
	track_lwp_t *lwp)
{
	perf_llrecgrp_t *llrec_grp;
	char content[WIN_LINECHAR_MAX];
	os_perf_llrec_t *rec_arr;
	sym_chainlist_t chainlist;
	win_reg_t *reg;
	int i;

	reg = &dyn->chain_caption;
	reg_erase(reg);	
	snprintf(content, WIN_LINECHAR_MAX, "Call-chain list:");
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	dump_write("%s\n", content);
	reg_refresh_nout(reg);

	reg = &dyn->pad;
	reg_erase(reg);	
	dump_write("\n");
	reg_refresh_nout(reg);

	if (lwp != NULL) {
		llrec_grp = &lwp->llrec_grp;
	} else {
		llrec_grp = &proc->llrec_grp;
	}

	if (sym_load(proc, SYM_TYPE_FUNC) != 0) {
		debug_print(NULL, 2, "Failed to load the process symbol "
			"(pid = %d)\n", proc->pid);
		return (-1);
	}

	memset(&chainlist, 0, sizeof (sym_chainlist_t));
	rec_arr = llrec_grp->rec_arr;

	for (i = 0; i < llrec_grp->nrec_cur; i++) {
		if ((rec_arr[i].addr < dyn->addr) ||
			(rec_arr[i].addr >= dyn->addr + dyn->size)) {
			continue;
		}

		sym_callchain_add(&proc->sym, rec_arr[i].callchain.ips,
			rec_arr[i].callchain.ip_num, &chainlist);		
	}

	chainlist_show(&chainlist, &dyn->chain_data);
	return (0);
}
コード例 #5
0
ファイル: elfcore.c プロジェクト: Blackburn29/PsycoKernel
int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
			       unsigned long limit)
{
	const struct elf_phdr *const gate_phdrs =
		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
	int i;
	Elf64_Off ofs = 0;

	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
		struct elf_phdr phdr = gate_phdrs[i];

		if (phdr.p_type == PT_LOAD) {
			phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
			phdr.p_filesz = phdr.p_memsz;
			if (ofs == 0) {
				ofs = phdr.p_offset = offset;
				offset += phdr.p_filesz;
			} else {
				phdr.p_offset = ofs;
			}
		} else {
			phdr.p_offset += ofs;
		}
		phdr.p_paddr = 0; 
		*size += sizeof(phdr);
		if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
			return 0;
	}
	return 1;
}
コード例 #6
0
ファイル: dump_machdep.c プロジェクト: AhmadTux/freebsd
static int
buf_write(struct dumperinfo *di, char *ptr, size_t sz)
{
	size_t len;
	int error;

	while (sz) {
		len = DEV_BSIZE - fragsz;
		if (len > sz)
			len = sz;
		bcopy(ptr, buffer + fragsz, len);
		fragsz += len;
		ptr += len;
		sz -= len;
		if (fragsz == DEV_BSIZE) {
			error = dump_write(di, buffer, 0, dumplo,
			    DEV_BSIZE);
			if (error)
				return error;
			dumplo += DEV_BSIZE;
			fragsz = 0;
		}
	}

	return (0);
}
コード例 #7
0
ファイル: dump_machdep.c プロジェクト: AhmadTux/freebsd
static int
blk_dump(struct dumperinfo *di, vm_paddr_t pa, vm_size_t size)
{
	vm_size_t pos, rsz;
	vm_offset_t va;
	int c, counter, error, twiddle;

	printf("  chunk at %#lx: %ld bytes ", (u_long)pa, (long)size);

	va = 0L;
	error = counter = twiddle = 0;
	for (pos = 0; pos < size; pos += MAXDUMPSZ, counter++) {
		if (counter % 128 == 0)
			printf("%c\b", "|/-\\"[twiddle++ & 3]);
		rsz = size - pos;
		rsz = (rsz > MAXDUMPSZ) ? MAXDUMPSZ : rsz;
		va = TLB_PHYS_TO_DIRECT(pa + pos);
		error = dump_write(di, (void *)va, 0, dumplo, rsz);
		if (error)
			break;
		dumplo += rsz;

		/* Check for user abort. */
		c = cncheckc();
		if (c == 0x03)
			return (ECANCELED);
		if (c != -1)
			printf("(CTRL-C to abort)  ");
	}
	printf("... %s\n", (error) ? "fail" : "ok");
	return (error);
}
コード例 #8
0
ファイル: podcore.c プロジェクト: bluelikeme/PodArch
int pod_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
			       unsigned long limit)
{
	if ( vsyscall_ehdr ) {
		const struct podhdr *const ehdrp =
			(struct podhdr *) vsyscall_ehdr;
		const struct pod_phdr *const phdrp =
			(const struct pod_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
		int i;
		Elf32_Off ofs = 0;

		for (i = 0; i < ehdrp->e_phnum; ++i) {
			struct pod_phdr phdr = phdrp[i];

			if (phdr.p_type == PT_LOAD) {
				ofs = phdr.p_offset = offset;
				offset += phdr.p_filesz;
			} else {
				phdr.p_offset += ofs;
			}
			phdr.p_paddr = 0; /* match other core phdrs */
			*size += sizeof(phdr);
			if (*size > limit
			    || !dump_write(file, &phdr, sizeof(phdr)))
				return 0;
		}
	}
	return 1;
}
コード例 #9
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static int
chainlist_show(sym_chainlist_t *chainlist, win_reg_t *reg)
{
	sym_callchain_t *chain;
	int nentry, nchain;
	int i, j = 0, k, nlines;
	char content[WIN_LINECHAR_MAX];
	callchain_line_t *buf, *line;

	sym_callchain_resort(chainlist);
	nentry = sym_chainlist_nentry(chainlist, &nchain);

	reg_erase(reg);
	if (nentry == 0) {
		snprintf(content, WIN_LINECHAR_MAX,
			"<- Detecting call-chain ... -> ");
		reg_line_write(reg, 0, ALIGN_LEFT, content);
		dump_write("%s\n", content);
		reg_refresh_nout(reg);
		return (0);
	}
	
	nlines = nentry + 2 * nchain;
	if ((buf = zalloc(nlines * sizeof (callchain_line_t))) == NULL) {
		return (-1);
	}
	
	for (i = 0; i < nchain; i++) {
		if ((chain = sym_callchain_detach(chainlist)) == NULL) {
			break;
		}
		
		line = &buf[j++];
		snprintf(line->content, WIN_LINECHAR_MAX,
			"<- call-chain %d: ->", i + 1);

		for (k = 0; k < chain->nentry; k++) {
			line = &buf[j++];			
			strncpy(line->content, chain->entry_arr[k].name, WIN_LINECHAR_MAX);
			line->content[WIN_LINECHAR_MAX - 1] = 0;
		}

		line = &buf[j++];
		strcpy(line->content, "");
		sym_callchain_free(chain);
	}

	if (reg->buf != NULL) {
		free(reg->buf);
	}

	reg->buf = (void *)buf;
	reg->nlines_total = nlines - 1;
	reg_scroll_show(reg, (void *)(reg->buf), nlines - 1, callchain_str_build);
	reg_refresh_nout(reg);
	sym_chainlist_free(chainlist);
	return (0);
}
コード例 #10
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static void
nodedetail_line_show(win_reg_t *reg, char *title, char *value, int line)
{
	char s1[256];

	snprintf(s1, sizeof (s1), "%-20s%15s", title, value);
	reg_line_write(reg, line, ALIGN_LEFT, s1);
	dump_write("%s\n", s1);
}
コード例 #11
0
static int
buf_flush(struct dumperinfo *di)
{
	int error;

	if (fragsz == 0)
		return (0);

	error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE);
	dumplo += DEV_BSIZE;
	return (error);
}
コード例 #12
0
ファイル: reg.c プロジェクト: aNeutrino/numatop
/*
 * Initialization for libcurses.
 */
boolean_t
reg_curses_init(boolean_t first_load)
{
	(void) initscr();
	(void) refresh();
	(void) start_color();
	(void) keypad(stdscr, TRUE);
	(void) nonl();
	(void) cbreak();
	(void) noecho();
	(void) curs_set(0);

	getmaxyx(stdscr, g_scr_height, g_scr_width);

	/*
	 * Set a window resize signal handler.
	 */
	(void) signal(SIGWINCH, disp_on_resize);
	s_curses_init = B_TRUE;

	if ((g_scr_height < 24 || g_scr_width < 80)) {
		if (!first_load) {
			(void) mvwprintw(stdscr, 0, 0,
			    "Terminal size is too small.");
			(void) mvwprintw(stdscr, 1, 0,
			    "Please resize it to 80x24 or larger.");
			(void) refresh();
		} else {
			reg_curses_fini();
			stderr_print("Terminal size is too small "
			    "(resize it to 80x24 or larger).\n");
		}

		dump_write("\n%s\n", "Terminal size is too small.");
		dump_write("%s\n", "Please resize it to 80x24 or larger.");
		return (B_FALSE);
	}

	return (B_TRUE);
}
コード例 #13
0
ファイル: reg.c プロジェクト: aNeutrino/numatop
/*
 * Show the 'scrolling reg'.
 */
void
reg_scroll_show(win_reg_t *r, void *lines, int nreqs,
    void (*str_build_func)(char *, int, int, void *))
{
	int highlight, i, start, end;
	char content[WIN_LINECHAR_MAX];

	highlight = r->scroll.highlight;
	if (highlight != -1) {
		if (highlight >= r->nlines_total) {
			highlight = r->nlines_total - 1;
		}

		if (highlight >= r->scroll.page_start) {
			if ((i = ((highlight - r->scroll.page_start) /
			    r->nlines_scr)) != 0) {
				r->scroll.page_start += r->nlines_scr * i;
			}
		} else {
			r->scroll.page_start =
			    (highlight / r->nlines_scr) *
			    r->nlines_scr;
		}

		start = r->scroll.page_start;
		i = MIN(nreqs, r->nlines_scr);
		if ((end = start + i) > r->nlines_total) {
			end = r->nlines_total;
		}
	} else {
		highlight = 0;
		start = 0;
		end = MIN(nreqs, r->nlines_scr);
	}

	for (i = start; i < end; i++) {
		str_build_func(content, sizeof (content), i, lines);
		dump_write("%s\n", content);
		if (i != highlight) {
			reg_line_write(r, i - r->scroll.page_start,
			    ALIGN_LEFT, content);
		}
	}

	if ((highlight >= start) && (highlight < end)) {
		str_build_func(content, sizeof (content), highlight, lines);
		reg_highlight_write(r, highlight - r->scroll.page_start,
		    ALIGN_LEFT, content);
		r->scroll.highlight = highlight;
	}
}
コード例 #14
0
/*
 * textdump_writeblock() writes TEXTDUMP_BLOCKSIZE-sized blocks of data to
 * the space between di->mediaoffset and di->mediaoffset + di->mediasize.  It
 * accepts an offset relative to di->mediaoffset.  If we're carrying any
 * error from previous I/O, return that error and don't continue to try to
 * write.  Most writers ignore the error and forge ahead on the basis that
 * there's not much you can do.
 */
static int
textdump_writeblock(struct dumperinfo *di, off_t offset, char *buffer)
{

	if (textdump_error)
		return (textdump_error);
	if (offset + TEXTDUMP_BLOCKSIZE > di->mediasize)
		return (EIO);
	if (offset < SIZEOF_METADATA)
		return (ENOSPC);
	textdump_error = dump_write(di, buffer, 0, offset + di->mediaoffset,
	    TEXTDUMP_BLOCKSIZE);
	return (textdump_error);
}
コード例 #15
0
ファイル: elfcore.c プロジェクト: Blackburn29/PsycoKernel
int elf_core_write_extra_data(struct file *file, size_t *size,
			      unsigned long limit)
{
	const struct elf_phdr *const gate_phdrs =
		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
	int i;

	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
		if (gate_phdrs[i].p_type == PT_LOAD) {
			void *addr = (void *)gate_phdrs[i].p_vaddr;
			size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);

			*size += memsz;
			if (*size > limit || !dump_write(file, addr, memsz))
				return 0;
			break;
		}
	}
	return 1;
}
コード例 #16
0
ファイル: dumper.c プロジェクト: vocho/openqnx
void dump_memory( int fd, FILE *fp, procfs_mapinfo *mem, long *size )
{
int		num, i, ok = 1;

	dprintf(("dumping %lld bytes of memory at %#llx\n", mem->size, mem->vaddr ));

	for (i = 0; i < mem->size; i+= pagesize ) {
		/* read memory here */
		if ( ok ) {
			num = read( fd, membuf, min(pagesize, mem->size - i) );
		} else {
			memset( membuf, -1, sizeof membuf );
			num = pagesize;
		}
		if(dump_write( fp, membuf, min(pagesize, mem->size - i), size) == -1)
			return;
		if ( num != pagesize ) {
			dprintf(("cut short at %d+%d\n", i, num ));
			ok = 0;
		}
	}
}
コード例 #17
0
ファイル: podcore.c プロジェクト: bluelikeme/PodArch
int pod_core_write_extra_data(struct file *file, size_t *size,
			      unsigned long limit)
{
	if ( vsyscall_ehdr ) {
		const struct podhdr *const ehdrp =
			(struct podhdr *) vsyscall_ehdr;
		const struct pod_phdr *const phdrp =
			(const struct pod_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
		int i;

		for (i = 0; i < ehdrp->e_phnum; ++i) {
			if (phdrp[i].p_type == PT_LOAD) {
				void *addr = (void *) phdrp[i].p_vaddr;
				size_t filesz = phdrp[i].p_filesz;

				*size += filesz;
				if (*size > limit
				    || !dump_write(file, addr, filesz))
					return 0;
			}
		}
	}
	return 1;
}
コード例 #18
0
ファイル: ufwutil.c プロジェクト: cainiaocome/hmmm
static int ufw_send(ufw_sk *sk){
	struct timeval time;
	struct node *cur;
	struct hookinfo *hki;
	struct iphdr *ip;
	struct sockaddr_in addr;
	double delay;
	int r;
	static struct timeval last = {0, 0};
	size_t len;

	if(!sk){
		errno = EBADF;
		return -1;
	}

	ip = (struct iphdr *)sk->sendbuf;
	len = ntohs(ip->tot_len);
	delay = 0;

	if(sk->limit_byte > 0)
		delay = (double)len/sk->limit_byte;
	if(sk->limit_packet > 0 
	&& (ip->protocol == IPPROTO_UDP 
		|| (sk->limit_packet_flags & sk->sendbuf[(ip->ihl << 2) + 13]))
	&& 1./sk->limit_packet > delay)
		delay = 1./sk->limit_packet;

	gettimeofday(&time, NULL);
	if(last.tv_sec){
		delay -= time.tv_sec - last.tv_sec + (time.tv_usec - last.tv_usec)/1e6;
		if(delay > 0)
			dsleep(delay);
	}
	gettimeofday(&last, NULL);


	do{
		addr.sin_family = AF_INET;
		addr.sin_port = sk->proto;
		addr.sin_addr.s_addr = sk->daddr;
		r = sendto(sk->fd, sk->sendbuf, len, 0, (struct sockaddr *)&addr, sizeof(addr));
	}while(r < 0 && errno == EAGAIN);

	gettimeofday(&time, NULL);

	if(!sk->first_packet.tv_sec)
		sk->first_packet = time;
	if(r < 0){
		if(sk->opts & FATAL)die("sendto");
		return -1;
	}

	for(cur = sk->sendhook; cur; cur = cur->next){
		hki = cur->data;
		if(!hki->func(sk->sendbuf, &time, 1, hki->user))
			return r;
	}

	if((sk->opts & DUMP_SEND) && sk->dump)
		dump_write(sk->dump, sk->sendbuf, 0, &time);

	time.tv_sec -= sk->first_packet.tv_sec;
	time.tv_usec -= sk->first_packet.tv_usec;
	if(time.tv_usec < 0)time.tv_usec += 1000000;

	if(sk->opts & PRINT_SEND)
		print_packet(sk->sendbuf, &time, 1);

	return r;
}
コード例 #19
0
ファイル: dumper.c プロジェクト: vocho/openqnx
int elfcore(int fd, FILE *fp, const char *path, long coresize)
{
procfs_sysinfo		*sysinfo;
int					sysinfo_len;
procfs_info			info;
procfs_status		status;
int					ret;
procfs_mapinfo		*mem = NULL, *mapinfos = NULL, *ldd_infos = NULL;
int					numnote=0, num, i, j, seg = 0, err, n_ldd_infos = 0;
Elf32_Ehdr			elf;
Elf32_Phdr 			phdr;
struct memelfnote	notes[20], thread_note;
off_t				offset = 0, dataoff;
uint64_t			cur_tid_base = 0, cur_tid_size = 0;


	if (nodumpmem) {
		if (-1 == get_ldd_mapinfos(fd, &ldd_infos, &n_ldd_infos)) {
			/* should we bail out here? */
			n_ldd_infos = 0;
		}
	}

	if((ret = devctl(fd, DCMD_PROC_SYSINFO, 0, 0, &sysinfo_len)) != EOK) {
		errno = ret;
		goto bailout;
	}
	if(sysinfo = alloca(sysinfo_len)) {
		if((ret = devctl(fd, DCMD_PROC_SYSINFO, sysinfo, sysinfo_len, 0)) != EOK) {
			errno = ret;
			goto bailout;
		}
	}

	if((ret = devctl(fd, DCMD_PROC_INFO, &info, sizeof info, 0)) != EOK) {
		errno = ret;
		goto bailout;
	}

	pagesize = sysconf( _SC_PAGESIZE );
	if ( membuf == NULL && ((membuf = malloc( pagesize )) == NULL) ) {
		goto bailout;
	}

	// write elf header
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELFCLASS32;
	elf.e_ident[EI_DATA] = ELFDATANATIVE;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
#if defined (__ARM__)
	elf.e_ident[EI_OSABI] = ELFOSABI_ARM;
#endif
	
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	if((ret = devctl(fd, DCMD_PROC_PAGEDATA, NULL, 0, &num)) != EOK) {
		errno = ret;
		goto bailout;
	}

	mapinfos = malloc( num * sizeof *mem );
	if ( mapinfos == NULL ) {
		goto bailout;
	}

	if((ret = devctl(fd, DCMD_PROC_PAGEDATA, mapinfos, num*sizeof(*mapinfos), &num)) != EOK) {
		errno = ret;
		goto bailout;
	}

	mem = malloc( (n_ldd_infos + num) * sizeof(*mem) );
	if ( mem == NULL ) {
		goto bailout;
	}

	/* find the offending thread */
	for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
		dprintf(("thread %d.flags is %#x\n", status.tid, status.flags ));
		if(status.why == _DEBUG_WHY_SIGNALLED) {
			// This is the faulting thread...
			dprintf(("thread %d is was SIGNALLED\n", status.tid ));
			cur_tid = status.tid;
			cur_tid_base = status.stkbase;
			cur_tid_size = status.stksize;
		}
		dprintf(("thread %d.why is %#x\n", status.tid, status.why ));
	}

	if(cur_tid == 0) {
		/* can't find the faulting thread then we need to dump all stack information */
		cur_tid_only = 0;
	}

	for(seg = 0, i = 0; i < num; i++) {
	  	if(!(mapinfos[i].flags & PG_HWMAPPED) ||
			(nodumpmem && !(mapinfos[i].flags & MAP_STACK)) ) {
			continue;
		}
		if ( (nodumpphys && (mapinfos[i].flags & MAP_PHYS) && !(mapinfos[i].flags & MAP_ANON)) ) {
			continue;
		}

		/* if we only want to dump the offending tid's stack */
		if(cur_tid_only && (mapinfos[i].flags & MAP_STACK) && 
			!OFFENDING_THREAD(cur_tid_base, cur_tid_size, &mapinfos[i])) {
			continue;
		}

		memcpy(&mem[seg], &mapinfos[i], sizeof(*mem));
		seg++;
	}

	dprintf(("ldd mapinfos:\n"));
	for(i = 0; i < n_ldd_infos; i++) {
		dprintf(("%svaddr=%#llx, offset=%#llx, size=%#llx, flags=%#x\n", ldd_infos[i].flags & PG_HWMAPPED?"*":"", ldd_infos[i].vaddr, ldd_infos[i].offset, ldd_infos[i].size, ldd_infos[i].flags ));
		memcpy( &mem[seg], &ldd_infos[i], sizeof(*mem));;
		seg++;
	}
	free(mapinfos);
	mapinfos = NULL;
	if(n_ldd_infos) {
		free(ldd_infos);
		ldd_infos = NULL;
	}
	num = seg;

	elf.e_type = ET_CORE;
	elf.e_machine = EM_NATIVE;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
#ifdef __SH__
	{
		struct cpuinfo_entry	*cpu;

		cpu = SYSPAGE_ENTRY(cpuinfo);
		switch ( SH4_PVR_FAM(cpu[0].cpu) ) {
			case SH4_PVR_SH4A:
				dprintf(("Noting SH4-A CPU\n"));
				elf.e_flags = EF_SH4A;
				break;
			case SH4_PVR_SH4:
			default:
				elf.e_flags = EF_SH4;
				break;
		}
	}
#else
	elf.e_flags = 0;
#endif
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(phdr);
	elf.e_phnum = seg+1; /* xxxx */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	if(dump_write( fp, &elf, sizeof elf, &coresize ) == -1)
		goto bailout;
	
	offset += sizeof elf;
	offset += (elf.e_phnum) * sizeof phdr;

	if(sysinfo) {
		// write QNT_CORE_SYSINFO note
		memset( notes, 0, sizeof notes );
		notes[numnote].name = QNX_NOTE_NAME;
		notes[numnote].type = QNT_CORE_SYSINFO;
		notes[numnote].datasz = roundup(sysinfo_len, sizeof (Elf32_Word));
		notes[numnote].data = sysinfo;
		numnote++;
	}

	// write QNT_CORE_INFO note
	notes[numnote].name = QNX_NOTE_NAME;
	notes[numnote].type = QNT_CORE_INFO;
	notes[numnote].datasz = sizeof(info);
	notes[numnote].data = &info;
	numnote++;

	/* Write notes phdr entry */
	{
		int sz = 0;

		memset( &phdr, 0, sizeof phdr );

		for(i = 0; i < numnote; i++)
		    sz += notesize(&notes[i]);

		for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
			procfs_greg					greg;
			procfs_fpreg				fpreg;
			int							size;

			if ( (err = devctl(fd, DCMD_PROC_CURTHREAD, &status.tid, sizeof status.tid, 0 )) != EOK ) {
				continue;
			}

			if (cur_tid_only && (cur_tid != status.tid)) {
				continue;
			}

			fixup_stack_boundary( &status, mem, seg );

			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_STATUS;
			thread_note.datasz = sizeof(status);
			thread_note.data = &status;
			sz += notesize( &thread_note );

			if(devctl(fd, DCMD_PROC_GETGREG, &greg, sizeof greg, &size) == EOK) {
				thread_note.name = QNX_NOTE_NAME;
				thread_note.type = QNT_CORE_GREG;
				thread_note.datasz = size;
				thread_note.data = &greg;
				sz += notesize( &thread_note );
			}
			if(devctl(fd, DCMD_PROC_GETFPREG, &fpreg, sizeof fpreg, &size) == EOK) {
				thread_note.name = QNX_NOTE_NAME;
				thread_note.type = QNT_CORE_FPREG;
				thread_note.datasz = size;
				thread_note.data = &fpreg;
				sz += notesize( &thread_note );
			}
		}

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		if(dump_write( fp, &phdr, sizeof(phdr), &coresize) == -1)
			goto bailout;
	}

	/* Page-align dumped data */
	dataoff = offset = roundup(offset, pagesize);

	for ( i = 0; i < seg; i++ ) {
		memset( &phdr, 0, sizeof phdr );

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = mem[i].vaddr;
		phdr.p_paddr = 0;
		phdr.p_memsz = mem[i].size;
		phdr.p_flags = PF_W|PF_R;
		if ( mem[i].flags & MAP_ELF )
			phdr.p_flags |= PF_X;
		phdr.p_align = pagesize;
		phdr.p_filesz = phdr.p_memsz;

		offset += phdr.p_filesz;
		if(dump_write( fp, &phdr, sizeof(phdr), &coresize) == -1)
			goto bailout;
	}

	for(i = 0; i < numnote; i++) {
	    if (!writenote(&notes[i], fp, &coresize ))
	    	goto bailout;
	}

	for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
		procfs_greg					greg;
		procfs_fpreg				fpreg;
		int							size;

		if ( devctl(fd, DCMD_PROC_CURTHREAD, &status.tid, sizeof status.tid, 0 ) != EOK ) {
			continue;
		}

		if ( cur_tid == 0 )
			cur_tid = status.tid;

		if (cur_tid_only && (cur_tid != status.tid)) {
			continue;
		} else if ( status.tid == cur_tid ) {
			dprintf(("thread %d is current thread!\n", status.tid ));
			slog_tid( &status, path );
			status.flags |= _DEBUG_FLAG_CURTID;
		}

		// write QNT_CORE_STATUS note
		thread_note.name = QNX_NOTE_NAME;
		thread_note.type = QNT_CORE_STATUS;
		thread_note.datasz = sizeof(status);
		thread_note.data = &status;
		if ( !writenote( &thread_note, fp, &coresize ) )
			goto bailout;

		if(devctl(fd, DCMD_PROC_GETGREG, &greg, sizeof greg, &size) == EOK) {
			// write QNT_CORE_GREG note
			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_GREG;
			thread_note.datasz = size;
			thread_note.data = &greg;
			if ( !writenote( &thread_note, fp, &coresize ) )
				goto bailout;
		}

		if(devctl(fd, DCMD_PROC_GETFPREG, &fpreg, sizeof fpreg, &size) == EOK) {
			// write QNT_CORE_FPREG note
			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_FPREG;
			thread_note.datasz = size;
			thread_note.data = &fpreg;
			if ( !writenote( &thread_note, fp, &coresize ) )
				goto bailout;
		}
	}

	dump_seek( fp, dataoff );

	for ( j = 0; j < seg; j++ ) {
		if ( lseek( fd, mem[j].vaddr, SEEK_SET ) == -1 )
			goto bailout;
		if ( mem[j].flags & MAP_STACK )
			dump_stack_memory( fd, fp, &mem[j], &coresize );
		else
		  if (!nodumpmem)
			dump_memory( fd, fp, &mem[j], &coresize );
	}

	// Return EOK when accually writing ELF files
	free(mem);
	return EOK;
bailout:
	if ( mapinfos != NULL ) {
		free(mapinfos);
	}
	if ( ldd_infos != NULL ) {
		free(ldd_infos);
	}
	if ( mem != NULL ) {
		free(mem);
	}
	return errno;
}
コード例 #20
0
ファイル: dump_machdep.c プロジェクト: AhmadTux/freebsd
void
dumpsys(struct dumperinfo *di)
{
	struct sparc64_dump_hdr hdr;
	vm_size_t size, totsize, hdrsize;
	int error, i, nreg;

	/* Calculate dump size. */
	size = 0;
	nreg = sparc64_nmemreg;
	for (i = 0; i < sparc64_nmemreg; i++)
		size += sparc64_memreg[i].mr_size;
	/* Account for the header size. */
	hdrsize = roundup2(sizeof(hdr) + sizeof(struct sparc64_dump_reg) * nreg,
	    DEV_BSIZE);
	size += hdrsize;

	totsize = size + 2 * sizeof(kdh);
	if (totsize > di->mediasize) {
		printf("Insufficient space on device (need %ld, have %ld), "
		    "refusing to dump.\n", (long)totsize,
		    (long)di->mediasize);
		error = ENOSPC;
		goto fail;
	}

	/* Determine dump offset on device. */
	dumplo = di->mediaoffset + di->mediasize - totsize;

	mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size,
	    di->blocksize);

	printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg);

	/* Dump leader */
	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
	if (error)
		goto fail;
	dumplo += sizeof(kdh);

	/* Dump the private header. */
	hdr.dh_hdr_size = hdrsize;
	hdr.dh_tsb_pa = tsb_kernel_phys;
	hdr.dh_tsb_size = tsb_kernel_size;
	hdr.dh_tsb_mask = tsb_kernel_mask;
	hdr.dh_nregions = nreg;

	if (buf_write(di, (char *)&hdr, sizeof(hdr)) != 0)
		goto fail;

	dumppos = hdrsize;
	/* Now, write out the region descriptors. */
	for (i = 0; i < sparc64_nmemreg; i++) {
		error = reg_write(di, sparc64_memreg[i].mr_start,
		    sparc64_memreg[i].mr_size);
		if (error != 0)
			goto fail;
	}
	buf_flush(di);

	/* Dump memory chunks. */
	for (i = 0; i < sparc64_nmemreg; i++) {
		error = blk_dump(di, sparc64_memreg[i].mr_start,
		    sparc64_memreg[i].mr_size);
		if (error != 0)
			goto fail;
	}

	/* Dump trailer */
	error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
	if (error)
		goto fail;

	/* Signal completion, signoff and exit stage left. */
	dump_write(di, NULL, 0, 0, 0);
	printf("\nDump complete\n");
	return;

 fail:
	/* XXX It should look more like VMS :-) */
	printf("** DUMP FAILED (ERROR %d) **\n", error);
}
コード例 #21
0
ファイル: disp.c プロジェクト: antoniogi/numatop
/* ARGSUSED */
static void *
cons_handler(void *arg)
{
	int c, cmd_id;
	unsigned char ch;

	if (!reg_curses_init(B_TRUE)) {
		goto L_EXIT;
	}

	win_fix_init();

	/*
	 * Excute "home" command. It shows the NumaTop default page.
	 */
	disp_go_home();

	for (;;) {
		FD_ZERO(&s_cons_ctl.fds);
		FD_SET(STDIN_FILENO, &s_cons_ctl.fds);
		FD_SET(s_cons_ctl.pipe[0], &s_cons_ctl.fds);

		/*
		 * Wait one character from "stdin" or pipe.
		 */
		if (select(s_cons_ctl.pipe[0] + 1, &s_cons_ctl.fds,
		    NULL, NULL, NULL) > 0) {
			if (FD_ISSET(s_cons_ctl.pipe[0], &s_cons_ctl.fds)) {
				if (read(s_cons_ctl.pipe[0], &ch, 1) == 1) {
					/*
					 * Character is from pipe.
					 */
					if (ch == PIPE_CHAR_QUIT) {
						/*
						 * Received a QUIT notification,
						 * "console thread" will be quit
						 */
						debug_print(NULL, 2, "cons: "
						    "received PIPE_CHAR_QUIT\n");
						break;
					}

					if (ch == PIPE_CHAR_RESIZE) {
						/*
						 * Send the "RESIZE" command
						 * to "display thread".
						 */
						(void) pthread_mutex_lock(
						    &s_disp_ctl.mutex);

						CMD_ID_SET(&s_disp_ctl.cmd,
						    CMD_RESIZE_ID);
					dispthr_flagset_nolock(DISP_FLAG_CMD);

					(void) pthread_mutex_unlock(
					    &s_disp_ctl.mutex);
					}
				}
			} else {
				/*
				 * Character is from STDIN.
				 */
				if ((c = getch()) == ERR) {
					/*
					 * It's possile if the associated
					 * terminal is lost.
					 */
					debug_print(NULL, 2, "cons: "
					    "getch() failed.\n");
					break;
				}

				ch = tolower((unsigned char)c);
				dump_write("\n<-- User hit the key '%c' "
				    "(ascii = %d) -->\n", ch, (int)ch);

				cmd_id = cmd_id_get(ch);
				if (cmd_id != CMD_INVALID_ID) {
					/*
					 * The character is a command. Send
					 * the command to 'disp thread'.
					 */
					(void) pthread_mutex_lock(
					    &s_disp_ctl.mutex);

					CMD_ID_SET(&s_disp_ctl.cmd, cmd_id);
					dispthr_flagset_nolock(DISP_FLAG_CMD);

					(void) pthread_mutex_unlock(
					    &s_disp_ctl.mutex);
				} else {
					/*
					 * Hit the keys 'UP'/'DOWN'/'ENTER'
					 */
					switch (ch) {
					case 2:	/* KEY DOWN */
						dispthr_flagset_lock(
						    DISP_FLAG_SCROLLDOWN);
						break;

					case 3:	/* KEY UP */
						dispthr_flagset_lock(
						    DISP_FLAG_SCROLLUP);
						break;

					case 13:	/* enter. */
						dispthr_flagset_lock(
						    DISP_FLAG_SCROLLENTER);
						break;

					default:
						break;
					}
				}
			}
		}
	}

	reg_curses_fini();

L_EXIT:
	debug_print(NULL, 2, "cons thread is exiting\n");
	return (NULL);
}
コード例 #22
0
ファイル: os_win.c プロジェクト: antoniogi/numatop
static void
llcallchain_data_show(dyn_win_t *win, boolean_t *note_out)
{
	dyn_llcallchain_t *dyn;
	pid_t pid;
	int lwpid;
	uint64_t size;
	track_proc_t *proc;
	track_lwp_t *lwp = NULL;
	win_reg_t *reg;
	char content[WIN_LINECHAR_MAX], intval_buf[16];
	char size_str[32];

	dyn = (dyn_llcallchain_t *)(win->dyn);
	pid = dyn->pid;
	lwpid = dyn->lwpid;
	size = dyn->size;
	*note_out = B_FALSE;

	if ((proc = proc_find(pid)) == NULL) {
		win_warn_msg(WARN_INVALID_PID);
		win_note_show(NOTE_INVALID_PID);
		*note_out = B_TRUE;
		return;
	}

	if ((lwpid > 0) && ((lwp = proc_lwp_find(proc, lwpid)) == NULL)) {
		proc_refcount_dec(proc);
		win_warn_msg(WARN_INVALID_LWPID);
		win_note_show(NOTE_INVALID_LWPID);
		*note_out = B_TRUE;
		return;
	}

	reg = &dyn->msg;
	reg_erase(reg);	
	disp_intval(intval_buf, 16);
	win_size2str(size, size_str, sizeof (size_str));

	if (lwp == NULL) {
		(void) snprintf(content, WIN_LINECHAR_MAX,
			"Call-chain when process accesses the memory area (pid: %d)"
	    	" (interval: %s)", pid, intval_buf);
	} else {
		(void) snprintf(content, WIN_LINECHAR_MAX,
			"Call-chain when thread accesses the memory area (lwpid: %d)"
	    	" (interval: %s)", lwpid, intval_buf);
	}

	dump_write("\n*** %s\n", content);
	reg_line_write(reg, 1, ALIGN_LEFT, content);
	reg_refresh_nout(reg);

	llcallchain_bufinfo_show(dyn, proc, lwp);
	llcallchain_list_show(dyn, proc, lwp);
	
	if (lwp != NULL) {
		lwp_refcount_dec(lwp);
	}

	proc_refcount_dec(proc);
}
コード例 #23
0
/*
 * Commit text dump to disk.
 */
void
textdump_dumpsys(struct dumperinfo *di)
{
	off_t dumplen, trailer_offset;

	if (di->blocksize != TEXTDUMP_BLOCKSIZE) {
		printf("Dump partition block size (%ju) not textdump "
		    "block size (%ju)", (uintmax_t)di->blocksize,
		    (uintmax_t)TEXTDUMP_BLOCKSIZE);
		return;
	}

	/*
	 * We don't know a priori how large the dump will be, but we do know
	 * that we need to reserve space for metadata and that we need two
	 * dump headers.  Also leave room for one ustar header and one block
	 * of data.
	 */
	if (di->mediasize < SIZEOF_METADATA + 2 * sizeof(kdh)) {
		printf("Insufficient space on dump partition.\n");
		return;
	}
	textdump_error = 0;

	/*
	 * Position the start of the dump so that we'll write the kernel dump
	 * trailer immediately before the end of the partition, and then work
	 * our way back.  We will rewrite this header later to reflect the
	 * true size if things go well.
	 */
	textdump_offset = di->mediasize - sizeof(kdh);
	textdump_saveoff(&trailer_offset);
	mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, 0, TEXTDUMP_BLOCKSIZE);
	(void)textdump_writenextblock(di, (char *)&kdh);

	/*
	 * Write a series of files in ustar format.
	 */
	if (textdump_do_ddb)
		db_capture_dump(di);
#ifdef INCLUDE_CONFIG_FILE
	if (textdump_do_config)
		textdump_dump_config(di);
#endif
	if (textdump_do_msgbuf)
		textdump_dump_msgbuf(di);
	if (textdump_do_panic && panicstr != NULL)
		textdump_dump_panic(di);
	if (textdump_do_version)
		textdump_dump_version(di);

	/*
	 * Now that we know the true size, we can write out the header, then
	 * seek back to the end and rewrite the trailer with the correct
	 * size.
	 */
	dumplen = trailer_offset - (textdump_offset + TEXTDUMP_BLOCKSIZE);
	mkdumpheader(&kdh, TEXTDUMPMAGIC, KERNELDUMP_TEXT_VERSION, dumplen,
	    TEXTDUMP_BLOCKSIZE);
	(void)textdump_writenextblock(di, (char *)&kdh);
	textdump_restoreoff(trailer_offset);
	(void)textdump_writenextblock(di, (char *)&kdh);

	/*
	 * Terminate the dump, report any errors, and clear the pending flag.
	 */
	if (textdump_error == 0)
		(void)dump_write(di, NULL, 0, 0, 0);
	if (textdump_error == ENOSPC)
		printf("Insufficient space on dump partition\n");
	else if (textdump_error != 0)
		printf("Error %d writing dump\n", textdump_error);
	else
		printf("Textdump complete.\n");
	textdump_pending = 0;
}
コード例 #24
0
ファイル: ufwutil.c プロジェクト: cainiaocome/hmmm
static inline int ufw_recv(ufw_sk *sk){
	struct cmsghdr* cmsg;
	char ctlbuf[4096];
	struct iovec iov;
	struct msghdr msg = {NULL, 0, &iov, 1, ctlbuf, sizeof(ctlbuf), 0};
	ssize_t s;
	struct node *cur;
	struct hookinfo *hki;
	struct timeval time;
	struct iphdr *ip;

	if(!sk){
		errno = EBADF;
		return -1;
	}

	iov.iov_base = sk->recvbuf;
	iov.iov_len = sizeof(sk->recvbuf);
	ip = (struct iphdr *)sk->recvbuf;

	for(;;){
	next:
		s = recvmsg(sk->fd, &msg, MSG_WAITALL);
		if(s < 0){
			if(errno == EAGAIN)
				return 0;
			else {
				if(sk->opts & FATAL)die("recvmsg");
				return -1;
			}
		}

		/* filter */
		if((sk->opts & FILTER_SADDR) && ip->daddr != sk->saddr)
			continue;
		if((sk->opts & FILTER_DADDR) && ip->saddr != sk->daddr)
			continue;
		if((sk->opts & FILTER_SPORT) 
			&& *(u_int16_t *)(sk->recvbuf + (ip->ihl << 2) + 2) != sk->sport)
			continue;
		if((sk->opts & FILTER_DPORT) 
			&& *(u_int16_t *)(sk->recvbuf + (ip->ihl << 2)) != sk->dport)
			continue;

		sk->received = 1;

		/* get timestamp */
		for(cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
			if(cmsg->cmsg_level == SOL_SOCKET
			&& cmsg->cmsg_type == SO_TIMESTAMP
			&& cmsg->cmsg_len >= CMSG_LEN(sizeof(struct timeval))){
				time = *(struct timeval *)CMSG_DATA(cmsg);
				break;
			}

		if(!sk->first_packet.tv_sec)
			sk->first_packet = time;

		for(cur = sk->recvhook; cur; cur = cur->next){
			hki = cur->data;
			if(!hki->func(sk->recvbuf, &time, 1, hki->user))
				goto next;
		}

		if((sk->opts & DUMP_RECV) && sk->dump)
			dump_write(sk->dump, sk->recvbuf, 0, &time);

		time.tv_sec -= sk->first_packet.tv_sec;
		time.tv_usec -= sk->first_packet.tv_usec;
		if(time.tv_usec < 0)time.tv_usec += 1000000;

		if(sk->opts & PRINT_RECV)
			print_packet(sk->recvbuf, &time, 0);
	}

	return -1;//never
}
コード例 #25
0
ファイル: dumper.c プロジェクト: vocho/openqnx
void dump_stack_memory( int fd, FILE *fp, procfs_mapinfo *mem, long *size )
{
int		num, i, max, min, base;
off_t	here, there;

	if ( (mem->flags & PG_HWMAPPED) == 0 ) {
		dprintf(("Ignoring non-mapped stack region: %#llx @ %#llx\n", 
			mem->size, mem->vaddr ));
		return;
	}
	base = mem->offset;
//	base = mem->vaddr;

	dprintf(("blanking %lld bytes of stack memory at %#x\n", mem->size, base ));
//printf("vaddr=%#x, offset=%#x, size=%lld\n", mem->vaddr, mem->offset, mem->size );

	here = dump_tell(fp);
	max = roundup( mem->size, pagesize );
	min = (mem->offset - mem->vaddr);
	dprintf(("max=%#x, min = %#x (%#llx->%#llx)\n", max, min, mem->vaddr+min, mem->vaddr+max ));

	if (gzlevel != -1) {
		int rsize;

		/* forward dumping from mem->offset to mem->offset + mem->size in gz mode */
		memset(membuf, 0, pagesize);
		for (i = 0; i < min; i += pagesize) {
			if( dump_write( fp, membuf, min(pagesize, min - i), size) == -1)
			  return;
		}

		for (i = min; i < mem->size; i += pagesize) {
			if ( lseek( fd, mem->vaddr + i, SEEK_SET ) == -1 ) {
				memset(membuf, 0, pagesize);
				num = pagesize;
			} else {
				rsize = (i & ~(pagesize - 1)) + pagesize;
				if (rsize >= mem->size) {
					rsize = mem->size - i;
				} else {
					rsize -= i;
				}
				if ((num = read( fd, membuf, rsize)) != rsize) {
					memset(membuf, -1, pagesize);
				}
			}
			if( dump_write( fp, membuf, num, size) == -1)
			  return;
		}
		return;
	}
	
	memset( membuf, 0, sizeof membuf );
	for (i = 0; i < mem->size; i+= pagesize ) {
		if(dump_write( fp, membuf, min( pagesize, mem->size - i ), size) == -1)
			return;
	}
	there = dump_tell(fp);

	for ( i = max - pagesize; i >= min; i -= pagesize ) {
		dump_seek( fp, here + i );
		if ( lseek( fd, mem->vaddr + i, SEEK_SET ) == -1 )
			continue;
		/* read memory here */
//		dprintf(("attempting to read @ %#llx\n", mem->vaddr + i ));
		if ( (num = read( fd, membuf, pagesize )) != pagesize ) {
			memset( membuf, -1, sizeof membuf );
			num = pagesize;
		}
		if(dump_write( fp, membuf, num, size) == -1)
			return;
		fflush( fp );
		if ( num != pagesize ) {
			dprintf(("cut short at %d+%d\n", i, num ));
			break;
		}
//		else
//			dprintf(("read %d bytes ok\n", num ));
	}
	dump_seek( fp, there );
}