Logo Search packages:      
Sourcecode: lcrash version File versions  Download package

kl_dumpaccess.c

/*
 * $Id: kl_dumpaccess.c,v 1.2 2005/02/23 01:09:12 tjm Exp $
 *
 * This file is part of libklib.
 * A library which provides access to Linux system kernel dumps.
 *
 * Created by Silicon Graphics, Inc.
 * Contributions by IBM, NEC, and others
 *
 * Copyright (C) 1999 - 2005 Silicon Graphics, Inc. All rights reserved.
 * Copyright (C) 2001, 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
 * Copyright 2000 Junichi Nomura, NEC Solutions <j-nomura@ce.jp.nec.com>
 *
 * This code is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */

#include <klib.h>

/*
 * declarations of static functions
 */

/* get integer value from buffer */
static kaddr_t  _kl_get_ptr(void*);
static uint8_t  _kl_get_uint8(void*);
static uint16_t _kl_get_uint16(void*);
static uint32_t _kl_get_uint32(void*);
static uint64_t _kl_get_uint64(void*);
/* read integer value from dump (physical address) */
static kaddr_t  _kl_read_ptr(kaddr_t);
static uint8_t  _kl_read_uint8(kaddr_t);
static uint16_t _kl_read_uint16(kaddr_t);
static uint32_t _kl_read_uint32(kaddr_t);
static uint64_t _kl_read_uint64(kaddr_t);
/* read integer value from dump (virtual address) */
static kaddr_t  _kl_vread_ptr(kaddr_t);
static uint8_t  _kl_vread_uint8(kaddr_t);
static uint16_t _kl_vread_uint16(kaddr_t);
static uint32_t _kl_vread_uint32(kaddr_t);
static uint64_t _kl_vread_uint64(kaddr_t);

/*
 * function definitions
 */

/* kl_set_dumpaccess()
 */
int
kl_set_dumpaccess(void)
{
      /* make sure byteorder of dump and host are set */
      if(!(KLP->host->byteorder && KLP->dump->arch.byteorder)){
            return(1);
      }

      if(KLP->host->byteorder == KLP->dump->arch.byteorder){
            /* no need for byte swappping */
            KLP->dump->func.get_ptr      = _kl_get_ptr;
            KLP->dump->func.get_uint16   = _kl_get_uint16;
            KLP->dump->func.get_uint32   = _kl_get_uint32;
            KLP->dump->func.get_uint64   = _kl_get_uint64;
            KLP->dump->func.read_ptr     = _kl_read_ptr;
            KLP->dump->func.read_uint16  = _kl_read_uint16;
            KLP->dump->func.read_uint32  = _kl_read_uint32;
            KLP->dump->func.read_uint64  = _kl_read_uint64;
            KLP->dump->func.vread_ptr    = _kl_vread_ptr;
            KLP->dump->func.vread_uint16 = _kl_vread_uint16;
            KLP->dump->func.vread_uint32 = _kl_vread_uint32;
            KLP->dump->func.vread_uint64 = _kl_vread_uint64;
      } else {/* (KLP->host->byteorder != KLP->dump->arch.byteorder) */
            /* byte swapping needed */
            KLP->dump->func.get_ptr      = kl_get_swap_ptr;
            KLP->dump->func.get_uint16   = kl_get_swap_uint16;
            KLP->dump->func.get_uint32   = kl_get_swap_uint32;
            KLP->dump->func.get_uint64   = kl_get_swap_uint64;
            KLP->dump->func.read_ptr     = kl_read_swap_ptr;
            KLP->dump->func.read_uint16  = kl_read_swap_uint16;
            KLP->dump->func.read_uint32  = kl_read_swap_uint32;
            KLP->dump->func.read_uint64  = kl_read_swap_uint64;
            KLP->dump->func.vread_ptr    = kl_vread_swap_ptr;
            KLP->dump->func.vread_uint16 = kl_vread_swap_uint16;
            KLP->dump->func.vread_uint32 = kl_vread_swap_uint32;
            KLP->dump->func.vread_uint64 = kl_vread_swap_uint64;
      }

      /* common functions regardless of byteorder
       */
      KLP->dump->func.get_uint8    = _kl_get_uint8; 
      KLP->dump->func.read_uint8   = _kl_read_uint8; 
      KLP->dump->func.vread_uint8  = _kl_vread_uint8; 

      return(0);
}

/* get integer values from buffer previously filled from dump
 */
kaddr_t
_kl_get_ptr(void *ptr)
{
      switch(KLP->dump->arch.ptrsz){
      case 32:
            return (kaddr_t) (*(uint32_t*) ptr);
      case 64:
            return (kaddr_t) (*(uint64_t*) ptr);
      default:
            /* XXX set error code */
            return ((kaddr_t) 0);
      }
}

uint8_t
_kl_get_uint8(void *ptr)
{
      return *(uint8_t*) ptr;
}

uint16_t
_kl_get_uint16(void *ptr)
{
      uint16_t val;
      memcpy(&val, ptr, 2);
      return *(uint16_t*) &val;
}

uint32_t
_kl_get_uint32(void *ptr)
{
      uint32_t val;
      memcpy(&val, ptr, 4);
      return *(uint32_t*) &val;
}

uint64_t
_kl_get_uint64(void *ptr)
{
      uint64_t val;
      memcpy(&val, ptr, 8);
      return *(uint64_t*) &val;
}

/* read integer values directly from dump without address conversion
 */
kaddr_t
_kl_read_ptr(kaddr_t ptr)
{
      switch(KLP->dump->arch.ptrsz){
      case 32:
            {
                  uint32_t t;
                  kl_readmem(ptr, 4, &t);
                  return((kaddr_t)t);
            }
      case 64:
            {
                  uint64_t t;
                  kl_readmem(ptr, 8, &t);
                  return(t);
            }
      default:
            /* XXX set error code */
            return ((kaddr_t) 0);
      }
}

uint8_t
_kl_read_uint8(kaddr_t ptr)
{
      uint8_t t;
      kl_readmem(ptr, 1, &t);
      return(t);
}

uint16_t
_kl_read_uint16(kaddr_t ptr)
{
      uint16_t t;
      kl_readmem(ptr, 2, &t);
      return(t);
}

uint32_t
_kl_read_uint32(kaddr_t ptr)
{
      uint32_t t;
      kl_readmem(ptr, 4, &t);
      return(t);
}

uint64_t
_kl_read_uint64(kaddr_t ptr)
{
      uint64_t t;
      kl_readmem(ptr, 8, &t);
      return(t);
}

/* read integer values directly from dump including address conversion
 */
kaddr_t
_kl_vread_ptr(kaddr_t ptr)
{
      switch(KLP->dump->arch.ptrsz){
      case 32:
            {
                  uint32_t t;
                  GET_BLOCK(ptr, 4, &t);
                  return((kaddr_t)t);
            }
      case 64:
            {
                  uint64_t t;
                  GET_BLOCK(ptr, 8, &t);
                  return(t);
            }
      default:
            /* XXX set error code */
            return ((kaddr_t) 0);
      }
}

uint8_t
_kl_vread_uint8(kaddr_t ptr)
{
      uint8_t t;
      GET_BLOCK(ptr, 1, &t);
      return(t);
}

uint16_t
_kl_vread_uint16(kaddr_t ptr)
{
      uint16_t t;
      GET_BLOCK(ptr, 2, &t);
      return(t);
}

uint32_t
_kl_vread_uint32(kaddr_t ptr)
{
      uint32_t t;
      GET_BLOCK(ptr, 4, &t);
      return(t);
}

uint64_t
_kl_vread_uint64(kaddr_t ptr)
{
      uint64_t t;
      GET_BLOCK(ptr, 8, &t);
      return(t);
}

uint16_t
kl_get_swap_uint16(void *ptr)
{
      uint16_t t, rawval;

      memcpy(&rawval, ptr, 2);

      t =      (rawval << 8) & 0xff00;
      t = t | ((rawval >> 8) & 0x00ff);

      return t;
}

uint32_t
kl_get_swap_uint32(void *ptr)
{
      uint32_t t, rawval;

      memcpy(&rawval, ptr, 4);

      t =      (rawval << 24) & 0xff000000;
      t = t | ((rawval <<  8) & 0x00ff0000);
      t = t | ((rawval >>  8) & 0x0000ff00);
      t = t | ((rawval >> 24) & 0x000000ff);

      return t;
}

uint64_t
kl_get_swap_uint64(void *ptr)
{
      uint32_t l, h;
      uint64_t rawval;

      memcpy(&rawval, ptr, 8);

        h =      ((uint32_t)(rawval) << 24) & 0xff000000;
        h = h | (((uint32_t)(rawval) <<  8) & 0x00ff0000);
        h = h | (((uint32_t)(rawval) >>  8) & 0x0000ff00);
        h = h | (((uint32_t)(rawval) >> 24) & 0x000000ff);

        l =      ((rawval >> 32) << 24) & 0xff000000;
        l = l | (((rawval >> 32) <<  8) & 0x00ff0000);
        l = l | (((rawval >> 32) >>  8) & 0x0000ff00);
        l = l | (((rawval >> 32) >> 24) & 0x000000ff);

      return (uint64_t) h << 32 | (uint64_t) l;
}

/* get integer values from buffer previously filled from dump
 * and swap bytes
 */
kaddr_t
kl_get_swap_ptr(void *ptr)
{
      kaddr_t val = (kaddr_t)0;

      switch(KLP->dump->arch.ptrsz){
      case 32:
            val = (kaddr_t)kl_get_swap_uint32(ptr);
            break;

      case 64:

            val = (kaddr_t)kl_get_swap_uint64(ptr);
            break;

      default:
            /* XXX set error code */
            val = (kaddr_t)0;
      }
      return(val);
}

/* read integer values from dump and swap bytes
 */
kaddr_t
kl_read_swap_ptr(kaddr_t ptr)
{
      uint64_t t;
      uint32_t s;
      kaddr_t val;

      switch(KLP->dump->arch.ptrsz) {
            case 32:
                  kl_readmem(ptr, 4, &s);
                  val = (kaddr_t)kl_get_swap_uint32(&s);
                  break;

            case 64:
                  kl_readmem(ptr, 8, &t);
                  val = (kaddr_t)kl_get_swap_uint64(&t);
                  break;

            default:
                  /* XXX set error code */
                  val = (kaddr_t)0;
                  break;
      }
      return(val);
}

uint16_t
kl_read_swap_uint16(kaddr_t ptr)
{
      uint16_t s, val;

      kl_readmem(ptr, 2, &s);
      val = (uint16_t)kl_get_swap_uint16(&s);
      return(val);
}

uint32_t
kl_read_swap_uint32(kaddr_t ptr)
{
      uint32_t s, val;

      kl_readmem(ptr, 4, &s);
      val = (uint32_t)kl_get_swap_uint32(&s);
      return(val);
}

uint64_t
kl_read_swap_uint64(kaddr_t ptr)
{
      uint64_t t, val;

      kl_readmem(ptr, 8, &t);
      val = (uint64_t)kl_get_swap_uint64(&t);
      return(val);
}

/* read integer values from dump and swap bytes
*/
kaddr_t
kl_vread_swap_ptr(kaddr_t ptr)
{
      uint64_t t=0;

      switch(KLP->dump->arch.ptrsz){
      case 32:
            GET_BLOCK(ptr, 4, &t);
            return kl_get_swap_ptr((void*) &t); 
      case 64:
            GET_BLOCK(ptr, 8, &t);
            return kl_get_swap_ptr((void*) &t); 
      default:
            /* XXX set error code */
            return ((kaddr_t) 0);
      }
}

uint16_t
kl_vread_swap_uint16(kaddr_t ptr)
{
      uint16_t s, val;

      GET_BLOCK(ptr, 2, &s);
      val = (uint16_t)kl_get_swap_uint16(&s);
      return(val);
}

uint32_t
kl_vread_swap_uint32(kaddr_t ptr)
{
      uint32_t s, val;

      GET_BLOCK(ptr, 4, &s);
      val = (uint32_t)kl_get_swap_uint32(&s);
      return(val);
}

uint64_t
kl_vread_swap_uint64(kaddr_t ptr)
{
      uint64_t s, val;

      GET_BLOCK(ptr, 8, &s);
      val = (uint64_t)kl_get_swap_uint64(&s);
      return(val);
}

#ifdef NOT
/*
 * kl_get_arch() -- tries to determine architecture of dump
 */
int
kl_get_arch(char *dump)
{
      int fd, dumparch = KL_ARCH_UNKNOWN;

      if (!dump) {
            return(KL_ARCH_UNKNOWN);
      }
      if (strcmp(dump, "/dev/mem") == 0) {
            /* This is a live system. There is no dump_header to
             * look for. We should make the dumparch the same as
             * the targetarch.
             */
            return(KL_LIVE_SYSTEM);
      }
      if((fd = open(dump, O_RDONLY)) < 0){
            KL_ERROR = KLE_OPEN_ERROR|KLE_DUMP;
      } else {
            dumparch = kl_get_dumparch(fd);
            close(fd);
      }
      return(dumparch);
}
#endif

Generated by  Doxygen 1.6.0   Back to index