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

hwgraph.c

/*
 * $Id: hwgraph.c,v 1.1 2004/12/21 23:26:17 tjm Exp $
 *
 * This file is part of lcrash, an analysis tool for Linux memory dumps.
 *
 * Created by Silicon Graphics, Inc.
 *
 * Copyright (C) 2003 - 2004 Silicon Graphics, Inc. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the file COPYING for more
 * information.
 */
#include <lcrash.h>
#include <kl_hwgraph.h>

/*
 * vertex_banner()
 */
void
vertex_banner(FILE *ofp, int flags)
{
        if (flags & BANNER) {
                fprintf(ofp, "            DENTRY                  NAME  "
                  "REFCNT     MODE                INFO\n");
        }

        if (flags & SMAJOR) {
                fprintf(ofp, "=========================================="
                  "===================================\n");

        } else if (flags & SMINOR) {
                fprintf(ofp, "------------------------------------------"
                  "-----------------------------------\n");
        }
}

/*
 * print_vertex_devfs()
 */
int
print_vertex_devfs(kaddr_t vertex, void *vp, int flags, FILE *ofp)
{
      int i, mode, namelen, link_name_sz, num_labels;
      char vname[128], label[LABEL_LENGTH_MAX];
      kaddr_t info, label_list, link_name;
      void *infop, *labelp, *link_name_p;
      uint64_t value;

      mode = KL_UINT(vp, "devfs_entry", "mode");
      namelen = KL_UINT(vp, "devfs_entry", "namelen");
      GET_BLOCK((vertex + kl_member_offset("devfs_entry", "name")),
            namelen, vname);
      vname[namelen] = 0;

      fprintf(ofp, "0x%16lx  ", vertex);
      fprintf(ofp, "%20s", vname);
      print_value(ofp, "  ",
            UINT64(KL_UINT(K_PTR(vp, "devfs_entry", "refcount"),
            "atomic_t", "counter")), 6, UNSIGNED_FLG);
      fprintf(ofp, "  %07o", mode);
      info = kl_kaddr(vp, "devfs_entry", "info");
      print_value(ofp, "  ", ADDR64(info), 18, ADDR_FLG);
      fprintf(ofp, "\n");
      if (flags & C_FULL) {

            fprintf(ofp, "\n");
            if ((value = ADDR64(kl_kaddr(vp, "devfs_entry", "next")))) {
                  print_value(ofp, "next=", value, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, "next=(nil)");
            }
            if ((value = ADDR64(kl_kaddr(vp, "devfs_entry", "prev")))) {
                  print_value(ofp, ", prev=", value, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, ", prev=(nil)");
            }

            fprintf(ofp, "\n");
            if ((value = ADDR64(kl_kaddr(vp, "devfs_entry", "parent")))) {
                  print_value(ofp, "parent=", value, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, "parent=(nil)");
            }
            if ((value = ADDR64(kl_kaddr(vp, "devfs_entry", "slave")))) {
                  print_value(ofp, ", slave=", value, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, ", slave=(nil)");
            }

            fprintf(ofp, "\n\n");
            if (IS_SPECIAL(mode)) {
                  fprintf(ofp, "SPECIAL FILE:\n");
            } else if (IS_DIR(mode)) {
                  fprintf(ofp, "DIRECTORY:\n\n");

                  value = ADDR64(kl_kaddr(K_PTR(vp, "devfs_entry", "u"),
                        "directory_type", "first"));
                  if (value) {
                        print_value(ofp, "  first=",
                              value, 18, ADDR_FLG);
                  } else {
                        fprintf(ofp, "  first=(nil)");
                  }

                  value = ADDR64(kl_kaddr(K_PTR(vp, "devfs_entry", "u"),
                        "directory_type", "last"));
                  if (value) {
                        print_value(ofp, ", last=",
                              value, 18, ADDR_FLG);
                  } else {
                        fprintf(ofp, ", last=(nil)");
                  }
                  fprintf(ofp, "\n");
            } else if (IS_LINK(mode)) {
                  fprintf(ofp, "LINK\n");
                  link_name_sz = KL_UINT(K_PTR(vp, "devfs_entry", "u"),
                        "symlink_type", "length");
                  link_name_p = kl_alloc_block(link_name_sz + 1, K_TEMP);
                  link_name = kl_kaddr(K_PTR(vp, "devfs_entry", "u"),
                        "symlink_type", "linkname");
                  GET_BLOCK(link_name, link_name_sz, link_name_p);
                  *((char *)((long)link_name_p + link_name_sz)) = 0;
                  fprintf(ofp, "  linkname=%s\n", (char *)link_name_p);
                  kl_free_block(link_name_p);
            } else if (IS_REG(mode)) {
                  fprintf(ofp, "REGULAR FILE\n");
            } else {
                  fprintf(ofp, "UNKNOWN MODE (%o)\n", mode);
            }
            fprintf(ofp, "\n");

            if (info) {
                  infop = kl_alloc_block(LABELCL_INFO_SZ, K_TEMP);
                  labelp = kl_alloc_block(LABEL_INFO_SZ, K_TEMP);
                  if (KL_ERROR) {
                        return(1);
                  }
                  GET_BLOCK(info, LABELCL_INFO_SZ, infop);
                  if (KL_ERROR) {
                        /* XXX -- print error */;
                        return(1);
                  }

                  /* Check the magic number to ensure we have a
                   * valid info struct...
                   */
                  if (*(uint64_t*)infop != INFO_MAGIC) {
                        fprintf(ofp, "BAD info magic number "
                              "(0x%lx)\n", *(uint64_t*)infop);
                        return(1);
                  }

                  fprintf(ofp, "INFO:\n\n");

                  num_labels = KL_UINT(infop,
                        "labelcl_info_s", "num_labels");

                  label_list = KL_UINT(infop,
                        "labelcl_info_s", "label_list");

                  fprintf(ofp, "  num_labels=%d, label_list=0x%lx\n\n",
                        num_labels, label_list);
                  for (i = 0; i < num_labels; i++) {
                        GET_BLOCK((label_list + (i *  LABEL_INFO_SZ)),
                              LABEL_INFO_SZ, labelp);

                        value = ADDR64(kl_kaddr(labelp,
                              "label_info_s", "name"));
                        if (value) {
                              GET_BLOCK(value,
                                    LABEL_LENGTH_MAX, label);
                        }
                        fprintf(ofp, "  name=0x%lx (%s)\n",
                              value, label);

                        value = ADDR64(kl_kaddr(labelp,
                              "label_info_s", "desc"));
                        fprintf(ofp, "      desc=0x%lx", value);

                        value = ADDR64(kl_kaddr(labelp,
                              "label_info_s", "info"));
                        fprintf(ofp, ", info=0x%lx\n", value);
                  }
            }
            fprintf(ofp, "\n");
      }
      return(0);
}

/*
 * print_vertex_dentry()
 */
int
print_vertex_dentry(kaddr_t vertex, void *vp, int flags, FILE *ofp)
{
      int i, mode, namelen, num_labels;
      char vname[128], label[LABEL_LENGTH_MAX];
      kaddr_t info, d_inode, label_list, link_name, nameaddr;
      void *infop, *labelp, *link_name_p, *d_name;
      uint64_t value;

      mode = dentry_mode(vp);
      d_name = (void *)(vp + kl_member_offset("dentry", "d_name"));
        namelen = KL_UINT(d_name, "qstr", "len");
      nameaddr = kl_kaddr(d_name, "qstr", "name");
      GET_BLOCK(nameaddr, namelen, vname);
        vname[namelen] = 0;

      fprintf(ofp, "0x%16lx  ", vertex);
      fprintf(ofp, "%20s", vname);
        print_value(ofp, "  ", 
            UINT64(KL_UINT(K_PTR(vp, "dentry", "d_count"),
                "atomic_t", "counter")), 6, UNSIGNED_FLG);
      fprintf(ofp, "  %07o", mode);
      info = kl_kaddr(vp, "dentry", "d_fsdata");
      print_value(ofp, "  ", ADDR64(info), 18, ADDR_FLG);
      fprintf(ofp, "\n");
      if (flags & C_FULL) {

            fprintf(ofp, "\n");
            if ((value = ADDR64(kl_kaddr(vp, "dentry", "d_parent")))) {
                  print_value(ofp, "parent=", value, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, "parent=(nil)");
            }
            if ((d_inode = ADDR64(kl_kaddr(vp, "dentry", "d_inode")))) {
                  print_value(ofp, ", inode=", d_inode, 18, ADDR_FLG);
            } else {
                  fprintf(ofp, ", inode=(nil)");
            }

            fprintf(ofp, "\n\n");
            if (IS_SPECIAL(mode)) {
                  fprintf(ofp, "SPECIAL FILE:\n");
            } else if (IS_DIR(mode)) {
                  fprintf(ofp, "DIRECTORY:\n\n");
            } else if (IS_LINK(mode)) {

                  fprintf(ofp, "LINK\n");
                  link_name_p = kl_alloc_block(4096, K_TEMP);
                  link_name = d_inode + 
                        (KL_PAGE_SIZE - (d_inode%KL_PAGE_SIZE));
                  GET_BLOCK(link_name, 4096, link_name_p);
                  fprintf(ofp, "  linkname=%s\n", (char *)link_name_p);
                  kl_free_block(link_name_p);
            } else if (IS_REG(mode)) {
                  fprintf(ofp, "REGULAR FILE\n");
            } else {
                  fprintf(ofp, "UNKNOWN MODE (%o)\n", mode);
            }
            fprintf(ofp, "\n");
            if (info) {
                  infop = kl_alloc_block(LABELCL_INFO_SZ, K_TEMP);
                  labelp = kl_alloc_block(LABEL_INFO_SZ, K_TEMP);
                  if (KL_ERROR) {
                        return(1);
                  }
                  GET_BLOCK(info, LABELCL_INFO_SZ, infop);
                  if (KL_ERROR) {
                        /* XXX -- print error */;
                        return(1);
                  } 

                  /* Check the magic number to ensure we have a
                   * valid info struct...
                   */
                  if (*(uint64_t*)infop != INFO_MAGIC) {
                        fprintf(ofp, "BAD info magic number "
                              "(0x%lx)\n", *(uint64_t*)infop);
                        return(1);
                  }

                  fprintf(ofp, "INFO:\n\n");

                  num_labels = KL_UINT(infop, 
                        "labelcl_info_s", "num_labels");

                  label_list = KL_UINT(infop, 
                        "labelcl_info_s", "label_list");

                  fprintf(ofp, "  num_labels=%d, label_list=0x%lx\n\n", 
                        num_labels, label_list);
                  for (i = 0; i < num_labels; i++) {
                        GET_BLOCK((label_list + (i *  LABEL_INFO_SZ)), 
                              LABEL_INFO_SZ, labelp);

                        value = ADDR64(kl_kaddr(labelp, 
                              "label_info_s", "name"));
                        if (value) {
                              GET_BLOCK(value, 
                                    LABEL_LENGTH_MAX, label);
                        }
                        fprintf(ofp, "  name=0x%lx (%s)\n", 
                              value, label);

                        value = ADDR64(kl_kaddr(labelp, 
                              "label_info_s", "desc"));
                        fprintf(ofp, "      desc=0x%lx", value); 

                        value = ADDR64(kl_kaddr(labelp, 
                              "label_info_s", "info"));
                        fprintf(ofp, ", info=0x%lx\n", value);
                  }
            }
            fprintf(ofp, "\n");
      }
      return(0);
}

/*
 * print_vertex()
 */
int
print_vertex(kaddr_t vertex, void *vp, int flags, FILE *ofp)
{
      return(print_vertex_dentry(vertex, vp, flags, ofp));
}

/*
 * print_pathnames()
 */
void
print_pathnames(command_t *cmd, path_t *path)
{
      int i;
      path_rec_t *p;
      path_chunk_t *pcp;

        pcp = path->pchunk;
        do {
                for (i = 0; i <= pcp->current; i++) {
                        p = pcp->path[i];
                        do {
                                fprintf(cmd->ofp, "/%s", p->name);
                                p = p->next;
                        } while (p != pcp->path[i]);

                        if (cmd->flags & C_FULL) {
                  }
                        fprintf(cmd->ofp, "\n");
                }
                pcp = pcp->next;
        } while (pcp != path->pchunk);
}

Generated by  Doxygen 1.6.0   Back to index