Blame lkcd_common.c

Packit Service 501009
/* lkcd_common.c - core analysis suite
Packit Service 501009
 *
Packit Service 501009
 * Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
Packit Service 501009
 * Copyright (C) 2002 Silicon Graphics, Inc. 
Packit Service 501009
 * Copyright (C) 2002 Free Software Foundation, Inc.
Packit Service 501009
 * Copyright (C) 2002-2005, 2007, 2009, 2011, 2013 David Anderson
Packit Service 501009
 * Copyright (C) 2002-2005, 2007, 2009, 2011, 2013 Red Hat, Inc. All rights reserved.
Packit Service 501009
 *
Packit Service 501009
 * This program is free software; you can redistribute it and/or modify
Packit Service 501009
 * it under the terms of the GNU General Public License as published by
Packit Service 501009
 * the Free Software Foundation; either version 2 of the License, or
Packit Service 501009
 * (at your option) any later version.
Packit Service 501009
 *
Packit Service 501009
 * This program is distributed in the hope that it will be useful,
Packit Service 501009
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 501009
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 501009
 * GNU General Public License for more details.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  lkcd_uncompress_RLE() is essentially LKCD's __cmpuncompress_page() rountine,
Packit Service 501009
 *  adapted from ../cmd/lcrash/lib/libklib/arch/i386/kl_cmp.c:
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * arch/i386/cmp.c
Packit Service 501009
 *
Packit Service 501009
 * This file handles compression aspects of crash dump files
Packit Service 501009
 * for i386 based systems.  Most of this is taken from the
Packit Service 501009
 * IRIX compression code, with exceptions to how the index
Packit Service 501009
 * is created, because the file format is different with Linux.
Packit Service 501009
 *
Packit Service 501009
 * Copyright 1999 Silicon Graphics, Inc. All rights reserved.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  This file has no knowledge of the dump_header_t, dump_header_asm_t or
Packit Service 501009
 *  dump_page_t formats, so it gathers information from them via the version
Packit Service 501009
 *  specific "_v1" or "_v2_v3" type routines.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#define LKCD_COMMON
Packit Service 501009
#include "defs.h"
Packit Service 501009
Packit Service 501009
static void dump_dump_page(char *, void *);
Packit Service 501009
static int lkcd_uncompress_RLE(unsigned char *, unsigned char *,uint32_t,int *);
Packit Service 501009
static int lkcd_uncompress_gzip(unsigned char *, ulong, unsigned char *, ulong);
Packit Service 501009
static int hash_page(ulong);
Packit Service 501009
static int page_is_cached(void);
Packit Service 501009
static int page_is_hashed(long *);
Packit Service 501009
static int cache_page(void);
Packit Service 501009
Packit Service 501009
struct lkcd_environment lkcd_environment = { 0 };
Packit Service 501009
struct lkcd_environment *lkcd = &lkcd_environment;
Packit Service 501009
static int uncompress_errloc;
Packit Service 501009
static int uncompress_recover(unsigned char *, ulong, unsigned char *, ulong);
Packit Service 501009
Packit Service 501009
ulonglong 
Packit Service 501009
fix_lkcd_address(ulonglong addr)
Packit Service 501009
{
Packit Service 501009
    int i; 
Packit Service 501009
    ulong offset;
Packit Service 501009
Packit Service 501009
    for (i = 0; i < lkcd->fix_addr_num; i++) {
Packit Service 501009
	if ( (addr >=lkcd->fix_addr[i].task) && 
Packit Service 501009
		(addr < lkcd->fix_addr[i].task + STACKSIZE())){
Packit Service 501009
Packit Service 501009
	    offset = addr - lkcd->fix_addr[i].task;
Packit Service 501009
	    addr = lkcd->fix_addr[i].saddr + offset;
Packit Service 501009
	}
Packit Service 501009
    }
Packit Service 501009
Packit Service 501009
    return addr;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Each version has its own dump initialization.
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
lkcd_dump_init(FILE *fp, int fd, char *dumpfile)
Packit Service 501009
{
Packit Service 501009
	switch (lkcd->version)
Packit Service 501009
	{
Packit Service 501009
        case LKCD_DUMP_V1:
Packit Service 501009
		return(lkcd_dump_init_v1(fp, fd));
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V2:
Packit Service 501009
        case LKCD_DUMP_V3:
Packit Service 501009
		return(lkcd_dump_init_v2_v3(fp, fd));
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V5:
Packit Service 501009
        case LKCD_DUMP_V6:
Packit Service 501009
		return(lkcd_dump_init_v5(fp, fd));
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V7:
Packit Service 501009
		return(lkcd_dump_init_v7(fp, fd, dumpfile));
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V8:
Packit Service 501009
        case LKCD_DUMP_V9:
Packit Service 501009
		return(lkcd_dump_init_v8(fp, fd, dumpfile));
Packit Service 501009
Packit Service 501009
	default:
Packit Service 501009
		return FALSE;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Return the page size value recorded in the dump header.
Packit Service 501009
 */
Packit Service 501009
uint32_t
Packit Service 501009
lkcd_page_size(void)
Packit Service 501009
{
Packit Service 501009
	return lkcd->page_size;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Return the panic task and panic string.
Packit Service 501009
 */
Packit Service 501009
unsigned long
Packit Service 501009
get_lkcd_panic_task(void)
Packit Service 501009
{
Packit Service 501009
	return(lkcd->flags & (LKCD_VALID|LKCD_REMOTE) ? lkcd->panic_task : 0);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
void
Packit Service 501009
get_lkcd_panicmsg(char *buf)
Packit Service 501009
{
Packit Service 501009
	if (lkcd->flags & (LKCD_VALID|LKCD_REMOTE))
Packit Service 501009
		strcpy(buf, lkcd->panic_string);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Called by remote_lkcd_dump_init() the local (!valid) lkcd_environment
Packit Service 501009
 *  is used to store the panic task and panic message for use by the
Packit Service 501009
 *  two routines above.
Packit Service 501009
 */ 
Packit Service 501009
void
Packit Service 501009
set_remote_lkcd_panic_data(ulong task, char *buf)
Packit Service 501009
{
Packit Service 501009
	if (buf) {
Packit Service 501009
		if (!(lkcd->panic_string = (char *)malloc(strlen(buf)+1))) {
Packit Service 501009
			fprintf(stderr, 
Packit Service 501009
			    "cannot malloc space for panic message!\n");
Packit Service 501009
			clean_exit(1);
Packit Service 501009
		}
Packit Service 501009
		strcpy(lkcd->panic_string, buf);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (task)
Packit Service 501009
		lkcd->panic_task = task;
Packit Service 501009
Packit Service 501009
	lkcd->flags |= LKCD_REMOTE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Does the magic number indicate an LKCD compressed dump?
Packit Service 501009
 *  If so, set the version number for all future forays into the
Packit Service 501009
 *  functions in this file.
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
is_lkcd_compressed_dump(char *s)
Packit Service 501009
{
Packit Service 501009
        int tmpfd;
Packit Service 501009
        uint64_t magic;
Packit Service 501009
	uint32_t version;
Packit Service 501009
	char errbuf[BUFSIZE];
Packit Service 501009
Packit Service 501009
        if ((tmpfd = open(s, O_RDONLY)) < 0) {
Packit Service 501009
		strcpy(errbuf, s);
Packit Service 501009
                perror(errbuf);
Packit Service 501009
                return FALSE;
Packit Service 501009
        }
Packit Service 501009
        if (read(tmpfd, &magic, sizeof(uint64_t)) != sizeof(uint64_t)) {
Packit Service 501009
                close(tmpfd);
Packit Service 501009
                return FALSE;
Packit Service 501009
        }
Packit Service 501009
        if (read(tmpfd, &version, sizeof(uint32_t)) != sizeof(uint32_t)) {
Packit Service 501009
                close(tmpfd);
Packit Service 501009
                return FALSE;
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
        close(tmpfd);
Packit Service 501009
Packit Service 501009
        if (!((magic == LKCD_DUMP_MAGIC_NUMBER) || 
Packit Service 501009
	     (magic == LKCD_DUMP_MAGIC_LIVE)))
Packit Service 501009
		return FALSE;
Packit Service 501009
Packit Service 501009
	switch (version & ~(LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1))
Packit Service 501009
	{
Packit Service 501009
	case LKCD_DUMP_V1:
Packit Service 501009
		lkcd->version = LKCD_DUMP_V1;
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	case LKCD_DUMP_V2:
Packit Service 501009
	case LKCD_DUMP_V3:
Packit Service 501009
		lkcd->version = LKCD_DUMP_V2;
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	case LKCD_DUMP_V5:
Packit Service 501009
	case LKCD_DUMP_V6:
Packit Service 501009
		lkcd->version = LKCD_DUMP_V5;
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	case LKCD_DUMP_V7:
Packit Service 501009
		lkcd->version = LKCD_DUMP_V7;
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	case LKCD_DUMP_V8:
Packit Service 501009
	case LKCD_DUMP_V9:
Packit Service 501009
	case LKCD_DUMP_V10:
Packit Service 501009
		lkcd->version = LKCD_DUMP_V8;
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	default:
Packit Service 501009
		lkcd_print("unsupported LKCD dump version: %ld (%lx)\n", 
Packit Service 501009
			version & ~(LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1), 
Packit Service 501009
			version);
Packit Service 501009
		return FALSE;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  console-only output for info regarding current page.
Packit Service 501009
 */
Packit Service 501009
static void
Packit Service 501009
dump_dump_page(char *s, void *dp)
Packit Service 501009
{
Packit Service 501009
        switch (lkcd->version)
Packit Service 501009
        {
Packit Service 501009
        case LKCD_DUMP_V1:
Packit Service 501009
                dump_dump_page_v1(s, dp);
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V2:
Packit Service 501009
        case LKCD_DUMP_V3:
Packit Service 501009
                dump_dump_page_v2_v3(s, dp);
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V5:
Packit Service 501009
                dump_dump_page_v5(s, dp);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V7:
Packit Service 501009
                dump_dump_page_v7(s, dp);
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V8:
Packit Service 501009
        case LKCD_DUMP_V9:
Packit Service 501009
                dump_dump_page_v8(s, dp);
Packit Service 501009
		break;
Packit Service 501009
        }
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  help -S output, or as specified by arg.
Packit Service 501009
 */
Packit Service 501009
void
Packit Service 501009
dump_lkcd_environment(ulong arg)
Packit Service 501009
{
Packit Service 501009
	int others;
Packit Service 501009
Packit Service 501009
	if (arg == LKCD_DUMP_HEADER_ONLY)
Packit Service 501009
		goto dump_header_only;
Packit Service 501009
	if (arg == LKCD_DUMP_PAGE_ONLY)
Packit Service 501009
		goto dump_page_only;
Packit Service 501009
Packit Service 501009
	lkcd_print("              fd: %d\n", lkcd->fd);
Packit Service 501009
	lkcd_print("              fp: %lx\n", lkcd->fp);
Packit Service 501009
	lkcd_print("           debug: %ld\n", lkcd->debug);
Packit Service 501009
	lkcd_print("           flags: %lx  (", lkcd->flags);
Packit Service 501009
	others = 0;
Packit Service 501009
	if (lkcd->flags & LKCD_VALID)
Packit Service 501009
		lkcd_print("%sLKCD_VALID", others++ ? "|" : "");
Packit Service 501009
	if (lkcd->flags & LKCD_REMOTE)
Packit Service 501009
		lkcd_print("%sLKCD_REMOTE", others++ ? "|" : "");
Packit Service 501009
	if (lkcd->flags & LKCD_NOHASH)
Packit Service 501009
		lkcd_print("%sLKCD_NOHASH", others++ ? "|" : "");
Packit Service 501009
        if (lkcd->flags & LKCD_MCLX)
Packit Service 501009
                lkcd_print("%sLKCD_MCLX", others++ ? "|" : "");
Packit Service 501009
        if (lkcd->flags & LKCD_BAD_DUMP)
Packit Service 501009
                lkcd_print("%sLKCD_BAD_DUMP", others++ ? "|" : "");
Packit Service 501009
	lkcd_print(")\n");
Packit Service 501009
Packit Service 501009
dump_header_only:
Packit Service 501009
        switch (lkcd->version)
Packit Service 501009
        {
Packit Service 501009
        case LKCD_DUMP_V1:
Packit Service 501009
                dump_lkcd_environment_v1(LKCD_DUMP_HEADER_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V2:
Packit Service 501009
        case LKCD_DUMP_V3:
Packit Service 501009
                dump_lkcd_environment_v2_v3(LKCD_DUMP_HEADER_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V5:
Packit Service 501009
                dump_lkcd_environment_v5(LKCD_DUMP_HEADER_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V7:
Packit Service 501009
                dump_lkcd_environment_v7(LKCD_DUMP_HEADER_ONLY);
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V8:
Packit Service 501009
        case LKCD_DUMP_V9:
Packit Service 501009
                dump_lkcd_environment_v8(LKCD_DUMP_HEADER_ONLY);
Packit Service 501009
		break;
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
        if (arg == LKCD_DUMP_HEADER_ONLY)
Packit Service 501009
                return;
Packit Service 501009
Packit Service 501009
dump_page_only:
Packit Service 501009
        switch (lkcd->version)
Packit Service 501009
        {
Packit Service 501009
        case LKCD_DUMP_V1:
Packit Service 501009
                dump_lkcd_environment_v1(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V2:
Packit Service 501009
        case LKCD_DUMP_V3:
Packit Service 501009
                dump_lkcd_environment_v2_v3(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V5:
Packit Service 501009
                dump_lkcd_environment_v5(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V7:
Packit Service 501009
                dump_lkcd_environment_v7(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
        case LKCD_DUMP_V8:
Packit Service 501009
                dump_lkcd_environment_v8(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
		break;
Packit Service 501009
        }
Packit Service 501009
	if (arg == LKCD_DUMP_PAGE_ONLY)
Packit Service 501009
		return;
Packit Service 501009
Packit Service 501009
	lkcd_print("         version: %ld\n", lkcd->version);
Packit Service 501009
	lkcd_print("       page_size: %ld\n", lkcd->page_size);
Packit Service 501009
	lkcd_print("      page_shift: %d\n", lkcd->page_shift);
Packit Service 501009
	lkcd_print("            bits: %d\n", lkcd->bits);
Packit Service 501009
	lkcd_print("      panic_task: %lx\n", lkcd->panic_task);
Packit Service 501009
	lkcd_print("    panic_string: %s%s", lkcd->panic_string,
Packit Service 501009
		lkcd->panic_string && strstr(lkcd->panic_string, "\n") ? 
Packit Service 501009
		"" : "\n");
Packit Service 501009
Packit Service 501009
	lkcd_print("     get_dp_size: ");
Packit Service 501009
	if (lkcd->get_dp_size == get_dp_size_v1)
Packit Service 501009
		lkcd_print("get_dp_size_v1()\n");
Packit Service 501009
	else if (lkcd->get_dp_size == get_dp_size_v2_v3)
Packit Service 501009
		lkcd_print("get_dp_size_v2_v3()\n");
Packit Service 501009
        else if (lkcd->get_dp_size == get_dp_size_v5)
Packit Service 501009
                lkcd_print("get_dp_size_v5()\n");
Packit Service 501009
	else
Packit Service 501009
		lkcd_print("%lx\n", lkcd->get_dp_size);
Packit Service 501009
Packit Service 501009
        lkcd_print("    get_dp_flags: ");
Packit Service 501009
        if (lkcd->get_dp_flags == get_dp_flags_v1)
Packit Service 501009
                lkcd_print("get_dp_flags_v1()\n");
Packit Service 501009
        else if (lkcd->get_dp_flags == get_dp_flags_v2_v3)
Packit Service 501009
                lkcd_print("get_dp_flags_v2_v3()\n");
Packit Service 501009
        else if (lkcd->get_dp_flags == get_dp_flags_v5)
Packit Service 501009
                lkcd_print("get_dp_flags_v5()\n");
Packit Service 501009
        else
Packit Service 501009
                lkcd_print("%lx\n", lkcd->get_dp_flags);
Packit Service 501009
Packit Service 501009
        lkcd_print("  get_dp_address: ");
Packit Service 501009
        if (lkcd->get_dp_address == get_dp_address_v1)
Packit Service 501009
                lkcd_print("get_dp_address_v1()\n");
Packit Service 501009
        else if (lkcd->get_dp_address == get_dp_address_v2_v3)
Packit Service 501009
                lkcd_print("get_dp_address_v2_v3()\n");
Packit Service 501009
        else if (lkcd->get_dp_address == get_dp_address_v5)
Packit Service 501009
                lkcd_print("get_dp_address_v5()\n");
Packit Service 501009
        else
Packit Service 501009
                lkcd_print("%lx\n", lkcd->get_dp_address);
Packit Service 501009
Packit Service 501009
	lkcd_print("     compression: ");
Packit Service 501009
	lkcd_print(BITS32() ? "%lx  " : "%x  ", lkcd->compression);
Packit Service 501009
	switch (lkcd->compression)
Packit Service 501009
	{
Packit Service 501009
	case LKCD_DUMP_COMPRESS_NONE:
Packit Service 501009
		lkcd_print("(LKCD_DUMP_COMPRESS_NONE)\n");
Packit Service 501009
		break;
Packit Service 501009
	case LKCD_DUMP_COMPRESS_RLE:
Packit Service 501009
		lkcd_print("(LKCD_DUMP_COMPRESS_RLE)\n");
Packit Service 501009
		break;
Packit Service 501009
	case LKCD_DUMP_COMPRESS_GZIP:
Packit Service 501009
		lkcd_print("(LKCD_DUMP_COMPRESS_GZIP)\n");
Packit Service 501009
		break;
Packit Service 501009
	default:
Packit Service 501009
		lkcd_print("(unknown)\n");
Packit Service 501009
		break;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	lkcd_print("page_header_size: %ld\n", lkcd->page_header_size);
Packit Service 501009
	lkcd_print("          curpos: %ld\n", lkcd->curpos);
Packit Service 501009
	lkcd_print("        curpaddr: ");
Packit Service 501009
	lkcd_print(BITS32() ? "%llx\n" : "%lx\n", lkcd->curpaddr);
Packit Service 501009
	lkcd_print("       curbufptr: %lx\n", lkcd->curbufptr);
Packit Service 501009
	lkcd_print("      curhdroffs: %ld\n", lkcd->curhdroffs);
Packit Service 501009
	lkcd_print("          kvbase: ");
Packit Service 501009
	lkcd_print(BITS32() ? "%llx\n" : "%lx\n", lkcd->kvbase);
Packit Service 501009
	lkcd_print("  page_cache_buf: %lx\n", lkcd->page_cache_buf);
Packit Service 501009
	lkcd_print(" compressed_page: %lx\n", lkcd->compressed_page);
Packit Service 501009
	lkcd_print("     evict_index: %d\n", lkcd->evict_index);
Packit Service 501009
	lkcd_print("       evictions: %ld\n", lkcd->evictions);
Packit Service 501009
	lkcd_print(" benchmark_pages: %ld\n", lkcd->benchmark_pages);
Packit Service 501009
	lkcd_print(" benchmarks_done: %ld\n", lkcd->benchmarks_done);
Packit Service 501009
Packit Service 501009
	lkcd_memory_dump(lkcd->fp);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Set the shadow debug flag.
Packit Service 501009
 */
Packit Service 501009
void
Packit Service 501009
set_lkcd_debug(ulong debug)
Packit Service 501009
{
Packit Service 501009
	lkcd->debug = debug;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Set no-hash flag bit.
Packit Service 501009
 */
Packit Service 501009
void 
Packit Service 501009
set_lkcd_nohash(void)
Packit Service 501009
{
Packit Service 501009
	lkcd->flags |= LKCD_NOHASH; 
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Set the file pointer for debug output.
Packit Service 501009
 */
Packit Service 501009
FILE *
Packit Service 501009
set_lkcd_fp(FILE *fp)
Packit Service 501009
{
Packit Service 501009
	lkcd->fp = fp;
Packit Service 501009
	return fp;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Return the number of pages cached.
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
lkcd_memory_used(void)
Packit Service 501009
{
Packit Service 501009
	int i, pages;
Packit Service 501009
        struct page_cache_hdr *sp;
Packit Service 501009
Packit Service 501009
        sp = &lkcd->page_cache_hdr[0];
Packit Service 501009
        for (i = pages = 0; i < LKCD_CACHED_PAGES; i++, sp++) { 
Packit Service 501009
		if (LKCD_VALID_PAGE(sp->pg_flags))
Packit Service 501009
			pages++;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return pages;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Since the dumpfile pages are temporary tenants of a fixed page cache,
Packit Service 501009
 *  this command doesn't do anything except clear the references. 
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
lkcd_free_memory(void)
Packit Service 501009
{
Packit Service 501009
        int i, pages;
Packit Service 501009
        struct page_cache_hdr *sp;
Packit Service 501009
Packit Service 501009
        sp = &lkcd->page_cache_hdr[0];
Packit Service 501009
        for (i = pages = 0; i < LKCD_CACHED_PAGES; i++, sp++) {
Packit Service 501009
                if (LKCD_VALID_PAGE(sp->pg_flags)) {
Packit Service 501009
			sp->pg_addr = 0;
Packit Service 501009
			sp->pg_hit_count = 0;
Packit Service 501009
                        pages++;
Packit Service 501009
		}
Packit Service 501009
		sp->pg_flags = 0;
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
        return pages;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Dump the page cache;
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
lkcd_memory_dump(FILE *fp)
Packit Service 501009
{
Packit Service 501009
        int i, c, pages;
Packit Service 501009
        struct page_cache_hdr *sp;
Packit Service 501009
        struct page_hash_entry *phe;
Packit Service 501009
	ulong pct_cached, pct_hashed;
Packit Service 501009
	ulong pct_compressed, pct_raw;
Packit Service 501009
	FILE *fpsave;
Packit Service 501009
	char buf[BUFSIZE];
Packit Service 501009
	int wrap;
Packit Service 501009
Packit Service 501009
	fpsave = lkcd->fp;
Packit Service 501009
	lkcd->fp = fp;
Packit Service 501009
Packit Service 501009
        lkcd_print("     total_pages: %ld\n", lkcd->total_pages);
Packit Service 501009
        pct_compressed = (lkcd->compressed*100) /
Packit Service 501009
                (lkcd->hashed ? lkcd->hashed : 1);
Packit Service 501009
        pct_raw = (lkcd->raw*100) /
Packit Service 501009
                (lkcd->hashed ? lkcd->hashed : 1);
Packit Service 501009
        lkcd_print("          hashed: %ld\n", lkcd->hashed);
Packit Service 501009
        lkcd_print("      compressed: %ld (%ld%%)\n", 
Packit Service 501009
		lkcd->compressed, pct_compressed);
Packit Service 501009
        lkcd_print("             raw: %ld (%ld%%)\n", 
Packit Service 501009
		lkcd->raw, pct_raw);
Packit Service 501009
        pct_cached = (lkcd->cached_reads*100) /  
Packit Service 501009
                (lkcd->total_reads ? lkcd->total_reads : 1);
Packit Service 501009
        pct_hashed = (lkcd->hashed_reads*100) /
Packit Service 501009
                (lkcd->total_reads ? lkcd->total_reads : 1); 
Packit Service 501009
        lkcd_print("    cached_reads: %ld (%ld%%)\n", lkcd->cached_reads,
Packit Service 501009
                pct_cached);
Packit Service 501009
        lkcd_print("    hashed_reads: %ld (%ld%%)\n", lkcd->hashed_reads,
Packit Service 501009
                pct_hashed);
Packit Service 501009
        lkcd_print("     total_reads: %ld (hashed or cached: %ld%%) \n",
Packit Service 501009
            lkcd->total_reads, pct_cached+pct_hashed);
Packit Service 501009
Packit Service 501009
        lkcd_print("page_hash[%2d]:\n", LKCD_PAGE_HASH);
Packit Service 501009
Packit Service 501009
	if (LKCD_DEBUG(1)) {
Packit Service 501009
	        for (i = 0; i < LKCD_PAGE_HASH; i++) {
Packit Service 501009
	                phe = &lkcd->page_hash[i];
Packit Service 501009
	                if (!LKCD_VALID_PAGE(phe->pg_flags))
Packit Service 501009
	                        continue;
Packit Service 501009
	                lkcd_print("  [%2d]: ", i);
Packit Service 501009
	                wrap = 0;
Packit Service 501009
	                while (phe && LKCD_VALID_PAGE(phe->pg_flags)) {
Packit Service 501009
				sprintf(buf, "%llx@", 
Packit Service 501009
					(ulonglong)phe->pg_addr);
Packit Service 501009
				sprintf(&buf[strlen(buf)],
Packit Service 501009
	                        	"%llx,", (ulonglong)phe->pg_hdr_offset);
Packit Service 501009
				lkcd_print("%18s", buf);
Packit Service 501009
Packit Service 501009
	                        phe = phe->next;
Packit Service 501009
	                        if (phe && (++wrap == 3)) {
Packit Service 501009
	                                lkcd_print("\n        ");
Packit Service 501009
	                                wrap = 0;
Packit Service 501009
	                        }
Packit Service 501009
	                }
Packit Service 501009
	                lkcd_print("\n");
Packit Service 501009
	        }
Packit Service 501009
	} else {
Packit Service 501009
	        for (i = 0; i < LKCD_PAGE_HASH; i++) {
Packit Service 501009
	                phe = &lkcd->page_hash[i];
Packit Service 501009
	                if (!LKCD_VALID_PAGE(phe->pg_flags))
Packit Service 501009
	                        continue;
Packit Service 501009
	                lkcd_print("  [%2d]: ", i);
Packit Service 501009
	                wrap = 0;
Packit Service 501009
	                while (phe && LKCD_VALID_PAGE(phe->pg_flags)) {
Packit Service 501009
				lkcd_print(BITS32() ? "%9llx," : "%9lx,",
Packit Service 501009
					phe->pg_addr);
Packit Service 501009
	                        phe = phe->next;
Packit Service 501009
	                        if (phe && (++wrap == 7)) {
Packit Service 501009
	                                lkcd_print("\n        ");
Packit Service 501009
	                                wrap = 0;
Packit Service 501009
	                        }
Packit Service 501009
	                }
Packit Service 501009
	                lkcd_print("\n");
Packit Service 501009
	        }
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        lkcd_print("page_cache_hdr[%2d]:\n", LKCD_CACHED_PAGES);
Packit Service 501009
	lkcd_print(" INDEX   PG_ADDR  PG_BUFPTR");
Packit Service 501009
        lkcd_print(BITS32() ? " PG_HIT_COUNT\n" : "        PG_HIT_COUNT\n");
Packit Service 501009
Packit Service 501009
        sp = &lkcd->page_cache_hdr[0];
Packit Service 501009
        for (i = pages = 0; i < LKCD_CACHED_PAGES; i++, sp++) {
Packit Service 501009
                if (LKCD_VALID_PAGE(sp->pg_flags))
Packit Service 501009
                        pages++;
Packit Service 501009
		if (BITS32())
Packit Service 501009
                	lkcd_print("  [%2d] %9llx  %lx        %ld\n",
Packit Service 501009
			    i, sp->pg_addr, sp->pg_bufptr, sp->pg_hit_count);
Packit Service 501009
		else
Packit Service 501009
                	lkcd_print("  [%2d] %9lx  %lx  %ld\n",
Packit Service 501009
			    i, sp->pg_addr, sp->pg_bufptr, sp->pg_hit_count);
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
	if (lkcd->mb_hdr_offsets) {
Packit Service 501009
		lkcd_print("mb_hdr_offsets[%3ld]: \n", lkcd->benchmark_pages);
Packit Service 501009
Packit Service 501009
		for (i = 0; i < lkcd->benchmark_pages; i += 8) {
Packit Service 501009
			lkcd_print("  [%3d]", i);
Packit Service 501009
			c = 0;
Packit Service 501009
			while ((c < 8) && ((i+c) < lkcd->benchmark_pages)) {
Packit Service 501009
				lkcd_print(" %8lx", lkcd->mb_hdr_offsets[i+c]);
Packit Service 501009
				c++;
Packit Service 501009
			}
Packit Service 501009
			lkcd_print("\n");
Packit Service 501009
		}
Packit Service 501009
	} else {
Packit Service 501009
		lkcd_print("  mb_hdr_offsets: NA\n");
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (lkcd->zones) {
Packit Service 501009
		lkcd_print("       num_zones: %d / %d\n", lkcd->num_zones,
Packit Service 501009
				lkcd->max_zones);
Packit Service 501009
		lkcd_print("   zoned_offsets: %ld\n", lkcd->zoned_offsets);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	lkcd_print("  dumpfile_index: %s\n", lkcd->dumpfile_index);
Packit Service 501009
	lkcd_print("             ifd: %d\n", lkcd->ifd);
Packit Service 501009
        lkcd_print("    memory_pages: %ld\n", lkcd->memory_pages);
Packit Service 501009
        lkcd_print(" page_offset_max: %ld\n", lkcd->page_offset_max);
Packit Service 501009
        lkcd_print("  page_index_max: %ld\n", lkcd->page_index_max);
Packit Service 501009
        lkcd_print("    page_offsets: %lx\n", lkcd->page_offsets);
Packit Service 501009
Packit Service 501009
	lkcd->fp = fpsave;
Packit Service 501009
Packit Service 501009
        return pages;
Packit Service 501009
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  The lkcd_lseek() routine does the bulk of the work setting things up 
Packit Service 501009
 *  so that the subsequent lkcd_read() simply has to do a bcopy().
Packit Service 501009
Packit Service 501009
 *  Given a physical address, first determine:
Packit Service 501009
 *
Packit Service 501009
 *   (1) its page offset (lkcd->curpos).
Packit Service 501009
 *   (2) its page address as specified in the dumpfile (lkcd->curpaddr).
Packit Service 501009
 *
Packit Service 501009
 *  If the page data is already cached, everything will be set up for the
Packit Service 501009
 *  subsequent read when page_is_cached() returns.
Packit Service 501009
 *
Packit Service 501009
 *  If the page data is not cached, either of the following occurs:
Packit Service 501009
 *
Packit Service 501009
 *   (1) page_is_hashed() will check whether the page header offset is cached,
Packit Service 501009
 *       and if so, will set up the page variable, and lseek to the header.
Packit Service 501009
 *
Packit Service 501009
 *  In either case above, the starting point for the page search is set up.
Packit Service 501009
 *  Lastly, cache_page() stores the requested page's data.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
static int
Packit Service 501009
save_offset(uint64_t paddr, off_t off)
Packit Service 501009
{
Packit Service 501009
	uint64_t zone, page;
Packit Service 501009
	int ii, ret;
Packit Service 501009
	int max_zones;
Packit Service 501009
	struct physmem_zone *zones;
Packit Service 501009
Packit Service 501009
	ret = -1;
Packit Service 501009
	zone = paddr & lkcd->zone_mask;
Packit Service 501009
Packit Service 501009
	page = (paddr & ~lkcd->zone_mask) >> lkcd->page_shift;
Packit Service 501009
Packit Service 501009
	if (lkcd->num_zones == 0) {
Packit Service 501009
		lkcd->zones = malloc(ZONE_ALLOC * sizeof(struct physmem_zone));
Packit Service 501009
		if (!lkcd->zones) {
Packit Service 501009
			return -1; /* This should be fatal */
Packit Service 501009
		}
Packit Service 501009
		BZERO(lkcd->zones, ZONE_ALLOC * sizeof(struct physmem_zone));
Packit Service 501009
Packit Service 501009
		lkcd->max_zones = ZONE_ALLOC;
Packit Service 501009
Packit Service 501009
		lkcd->zones[0].start = zone;
Packit Service 501009
		lkcd->zones[0].pages = malloc((ZONE_SIZE >> lkcd->page_shift) *
Packit Service 501009
					sizeof(struct page_desc));
Packit Service 501009
		if (!lkcd->zones[0].pages) {
Packit Service 501009
			return -1; /* this should be fatal */
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
		BZERO(lkcd->zones[0].pages, (ZONE_SIZE >> lkcd->page_shift) *
Packit Service 501009
					sizeof(struct page_desc));
Packit Service 501009
		lkcd->num_zones++;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
retry:
Packit Service 501009
	/* find the zone */
Packit Service 501009
	for (ii=0; ii < lkcd->num_zones; ii++) {
Packit Service 501009
		if (lkcd->zones[ii].start == zone) {
Packit Service 501009
			if (lkcd->zones[ii].pages[page].offset != 0) {
Packit Service 501009
			   if (lkcd->zones[ii].pages[page].offset != off) {
Packit Service 501009
				if (CRASHDEBUG(1) && !STREQ(pc->curcmd, "search"))
Packit Service 501009
				    error(INFO, "LKCD: conflicting page: zone %lld, "
Packit Service 501009
					"page %lld: %lld, %lld != %lld\n",
Packit Service 501009
					(unsigned long long)zone, 
Packit Service 501009
					(unsigned long long)page, 
Packit Service 501009
					(unsigned long long)paddr, 
Packit Service 501009
					(unsigned long long)off,
Packit Service 501009
					(unsigned long long)lkcd->zones[ii].pages[page].offset);
Packit Service 501009
				return -1;
Packit Service 501009
			   }
Packit Service 501009
			   ret = 0;
Packit Service 501009
			} else {
Packit Service 501009
			   lkcd->zones[ii].pages[page].offset = off;
Packit Service 501009
			   ret = 1;
Packit Service 501009
			}
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
	if (ii == lkcd->num_zones) {
Packit Service 501009
		/* This is a new zone */
Packit Service 501009
		if (lkcd->num_zones < lkcd->max_zones) {
Packit Service 501009
			/* We have room for another one */
Packit Service 501009
			lkcd->zones[ii].start = zone;
Packit Service 501009
			lkcd->zones[ii].pages = malloc(
Packit Service 501009
					(ZONE_SIZE >> lkcd->page_shift) *
Packit Service 501009
					sizeof(struct page_desc));
Packit Service 501009
			if (!lkcd->zones[ii].pages) {
Packit Service 501009
				return -1; /* this should be fatal */
Packit Service 501009
			}
Packit Service 501009
Packit Service 501009
			BZERO(lkcd->zones[ii].pages, 
Packit Service 501009
					(ZONE_SIZE >> lkcd->page_shift) *
Packit Service 501009
					sizeof(struct page_desc));
Packit Service 501009
			lkcd->zones[ii].pages[page].offset = off;
Packit Service 501009
			ret = 1;
Packit Service 501009
			lkcd->num_zones++;
Packit Service 501009
		} else {
Packit Service 501009
			/* need to expand zone */
Packit Service 501009
			max_zones = lkcd->max_zones * 2;
Packit Service 501009
			zones = malloc(max_zones * sizeof(struct physmem_zone));
Packit Service 501009
			if (!zones) {
Packit Service 501009
				return -1; /* This should be fatal */
Packit Service 501009
			}
Packit Service 501009
			BZERO(zones, max_zones * sizeof(struct physmem_zone));
Packit Service 501009
			memcpy(zones, lkcd->zones,
Packit Service 501009
				lkcd->max_zones * sizeof(struct physmem_zone));
Packit Service 501009
			free(lkcd->zones);
Packit Service 501009
Packit Service 501009
			lkcd->zones = zones;
Packit Service 501009
			lkcd->max_zones = max_zones;
Packit Service 501009
			goto retry;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return ret;  /* 1 if the page is new */
Packit Service 501009
}
Packit Service 501009
		
Packit Service 501009
static off_t
Packit Service 501009
get_offset(uint64_t paddr)
Packit Service 501009
{
Packit Service 501009
	uint64_t zone, page;
Packit Service 501009
	int ii;
Packit Service 501009
Packit Service 501009
	zone = paddr & lkcd->zone_mask;
Packit Service 501009
	page = (paddr % ZONE_SIZE) >> lkcd->page_shift;
Packit Service 501009
Packit Service 501009
	if (lkcd->zones == 0) {
Packit Service 501009
		return 0;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	/* find the zone */
Packit Service 501009
	for (ii=0; ii < lkcd->num_zones; ii++) {
Packit Service 501009
		if (lkcd->zones[ii].start == zone) {
Packit Service 501009
			return (lkcd->zones[ii].pages[page].offset);
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
	return 0;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
#ifdef IA64
Packit Service 501009
Packit Service 501009
int
Packit Service 501009
lkcd_get_kernel_start(ulong *addr)
Packit Service 501009
{
Packit Service 501009
	if (!addr)
Packit Service 501009
		return 0;
Packit Service 501009
Packit Service 501009
	switch (lkcd->version)
Packit Service 501009
	{
Packit Service 501009
        case LKCD_DUMP_V8:
Packit Service 501009
        case LKCD_DUMP_V9:
Packit Service 501009
		return lkcd_get_kernel_start_v8(addr);
Packit Service 501009
Packit Service 501009
	default:
Packit Service 501009
		return 0;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
Packit Service 501009
int
Packit Service 501009
lkcd_lseek(physaddr_t paddr)
Packit Service 501009
{
Packit Service 501009
	int err;
Packit Service 501009
        int eof;
Packit Service 501009
        void *dp;
Packit Service 501009
        long page = 0;
Packit Service 501009
	physaddr_t physaddr;
Packit Service 501009
	int seeked_to_page = 0;
Packit Service 501009
	off_t page_offset;
Packit Service 501009
Packit Service 501009
	dp = lkcd->dump_page;
Packit Service 501009
Packit Service 501009
	lkcd->curpos = paddr & ((physaddr_t)(lkcd->page_size-1));
Packit Service 501009
        lkcd->curpaddr = paddr & ~((physaddr_t)(lkcd->page_size-1));
Packit Service 501009
Packit Service 501009
	if (page_is_cached()) 
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	/* Faster than paging in lkcd->page_offsets[page] */
Packit Service 501009
	if(page_is_hashed(&page)) {
Packit Service 501009
		seeked_to_page = 1;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	 /* Find the offset for this page, if known */
Packit Service 501009
    if ((page_offset = get_offset(paddr)) > 0) {
Packit Service 501009
	off_t seek_offset;
Packit Service 501009
	seek_offset = lseek(lkcd->fd, page_offset, SEEK_SET);
Packit Service 501009
Packit Service 501009
	if (seek_offset == page_offset) {
Packit Service 501009
	    seeked_to_page = 1;
Packit Service 501009
	    page = 0; /* page doesn't make any sense */
Packit Service 501009
	}
Packit Service 501009
    }
Packit Service 501009
Packit Service 501009
Packit Service 501009
    if (seeked_to_page) {
Packit Service 501009
	err = lkcd_load_dump_page_header(dp, page);
Packit Service 501009
	if (err == LKCD_DUMPFILE_OK) {
Packit Service 501009
	    return(cache_page());
Packit Service 501009
	}
Packit Service 501009
    }	
Packit Service 501009
Packit Service 501009
    /* We have to grind through some more of the dump file */
Packit Service 501009
    lseek(lkcd->fd, lkcd->page_offset_max, SEEK_SET);
Packit Service 501009
    eof = FALSE;
Packit Service 501009
    while (!eof) {
Packit Service 501009
	switch (lkcd_load_dump_page_header(dp, page))
Packit Service 501009
	{
Packit Service 501009
	    case LKCD_DUMPFILE_OK:
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
	    case LKCD_DUMPFILE_EOF:
Packit Service 501009
		eof = TRUE;
Packit Service 501009
		continue;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	physaddr = lkcd->get_dp_flags() & 
Packit Service 501009
	    (LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1) ?
Packit Service 501009
	    (lkcd->get_dp_address() - lkcd->kvbase) << lkcd->page_shift:
Packit Service 501009
	    lkcd->get_dp_address() - lkcd->kvbase;
Packit Service 501009
Packit Service 501009
	if (physaddr == lkcd->curpaddr) {
Packit Service 501009
	    return(cache_page());
Packit Service 501009
	}
Packit Service 501009
	lseek(lkcd->fd, lkcd->get_dp_size(), SEEK_CUR);
Packit Service 501009
    }
Packit Service 501009
Packit Service 501009
	return FALSE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Everything's been set up by the previous lkcd_lseek(), so all that has
Packit Service 501009
 *  to be done is to read the uncompressed data into the user buffer:
Packit Service 501009
 *
Packit Service 501009
 *    lkcd->curbufptr points to the uncompressed page base.
Packit Service 501009
 *    lkcd->curpos is the offset into the buffer.
Packit Service 501009
 */
Packit Service 501009
long 
Packit Service 501009
lkcd_read(void *buf, long count)
Packit Service 501009
{
Packit Service 501009
	char *p;
Packit Service 501009
Packit Service 501009
	lkcd->total_reads++;
Packit Service 501009
Packit Service 501009
	p = lkcd->curbufptr + lkcd->curpos;
Packit Service 501009
	
Packit Service 501009
	BCOPY(p, buf, count);
Packit Service 501009
	return count;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Check whether lkcd->curpaddr is already cached.  If it is, update
Packit Service 501009
 *  lkcd->curbufptr to point to the page's uncompressed data.  
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
page_is_cached(void)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
Packit Service 501009
	for (i = 0; i < LKCD_CACHED_PAGES; i++) {
Packit Service 501009
Packit Service 501009
		if (!LKCD_VALID_PAGE(lkcd->page_cache_hdr[i].pg_flags))
Packit Service 501009
			continue;
Packit Service 501009
Packit Service 501009
		if (lkcd->page_cache_hdr[i].pg_addr == lkcd->curpaddr) {
Packit Service 501009
			lkcd->page_cache_hdr[i].pg_hit_count++;
Packit Service 501009
			lkcd->curbufptr = lkcd->page_cache_hdr[i].pg_bufptr;
Packit Service 501009
			lkcd->cached_reads++;
Packit Service 501009
			return TRUE;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return FALSE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  For an incoming page:
Packit Service 501009
 *  
Packit Service 501009
 *   (1) If it's already hashed just return TRUE.
Packit Service 501009
 *   (2) If the base page_hash_entry is unused, fill it up and return TRUE;
Packit Service 501009
 *   (3) Otherwise, find the last page_hash_entry on the list, allocate and
Packit Service 501009
 *       fill a new one, link it on the list, and return TRUE.
Packit Service 501009
 *   (4) If the malloc fails, quietly return FALSE (with no harm done).
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
hash_page(ulong type)
Packit Service 501009
{
Packit Service 501009
	struct page_hash_entry *phe;
Packit Service 501009
	int index;
Packit Service 501009
Packit Service 501009
        if (lkcd->flags & LKCD_NOHASH) {
Packit Service 501009
                lkcd->flags &= ~LKCD_NOHASH;
Packit Service 501009
		return FALSE;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	index = LKCD_PAGE_HASH_INDEX(lkcd->curpaddr);
Packit Service 501009
Packit Service 501009
	for (phe = &lkcd->page_hash[index]; LKCD_VALID_PAGE(phe->pg_flags); 
Packit Service 501009
	     phe = phe->next) {
Packit Service 501009
		if (phe->pg_addr == lkcd->curpaddr)
Packit Service 501009
			return TRUE;
Packit Service 501009
		if (!phe->next)
Packit Service 501009
			break;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (LKCD_VALID_PAGE(phe->pg_flags)) {
Packit Service 501009
		if ((phe->next = malloc
Packit Service 501009
		    (sizeof(struct page_hash_entry))) == NULL)
Packit Service 501009
			return FALSE;
Packit Service 501009
		phe = phe->next;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	phe->pg_flags |= LKCD_VALID;
Packit Service 501009
	phe->pg_addr = lkcd->curpaddr;
Packit Service 501009
	phe->pg_hdr_offset = lkcd->curhdroffs;
Packit Service 501009
	phe->next = NULL;
Packit Service 501009
Packit Service 501009
	lkcd->hashed++;
Packit Service 501009
	switch (type)
Packit Service 501009
	{
Packit Service 501009
	case LKCD_DUMP_COMPRESSED:
Packit Service 501009
		lkcd->compressed++;
Packit Service 501009
		break;
Packit Service 501009
	case LKCD_DUMP_RAW:
Packit Service 501009
		lkcd->raw++;
Packit Service 501009
		break;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return TRUE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Check whether a page is currently hashed, and if so, return the page
Packit Service 501009
 *  number so that the subsequent search loop will find it immediately.
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
page_is_hashed(long *pp)
Packit Service 501009
{
Packit Service 501009
	struct page_hash_entry *phe;
Packit Service 501009
	int index;
Packit Service 501009
Packit Service 501009
	index = LKCD_PAGE_HASH_INDEX(lkcd->curpaddr);
Packit Service 501009
Packit Service 501009
	for (phe = &lkcd->page_hash[index]; LKCD_VALID_PAGE(phe->pg_flags); 
Packit Service 501009
	     phe = phe->next) {
Packit Service 501009
		if (phe->pg_addr == lkcd->curpaddr) {
Packit Service 501009
			*pp = (long)(lkcd->curpaddr >> lkcd->page_shift);
Packit Service 501009
			lseek(lkcd->fd, phe->pg_hdr_offset, SEEK_SET);
Packit Service 501009
			lkcd->hashed_reads++;
Packit Service 501009
			return TRUE;
Packit Service 501009
		}
Packit Service 501009
		if (!phe->next)
Packit Service 501009
			break;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return FALSE;
Packit Service 501009
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  The caller stores the incoming page's page header offset in 
Packit Service 501009
 *  lkcd->curhdroffs.
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
set_mb_benchmark(ulong page)
Packit Service 501009
{
Packit Service 501009
	long mb;
Packit Service 501009
Packit Service 501009
	if ((mb = LKCD_PAGE_MEGABYTE(page)) >= lkcd->benchmark_pages)
Packit Service 501009
		return FALSE;
Packit Service 501009
Packit Service 501009
        if (!lkcd->mb_hdr_offsets[mb]) {
Packit Service 501009
        	lkcd->mb_hdr_offsets[mb] = lkcd->curhdroffs;
Packit Service 501009
		lkcd->benchmarks_done++;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	return TRUE;
Packit Service 501009
}
Packit Service 501009
	
Packit Service 501009
/*
Packit Service 501009
 *  Coming into this routine:
Packit Service 501009
 *
Packit Service 501009
 *   (1) lkcd->curpaddr points to the page address as specified in the dumpfile.
Packit Service 501009
 *   (2) the dump_page header has been copied into lkcd->dump_page.
Packit Service 501009
 *   (3) the file pointer is sitting at the beginning of the page data,
Packit Service 501009
 *       be it compressed or otherwise.
Packit Service 501009
 *   (4) lkcd->curhdroffs contains the file pointer to the incoming page's
Packit Service 501009
 *       header offset.
Packit Service 501009
 *
Packit Service 501009
 *  If an empty page cache location is available, take it.  Otherwise, evict
Packit Service 501009
 *  the entry indexed by evict_index, and then bump evict index.  The hit_count
Packit Service 501009
 *  is only gathered for dump_lkcd_environment().
Packit Service 501009
 *
Packit Service 501009
 *  If the page is compressed, uncompress it into the selected page cache entry.
Packit Service 501009
 *  If the page is raw, just copy it into the selected page cache entry.
Packit Service 501009
 *  If all works OK, update lkcd->curbufptr to point to the page's uncompressed
Packit Service 501009
 *  data.
Packit Service 501009
 *
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
cache_page(void)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	ulong type;
Packit Service 501009
	int found, newsz;
Packit Service 501009
	uint32_t rawsz;
Packit Service 501009
	ssize_t bytes ATTRIBUTE_UNUSED;
Packit Service 501009
Packit Service 501009
Packit Service 501009
        for (i = found = 0; i < LKCD_CACHED_PAGES; i++) {
Packit Service 501009
                if (LKCD_VALID_PAGE(lkcd->page_cache_hdr[i].pg_flags))
Packit Service 501009
                        continue;
Packit Service 501009
		found = TRUE;
Packit Service 501009
		break;
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
	if (!found) {
Packit Service 501009
                i = lkcd->evict_index;
Packit Service 501009
		lkcd->page_cache_hdr[i].pg_hit_count = 0;
Packit Service 501009
                lkcd->evict_index = (lkcd->evict_index+1) % LKCD_CACHED_PAGES;
Packit Service 501009
                lkcd->evictions++;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        lkcd->page_cache_hdr[i].pg_flags = 0;
Packit Service 501009
        lkcd->page_cache_hdr[i].pg_addr = lkcd->curpaddr;
Packit Service 501009
	lkcd->page_cache_hdr[i].pg_hit_count++;
Packit Service 501009
Packit Service 501009
	type = lkcd->get_dp_flags() & (LKCD_DUMP_COMPRESSED|LKCD_DUMP_RAW);
Packit Service 501009
Packit Service 501009
	switch (type)
Packit Service 501009
	{
Packit Service 501009
	case LKCD_DUMP_COMPRESSED:
Packit Service 501009
		if (LKCD_DEBUG(2)) 
Packit Service 501009
			dump_dump_page("cmp: ", lkcd->dump_page);
Packit Service 501009
		
Packit Service 501009
		newsz = 0;
Packit Service 501009
		BZERO(lkcd->compressed_page, lkcd->page_size);
Packit Service 501009
                bytes = read(lkcd->fd, lkcd->compressed_page, lkcd->get_dp_size());
Packit Service 501009
Packit Service 501009
		switch (lkcd->compression)
Packit Service 501009
		{
Packit Service 501009
		case LKCD_DUMP_COMPRESS_NONE:
Packit Service 501009
			lkcd_print("dump_header: DUMP_COMPRESS_NONE and "
Packit Service 501009
			          "dump_page: DUMP_COMPRESSED (?)\n");
Packit Service 501009
			return FALSE;
Packit Service 501009
Packit Service 501009
		case LKCD_DUMP_COMPRESS_RLE:
Packit Service 501009
			if (!lkcd_uncompress_RLE((unsigned char *)
Packit Service 501009
			    lkcd->compressed_page,
Packit Service 501009
			    (unsigned char *)lkcd->page_cache_hdr[i].pg_bufptr, 	
Packit Service 501009
			    lkcd->get_dp_size(), &newsz) || 
Packit Service 501009
			    (newsz != lkcd->page_size)) {
Packit Service 501009
				lkcd_print("uncompress of page ");
Packit Service 501009
				lkcd_print(BITS32() ? 
Packit Service 501009
					"%llx failed!\n" : "%lx failed!\n",
Packit Service 501009
					lkcd->get_dp_address());
Packit Service 501009
				lkcd_print("newsz returned: %d\n", newsz);
Packit Service 501009
				return FALSE;
Packit Service 501009
			}
Packit Service 501009
			break;
Packit Service 501009
Packit Service 501009
		case LKCD_DUMP_COMPRESS_GZIP:
Packit Service 501009
			if (!lkcd_uncompress_gzip((unsigned char *)
Packit Service 501009
			    lkcd->page_cache_hdr[i].pg_bufptr, lkcd->page_size,
Packit Service 501009
			    (unsigned char *)lkcd->compressed_page, 
Packit Service 501009
			    lkcd->get_dp_size())) {
Packit Service 501009
                                lkcd_print("uncompress of page ");
Packit Service 501009
                                lkcd_print(BITS32() ? 
Packit Service 501009
                                        "%llx failed!\n" : "%lx failed!\n",
Packit Service 501009
                                        lkcd->get_dp_address());
Packit Service 501009
				return FALSE;
Packit Service 501009
			}
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
	case LKCD_DUMP_RAW:
Packit Service 501009
		if (LKCD_DEBUG(2)) 
Packit Service 501009
			dump_dump_page("raw: ", lkcd->dump_page);
Packit Service 501009
		if ((rawsz = lkcd->get_dp_size()) == 0)
Packit Service 501009
			BZERO(lkcd->page_cache_hdr[i].pg_bufptr, 
Packit Service 501009
				lkcd->page_size);
Packit Service 501009
		else if (rawsz == lkcd->page_size)
Packit Service 501009
			bytes = read(lkcd->fd, lkcd->page_cache_hdr[i].pg_bufptr, 
Packit Service 501009
				lkcd->page_size);
Packit Service 501009
		else {
Packit Service 501009
			lkcd_print("cache_page: "
Packit Service 501009
		        	"invalid LKCD_DUMP_RAW dp_size\n");
Packit Service 501009
			dump_lkcd_environment(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
			return FALSE;
Packit Service 501009
		}
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
	default:
Packit Service 501009
		lkcd_print("cache_page: bogus page:\n");
Packit Service 501009
		dump_lkcd_environment(LKCD_DUMP_PAGE_ONLY);
Packit Service 501009
		return FALSE;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        lkcd->page_cache_hdr[i].pg_flags |= LKCD_VALID;
Packit Service 501009
	lkcd->curbufptr = lkcd->page_cache_hdr[i].pg_bufptr;
Packit Service 501009
Packit Service 501009
	hash_page(type);
Packit Service 501009
Packit Service 501009
	return TRUE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Uncompress an RLE-encoded buffer.
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
lkcd_uncompress_RLE(unsigned char *cbuf, unsigned char *ucbuf, 
Packit Service 501009
	       uint32_t blk_size, int *new_size)
Packit Service 501009
{
Packit Service 501009
        int i;
Packit Service 501009
        unsigned char value, count, cur_byte;
Packit Service 501009
        uint32_t ri, wi;
Packit Service 501009
Packit Service 501009
        /* initialize the read / write indices */
Packit Service 501009
        ri = wi = 0;
Packit Service 501009
Packit Service 501009
        /* otherwise decompress using run length encoding */
Packit Service 501009
        while(ri < blk_size) {
Packit Service 501009
                cur_byte = cbuf[ri++];
Packit Service 501009
                if (cur_byte == 0) {
Packit Service 501009
                        count = cbuf[ri++];
Packit Service 501009
                        if (count == 0) {
Packit Service 501009
                                ucbuf[wi++] = 0;
Packit Service 501009
                        } else {
Packit Service 501009
                                value = cbuf[ri++];
Packit Service 501009
                                for (i = 0; i <= count; i++) {
Packit Service 501009
                                        ucbuf[wi++] = value;
Packit Service 501009
                                }
Packit Service 501009
                        }
Packit Service 501009
                } else {
Packit Service 501009
                        ucbuf[wi++] = cur_byte;
Packit Service 501009
                }
Packit Service 501009
Packit Service 501009
                /* if our write index is beyond the page size, exit out */
Packit Service 501009
                if (wi > /* PAGE_SIZE */ lkcd->page_size) {
Packit Service 501009
			lkcd_print( 
Packit Service 501009
           "Attempted to decompress beyond page boundaries: file corrupted!\n");
Packit Service 501009
                        return (0);
Packit Service 501009
                }
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
        /* set return size to be equal to uncompressed size (in bytes) */
Packit Service 501009
        *new_size = wi;
Packit Service 501009
Packit Service 501009
        return 1;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/* Returns the bit offset if it's able to correct, or negative if not */
Packit Service 501009
static int
Packit Service 501009
uncompress_recover(unsigned char *dest, ulong destlen,
Packit Service 501009
    unsigned char *source, ulong sourcelen)
Packit Service 501009
{
Packit Service 501009
        int byte, bit;
Packit Service 501009
        ulong retlen = destlen;
Packit Service 501009
        int good_decomp = 0, good_rv = -1;
Packit Service 501009
Packit Service 501009
        /* Generate all single bit errors */
Packit Service 501009
        if (sourcelen > 16384) {
Packit Service 501009
                lkcd_print("uncompress_recover: sourcelen %ld too long\n",
Packit Service 501009
                    sourcelen);
Packit Service 501009
                return(-1);
Packit Service 501009
        }
Packit Service 501009
        for (byte = 0; byte < sourcelen; byte++) {
Packit Service 501009
                for (bit = 0; bit < 8; bit++) {
Packit Service 501009
                        source[byte] ^= (1 << bit);
Packit Service 501009
Packit Service 501009
                        if (uncompress(dest, &retlen, source, sourcelen) == Z_OK &&
Packit Service 501009
                            retlen == destlen) {
Packit Service 501009
                                good_decomp++;
Packit Service 501009
                                lkcd_print("good for flipping byte %d bit %d\n",
Packit Service 501009
                                    byte, bit);
Packit Service 501009
                                good_rv = bit + byte * 8;
Packit Service 501009
                        }
Packit Service 501009
Packit Service 501009
                        /* Put it back */
Packit Service 501009
                        source[byte] ^= (1 << bit);
Packit Service 501009
                }
Packit Service 501009
        }
Packit Service 501009
        if (good_decomp == 0) {
Packit Service 501009
                lkcd_print("Could not correct gzip errors.\n");
Packit Service 501009
                return -2;
Packit Service 501009
        } else if (good_decomp > 1) {
Packit Service 501009
                lkcd_print("Too many valid gzip decompressions: %d.\n", good_decomp);
Packit Service 501009
                return -3;
Packit Service 501009
        } else {
Packit Service 501009
                source[good_rv >> 8] ^= 1 << (good_rv % 8);
Packit Service 501009
                uncompress(dest, &retlen, source, sourcelen);
Packit Service 501009
                source[good_rv >> 8] ^= 1 << (good_rv % 8);
Packit Service 501009
                return good_rv;
Packit Service 501009
        }
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Uncompress a gzip'd buffer.
Packit Service 501009
 *
Packit Service 501009
 *  Returns FALSE on error.  If set, then
Packit Service 501009
 *    a non-negative value of uncompress_errloc indicates the location of
Packit Service 501009
 *    a single-bit error, and the data may be used.
Packit Service 501009
 */
Packit Service 501009
static int 
Packit Service 501009
lkcd_uncompress_gzip(unsigned char *dest, ulong destlen, 
Packit Service 501009
	unsigned char *source, ulong sourcelen)
Packit Service 501009
{
Packit Service 501009
        ulong retlen = destlen;
Packit Service 501009
        int rc = FALSE;
Packit Service 501009
Packit Service 501009
	switch (uncompress(dest, &retlen, source, sourcelen)) 
Packit Service 501009
	{
Packit Service 501009
	case Z_OK:
Packit Service 501009
		if (retlen == destlen) {
Packit Service 501009
                        rc = TRUE;
Packit Service 501009
                        break;
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
		lkcd_print("uncompress: returned length not page size: %ld\n",
Packit Service 501009
				retlen);
Packit Service 501009
                rc = FALSE;
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
	case Z_MEM_ERROR:
Packit Service 501009
		lkcd_print("uncompress: Z_MEM_ERROR (not enough memory)\n");
Packit Service 501009
                rc = FALSE;
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
	case Z_BUF_ERROR:
Packit Service 501009
		lkcd_print("uncompress: "
Packit Service 501009
			"Z_BUF_ERROR (not enough room in output buffer)\n");
Packit Service 501009
                rc = FALSE;
Packit Service 501009
                break;
Packit Service 501009
Packit Service 501009
	case Z_DATA_ERROR:
Packit Service 501009
		lkcd_print("uncompress: Z_DATA_ERROR (input data corrupted)\n");
Packit Service 501009
                rc = FALSE;
Packit Service 501009
                break;
Packit Service 501009
        default:
Packit Service 501009
                rc = FALSE;
Packit Service 501009
                break;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        if (rc == FALSE) {
Packit Service 501009
                uncompress_errloc =
Packit Service 501009
                    uncompress_recover(dest, destlen, source, sourcelen);
Packit Service 501009
        }
Packit Service 501009
	return rc;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Generic print routine to handle integral and remote daemon usage of
Packit Service 501009
 */
Packit Service 501009
void 
Packit Service 501009
lkcd_print(char *fmt, ...)
Packit Service 501009
{
Packit Service 501009
	char buf[BUFSIZE];
Packit Service 501009
	va_list ap;
Packit Service 501009
Packit Service 501009
        if (!fmt || !strlen(fmt))
Packit Service 501009
                return;
Packit Service 501009
Packit Service 501009
        va_start(ap, fmt);
Packit Service 501009
        (void)vsnprintf(buf, BUFSIZE, fmt, ap);
Packit Service 501009
        va_end(ap);
Packit Service 501009
Packit Service 501009
	if (lkcd->fp)
Packit Service 501009
		fprintf(lkcd->fp, "%s", buf);
Packit Service 501009
	else
Packit Service 501009
		console(buf);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Try to read the current dump page header, reporting back either
Packit Service 501009
 *  LKCD_DUMPFILE_EOF, LKCD_DUMPFILE_END or LKCD_DUMPFILE_OK.  The header's
Packit Service 501009
 *  file pointer position is saved in lkcd->curhdroffs.  If the page is
Packit Service 501009
 *  an even megabyte, save its offset.
Packit Service 501009
 */
Packit Service 501009
int
Packit Service 501009
lkcd_load_dump_page_header(void *dp, ulong page)
Packit Service 501009
{
Packit Service 501009
	uint32_t dp_flags;
Packit Service 501009
	uint64_t dp_address, physaddr;
Packit Service 501009
	off_t page_offset;
Packit Service 501009
	int ret;
Packit Service 501009
Packit Service 501009
Packit Service 501009
	/* This is wasted effort */
Packit Service 501009
        page_offset = lkcd->curhdroffs = lseek(lkcd->fd, 0, SEEK_CUR);
Packit Service 501009
Packit Service 501009
        if (read(lkcd->fd, dp, lkcd->page_header_size) != 
Packit Service 501009
	    lkcd->page_header_size) {
Packit Service 501009
		if (page > lkcd->total_pages) 
Packit Service 501009
			lkcd_dumpfile_complaint(page, lkcd->total_pages, 
Packit Service 501009
				LKCD_DUMPFILE_EOF);
Packit Service 501009
                return LKCD_DUMPFILE_EOF;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	dp_flags = lkcd->get_dp_flags();
Packit Service 501009
	dp_address = lkcd->get_dp_address();
Packit Service 501009
Packit Service 501009
        if (dp_flags & LKCD_DUMP_END) {
Packit Service 501009
                return LKCD_DUMPFILE_END;
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
	if ((lkcd->flags & LKCD_VALID) && (page > lkcd->total_pages)) 
Packit Service 501009
		lkcd->total_pages = page;
Packit Service 501009
Packit Service 501009
#ifdef X86
Packit Service 501009
	/*
Packit Service 501009
	 *  Ugly leftover from very early x86 LKCD versions which used 
Packit Service 501009
	 *  the kernel unity-mapped virtual address as the dp_address.
Packit Service 501009
	 */
Packit Service 501009
        if ((page == 0) && !(lkcd->flags & LKCD_VALID) && 
Packit Service 501009
	    (lkcd->version == LKCD_DUMP_V1) && 
Packit Service 501009
	    (dp_address == 0xc0000000)) 
Packit Service 501009
        	lkcd->kvbase = dp_address;
Packit Service 501009
#endif
Packit Service 501009
Packit Service 501009
	physaddr = dp_flags & (LKCD_DUMP_MCLX_V0|LKCD_DUMP_MCLX_V1) ?
Packit Service 501009
		(dp_address - lkcd->kvbase) << lkcd->page_shift : 
Packit Service 501009
        	dp_address - lkcd->kvbase;
Packit Service 501009
Packit Service 501009
Packit Service 501009
	if ((ret = save_offset(physaddr, page_offset)) < 0) {
Packit Service 501009
	    return LKCD_DUMPFILE_EOF; /* really an error */
Packit Service 501009
	} 
Packit Service 501009
Packit Service 501009
	lkcd->zoned_offsets += ret;  /* return = 0 if already known */
Packit Service 501009
Packit Service 501009
	if (page_offset > lkcd->page_offset_max) {
Packit Service 501009
	    /* doesn't this mean I have to re-read this dp? */
Packit Service 501009
	    lkcd->page_offset_max = page_offset;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
Packit Service 501009
	return LKCD_DUMPFILE_OK;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Register a complaint one time, if appropriate.
Packit Service 501009
 */
Packit Service 501009
void
Packit Service 501009
lkcd_dumpfile_complaint(uint32_t realpages, uint32_t dh_num_pages, int retval)
Packit Service 501009
{
Packit Service 501009
	if (lkcd->flags & LKCD_BAD_DUMP)
Packit Service 501009
		return;
Packit Service 501009
	
Packit Service 501009
	lkcd->flags |= LKCD_BAD_DUMP;
Packit Service 501009
Packit Service 501009
	if (realpages > dh_num_pages) {
Packit Service 501009
		lkcd_print(
Packit Service 501009
"\n\nWARNING: This dumpfile contains more pages than the amount indicated\n"
Packit Service 501009
"         in the dumpfile header.  This is indicative of a failure during\n"
Packit Service 501009
"         the post-panic creation of the dumpfile on the dump device.\n\n");
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (realpages < dh_num_pages) {
Packit Service 501009
		lkcd_print(
Packit Service 501009
"\n\nWARNING: This dumpfile contains fewer pages than the amount indicated\n"
Packit Service 501009
"         in the dumpfile header.  This is indicative of a failure during\n"
Packit Service 501009
"         the creation of the dumpfile during boot.\n\n");
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
int
Packit Service 501009
get_lkcd_regs_for_cpu(struct bt_info *bt, ulong *eip, ulong *esp)
Packit Service 501009
{
Packit Service 501009
	switch (lkcd->version) {
Packit Service 501009
	case LKCD_DUMP_V8:
Packit Service 501009
	case LKCD_DUMP_V9:
Packit Service 501009
		return get_lkcd_regs_for_cpu_v8(bt, eip, esp);
Packit Service 501009
	default:
Packit Service 501009
		return -1;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009