root/scripts/ksymoops.cc

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. strequ
  2. set_extent
  3. find
  4. usage
  5. main

   1 /* ksymoops.c -- simple Linux Oops-log symbol resolver
   2    Copyright (C) 1995 Greg McGary
   3   
   4    This program is free software; you can redistribute it and/or modify
   5    it under the terms of the GNU General Public License as published by
   6    the Free Software Foundation; either version 2, or (at your option)
   7    any later version.
   8   
   9    This program is distributed in the hope that it will be useful,
  10    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12    GNU General Public License for more details.
  13   
  14    You should have received a copy of the GNU General Public License
  15    along with this program; see the file COPYING.  If not, write to the
  16    Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17 */
  18 
  19 /* This is a simple filter to resolve EIP and call-trace symbols from
  20    a Linux kernel "Oops" log.  Supply the symbol-map file name as a
  21    command-line argument, and redirect the oops-log into stdin.
  22    Out will come the EIP and call-trace in symbolic form.  */
  23 
  24 #include <fstream.h>
  25 #include <string.h>
  26 #include <stdlib.h>
  27 
  28 inline int strequ(char const* x, char const* y) { return (::strcmp(x, y) == 0); }
     /* [previous][next][first][last][top][bottom][index][help] */
  29 
  30 //////////////////////////////////////////////////////////////////////////////
  31 
  32 class KSym
  33 {
  34     friend class NameList;
  35 
  36   private:
  37     long address_;
  38     char type_;
  39     char* name_;
  40     long offset_;
  41     long extent_;
  42 
  43   public:
  44     void set_extent(KSym const& next_ksym) { extent_ = next_ksym.address_ - address_; }
     /* [previous][next][first][last][top][bottom][index][help] */
  45     friend istream& operator >> (istream&, KSym&);
  46     friend ostream& operator << (ostream&, const KSym&);
  47 };
  48 
  49 istream&
  50 operator >> (istream& is, KSym& n)
  51 {
  52     is >> hex >> n.address_;
  53     is >> n.type_;
  54     char name[128];
  55     is >> name;
  56     n.name_ = new char [strlen(name)+1];
  57     strcpy(n.name_, name);
  58     n.offset_ = 0;
  59     return is;
  60 }
  61 
  62 ostream&
  63 operator << (ostream& os, const KSym& n)
  64 {
  65     os << hex << n.address_ + n.offset_ << ' ' << n.type_ << ' ' << n.name_;
  66     if (n.offset_)
  67         os << '+' << hex << n.offset_ << '/' << hex << n.extent_;
  68     return os;
  69 }
  70 
  71 //////////////////////////////////////////////////////////////////////////////
  72 
  73 class NameList
  74 {
  75   private:
  76     // Caution: Fixed Allocation!
  77     // This should suffice for awhile since 1.1.86 has only 2482 symbols.
  78     KSym ksyms_0_[4096];
  79     int cardinality_;
  80 
  81   public:
  82     NameList() : cardinality_(0) { }
  83     
  84   public:
  85     KSym* find(long address);
  86     
  87   public:
  88     friend istream& operator >> (istream&, NameList&);
  89 };
  90 
  91 KSym*
  92 NameList::find(long address)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94     KSym* start = ksyms_0_;
  95     KSym* end = &ksyms_0_[cardinality_];
  96     KSym* mid;
  97 
  98     while (start <= end) {
  99         mid = &start[(end - start) / 2];
 100         if (mid->address_ < address)
 101             start = mid + 1;
 102         else if (mid->address_ > address)
 103             end = mid - 1;
 104         else
 105             return mid;
 106     }
 107     while (mid->address_ > address)
 108         --mid;
 109     mid->offset_ = address - mid->address_;
 110     if (mid->offset_ > mid->extent_)
 111         clog << "Oops! " << *mid << endl;
 112     return mid;
 113 }
 114 
 115 istream&
 116 operator >> (istream& is, NameList& n)
 117 {
 118     KSym* ksyms = n.ksyms_0_;
 119     int cardinality = 0;
 120     while (!is.eof()) {
 121         is >> *ksyms;
 122         ksyms[-1].set_extent(*ksyms);
 123         ksyms++;
 124         cardinality++;
 125     }
 126     n.cardinality_ = --cardinality;
 127     return is;
 128 }
 129 
 130 //////////////////////////////////////////////////////////////////////////////
 131 
 132 char const* program_name;
 133 
 134 void
 135 usage()
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137     clog << "Usage: " << program_name << " system-map-file < oops-log" << endl;
 138     exit(1);
 139 }
 140 
 141 int
 142 main(int argc, char** argv)
     /* [previous][next][first][last][top][bottom][index][help] */
 143 {
 144     program_name = (argc--, *argv++);
 145     if (argc != 1)
 146         usage();
 147 
 148     char const* map_file_name = (argc--, *argv++);
 149     ifstream map(map_file_name);
 150     if (map.bad()) {
 151         clog << program_name << ": Can't open `" << map_file_name << "'" << endl;
 152         return 1;
 153     }
 154     
 155     NameList names;
 156     map >> names;
 157 
 158     char buffer[1024];
 159     while (!cin.eof())
 160     {
 161         long address;
 162         cin >> buffer;
 163         if (strequ(buffer, "EIP:")) {
 164             cin >> hex >> address;
 165             cin >> buffer[0];
 166             cin >> hex >> address;
 167             KSym* ksym = names.find(address);
 168             if (ksym)
 169                 cout << "EIP: " << *ksym << endl;
 170         } else if (strequ(buffer, "Trace:")) {
 171             while ((cin >> address) && address > 0xc) {
 172                 KSym* ksym = names.find(address);
 173                 if (ksym)
 174                     cout << "Trace: " << *ksym << endl;
 175             }
 176             cout << endl;
 177         }
 178     }
 179     cout << flush;
 180 
 181     return 0;
 182 }

/* [previous][next][first][last][top][bottom][index][help] */