示例#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
VMDump::VMDump(const char *fileName) : Dump(fileName, "rb")
{
	char fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
	
	ebcdicAsciiConv = iconv_open("ISO-8859-1", "EBCDIC-US");

	/* Record 1: adsrRecord */

	dump_seek(fh,0,SEEK_SET);
	dump_read(&adsrRecord,sizeof(adsrRecord),1,fh);

	if(debug) {
		char buf[1024];
		int i;
	
		dump_seek(fh,adsrRecord.sec3_offset,SEEK_SET);
		dump_read(buf, adsrRecord.sec3_len,1,fh);
		ebcAsc(buf,adsrRecord.sec3_len);
		for(i=0; i < adsrRecord.sec3_len; i++) {
			if((buf[i]==0) || iscntrl(buf[i]))
				buf[i]=' ';
		}
		buf[adsrRecord.sec3_len]=0;
		printf("symptom string1: %s\n",buf);
	}

	/* Record 2: fmbk */

	dump_seek(fh,0x1000,SEEK_SET);
	dump_read(&fmbkRecord,sizeof(fmbkRecord),1,fh);

	/* Check if this is a vmdump */
	if(memcmp(fmbkRecord.id, fmbk_id, 8) != 0) {
		throw DumpException("Input file is not a vmdump");
	}
	
	/* Record 3-7: fir records read by subclasses */

	/* Record 8: albk */

	dump_seek(fh,(fmbkRecord.rec_nr_access-1)*0x1000 ,SEEK_SET);
	dump_read(&albkRecord,sizeof(albkRecord),1,fh);
}
示例#3
0
VMDumpClassic::VMDumpClassic(const char *fileName) : VMDump(fileName)
{
	int storageKeyPages,bitMapPages;
		
	pageOffset = 0;

	/* Record 9: asibk */

	dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
	dump_read(&asibkRecord,sizeof(asibkRecord),1,fh);

	/* Record 10: bitmaps */

	dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);
        bitmap = new char[asibkRecord.storage_size_2GB / (0x1000 * 8)];
	dump_read(bitmap,asibkRecord.storage_size_2GB / (0x1000*8),1,fh);

        bitMapPages=asibkRecord.storage_size_2GB / (0x1000 * 8);
        if(bitMapPages % 0x1000 != 0)
                bitMapPages = bitMapPages/0x1000 + 1;
        else
                bitMapPages = bitMapPages/0x1000;

        storageKeyPages=asibkRecord.storage_size_2GB / 0x1000;
        if(storageKeyPages % 0x1000 != 0) {
                storageKeyPages = storageKeyPages/0x1000 + 1;
	} else {
                storageKeyPages = storageKeyPages/0x1000;
	}

        /* skip storage keys */

	memoryStartRecord = (fmbkRecord.rec_nr_access + 1) *0x1000 /* 0x9000 */
				+ (bitMapPages + storageKeyPages)*0x1000;
	if(debug) {
		printf("Mem Offset: %llx\n",(long long)memoryStartRecord);
	}
}
示例#4
0
VMDump64::VMDump64(const char* filename) : VMDumpClassic(filename)
{
	int i;
	
	if(!fh) {
		return;
	}

	dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
	dump_read(&fir64Record,sizeof(fir64Record),1,fh);

	fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
	for(i=0; i < fir64Record.online_cpus; i++) {
		/* fir other */
		dump_read(&fir64OtherRecords[i],sizeof(fir64OtherRecords[i]),1,
			  fh);
	}
	if(debug)
		printDebug();
}
示例#5
0
void
VMDump::readMem(char* buf, int size)
{
	int i;

	if(pageOffset == 0)
		dump_seek(fh, memoryStartRecord, SEEK_SET);

	if(size % 0x1000 != 0) {
		throw(DumpException("internal error: VMDump::readMem() "\
		"can only handle sizes which are multiples of page size"));
	}

	for(i = 0; i < size; i += 0x1000) {
		if(testPage(pageOffset)) {
			dump_read(buf + i, 0x1000,1,fh);
		} else {
			memset(buf + i, 0, 0x1000);
		}
		pageOffset += 1;
	}
}
示例#6
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;
}
示例#7
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 );
}
示例#8
0
VMDump64Big::VMDump64Big(const char* filename) : VMDump(filename)
{
	int i,j;
	uint64_t pageNum, nrDumpedPages;
	
	if(!fh) {
		return;
	}
		
	/* Record 9: asibk */

	dump_seek(fh,fmbkRecord.rec_nr_access * 0x1000,SEEK_SET);
	dump_read(&asibkRecordNew,sizeof(asibkRecordNew),1,fh);

	/* Record 10: bitmaps: */
	/* Read all bitmap pages and setup bitmap array */

	pageNum = 0;
	nrDumpedPages = asibkRecordNew.storage_size_def_store / 0x1000;
	memoryStartRecord = (fmbkRecord.rec_nr_access +  1) * 0x1000;
	bitmap = new char[asibkRecordNew.storage_size_def_store/(0x1000 * 8)];
	if(!bitmap) {
		throw(DumpErrnoException("out of memory"));
	}
	memset(bitmap,0,asibkRecordNew.storage_size_def_store/(0x1000 * 8));

	dump_seek(fh,(fmbkRecord.rec_nr_access + 1)* 0x1000 ,SEEK_SET);

	do {
		char bmIndexPage[0x1000];
		dump_read(bmIndexPage,sizeof(bmIndexPage),1,fh);
		memoryStartRecord += 0x1000;
		for(i=0; i < 0x1000; i++) {
			if(testBitmapPage(bmIndexPage,i)) {
				char bmPage[0x1000];
				dump_read(bmPage,sizeof(bmPage),1,fh);
				memoryStartRecord += 0x1000;
				for(j = 0; j < 0x1000; j++) {
					if(testBitmapKeyPage(bmPage, j)) {
						setPageBit(pageNum);
					}
					pageNum++;
					if(pageNum == nrDumpedPages) {
						goto all_bitmaps_read;
					}
				}
			} else {
				pageNum += 0x1000; // empty pages
			}
		}
	} while (pageNum < nrDumpedPages);

all_bitmaps_read:

	if(debug)
		printf("Mem Offset: %llx\n",(long long)memoryStartRecord);

	dump_seek(fh,(fmbkRecord.rec_nr_fir-1)* 0x1000 ,SEEK_SET);
	dump_read(&fir64Record,sizeof(fir64Record),1,fh);

	fir64OtherRecords = new _fir_other_64[fir64Record.online_cpus];
	for(i=0; i < fir64Record.online_cpus; i++) {
		/* fir other */
		dump_read(&fir64OtherRecords[i],sizeof(fir64OtherRecords[i]),1,
			  fh);
	}
	if(debug)
		printDebug();
}
示例#9
0
Dump::DumpType
VMDump::getDumpType(const char* inputFileName)
{
	FILE* fh;
	struct _fmbk fmbk;
	struct _fir_basic  fir;
	char fmbk_id[8] = {0xc8, 0xc3, 0xd7, 0xc4, 0xc6, 0xd4, 0xc2, 0xd2};
	char msg[200];

	fh = fopen(inputFileName,"r");
	if(!fh) {
		sprintf(msg,"Could not open '%s'",inputFileName);
		throw DumpErrnoException(msg);
	}

        /* Record 2: fmbk */
	dump_seek(fh,0x1000,SEEK_SET);
	if(fread(&fmbk,sizeof(fmbk),1,fh) != 1) {
		if(ferror(fh)) {
			sprintf(msg,"Could not read header of vmdump '%s'",
					inputFileName);
			fclose(fh);
			throw DumpErrnoException(msg);
		} else{
			sprintf(msg,"Input file '%s' is not a vmdump",
					inputFileName);
			fclose(fh);
			throw DumpException(msg);
		}
	}

	/* Check if this is a vmdump */
	if(memcmp(fmbk.id, fmbk_id, 8) != 0) {
		fclose(fh);
		sprintf(msg,"Input file '%s' is not a vmdump",inputFileName);
		throw DumpException(msg);
	}

	/* Record 3-7: fir */
	dump_seek(fh,(fmbk.rec_nr_fir-1)* 0x1000,SEEK_SET);
	if(fread(&fir,sizeof(fir),1,fh) != 1) {
		if(ferror(fh)) {
			sprintf(msg,"Could not read header of vmdump '%s'",
					inputFileName);
			fclose(fh);
			throw DumpErrnoException(msg);
		}
		else{
			sprintf(msg,"Could not read header of vmdump '%s'",
					inputFileName);
			fclose(fh);
			throw DumpException(msg);
		}
	}
	fclose(fh);
	if(fir.fir_format == 0) {
		return DT_VM32;
	} else if(fir.fir_format == 0x02) {/*XXX && (fir.dump_format == 0x1))*/
		return DT_VM64_BIG;
	} else if(fir.fir_format == 0x82) {
		return DT_VM64;
	} else {
		return DT_UNKNOWN;
	}
}