patch-2.2.0-pre4 linux/scripts/ksymoops.cc

Next file: linux/scripts/tkcond.c
Previous file: linux/scripts/ksymoops-0.6/symbol.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.0-pre3/linux/scripts/ksymoops.cc linux/scripts/ksymoops.cc
@@ -1,411 +0,0 @@
-// ksymoops.cc v1.7 -- A simple filter to resolve symbols in Linux Oops-logs
-// Copyright (C) 1995 Greg McGary <gkm@magilla.cichlid.com>
-// compile like so: g++ -o ksymoops ksymoops.cc -liostream
-
-// Update to binutils 2.8 and handling of header text on oops lines by
-// Keith Owens <kaos@ocs.com.au>
-
-//////////////////////////////////////////////////////////////////////////////
-
-// 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, or (at your option)
-// any later version.
-
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with this program; see the file COPYING.  If not, write to the
-// Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-// This is a simple filter to resolve EIP and call-trace symbols from
-// a Linux kernel "Oops" log.  Supply the symbol-map file name as a
-// command-line argument, and redirect the oops-log into stdin.  Out
-// will come the EIP and call-trace in symbolic form.
-
-// Changed by Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
-// adapted to Linux/m68k
-
-//////////////////////////////////////////////////////////////////////////////
-
-// BUGS:
-// * Only resolves operands of jump and call instructions.
-
-#include <fstream.h>
-#include <strstream.h>
-#include <iomanip.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <a.out.h>
-
-inline int strnequ(char const* x, char const* y, size_t n) { return (strncmp(x, y, n) == 0); }
-
-const int code_size = 20;
-
-//////////////////////////////////////////////////////////////////////////////
-
-class KSym
-{
-    friend class NameList;
-
-  private:
-    unsigned long address_;
-    char* name_;
-    long offset_;
-    long extent_;
-
-  private:
-    istream& scan(istream&);
-    ostream& print(ostream&) const;
-    void set_extent(KSym const& next_ksym) { extent_ = next_ksym.address_ - address_; }
-
-  public:
-    friend istream& operator >> (istream& is, KSym& k) { return k.scan(is); }
-    friend ostream& operator << (ostream& os, const KSym& k) { return k.print(os); }
-};
-
-istream&
-KSym::scan(istream& is)
-{
-    is >> ::hex >> address_;
-    char type;
-    is >> type;
-    char name[128];
-    is >> name;
-    name_ = new char [strlen(name)+1];
-    strcpy(name_, name);
-    offset_ = 0;
-    return is;
-}
-
-ostream&
-KSym::print(ostream& os) const
-{
-    os << ::hex << address_ + offset_ << ' ' << '<' << name_;
-    if (offset_)
-	os << '+' << ::hex << offset_ << '/' << ::hex << extent_;
-    return os << '>';
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-class NameList
-{
-  private:
-    // Caution: Fixed Allocation!
-    // This should suffice for awhile since 1.1.86 has only 2482 symbols.
-    KSym ksyms_0_[8000];
-    int cardinality_;
-
-  public:
-    NameList() : cardinality_(0) { }
-    
-  private:
-    istream& scan(istream&);
-
-  public:
-    int valid() { return (cardinality_ > 0); }
-	
-    KSym* find(unsigned long address);
-    void decode(unsigned char* code, long eip_addr);
-    
-  public:
-    friend istream& operator >> (istream& is, NameList& n) { return n.scan(is); }
-};
-
-KSym*
-NameList::find(unsigned long address)
-{
-    if (!valid())
-	return 0;
-    KSym* start = ksyms_0_;
-    KSym* end = &ksyms_0_[cardinality_ - 1];
-    if (address < start->address_ || address >= end->address_)
-	return 0;
-
-    KSym* mid;
-    while (start <= end) {
-	mid = &start[(end - start) / 2];
-	if (mid->address_ < address)
-	    start = mid + 1;
-	else if (mid->address_ > address)
-	    end = mid - 1;
-	else
-	    return mid;
-    }
-    while (mid->address_ > address)
-	--mid;
-    mid->offset_ = address - mid->address_;
-    if (mid->offset_ > mid->extent_)
-	clog << "Oops! " << *mid << endl;
-    return mid;
-}
-
-void
-NameList::decode(unsigned char* code, long eip_addr)
-{
-    /* This is a hack to avoid using gcc.  We create an object file by
-       concatenating objfile_head, the twenty bytes of code, and
-       objfile_tail.  */
-    static struct exec objfile_head = {
-	OMAGIC, code_size + 4, 0, 0, sizeof (struct nlist) * 3, 0, 0, 0
-    };
-    static struct {
-	unsigned char tail[4];
-	struct nlist syms[3];
-	unsigned long strsize;
-	char strings[42];
-    } objfile_tail = {
-#ifdef i386
-	{ 0x00, 0x90, 0x90, 0x90 },
-#endif
-#ifdef mc68000
-	{ 0x00, 0x00, 0x00, 0x00 },
-#endif
-	{ { (char *) 4, N_TEXT, 0, 0, 0 },
-	  { (char *) 19, N_TEXT, 0, 0, 0 },
-	  { (char *) 37, N_TEXT | N_EXT, 0, 0, 0 } },
-	42,
-	"gcc2_compiled.\0___gnu_compiled_c\0_EIP\0"
-    };
-    char const* objdump_command = "objdump -d oops_decode.o";
-    char const* objfile_name = &objdump_command[11];
-    ofstream objfile_stream(objfile_name);
-
-    objfile_stream.write((char *) &objfile_head, sizeof(objfile_head));
-    objfile_stream.write(code, code_size);
-    objfile_stream.write((char *) &objfile_tail, sizeof(objfile_tail));
-    objfile_stream.close();
-    
-    FILE* objdump_FILE = popen(objdump_command, "r");
-    if (objdump_FILE == 0) {
-	clog << "Sorry, without " << objdump_command << ", I can't disassemble the `Code' section." << endl;
-	return;
-    }
-    
-    char buf[1024];
-    int lines = 0;
-    int eip_seen = 0;
-    long offset;
-    while (fgets(buf, sizeof(buf), objdump_FILE)) {
-	if (strlen(buf) < 14)
-	    continue;
-	if (eip_seen && buf[4] == ':') {
-	    // assume objdump from binutils 2.8..., reformat to old style
-	    offset = strtol(buf, 0, 16);
-	    char newbuf[sizeof(buf)];
-	    memset(newbuf, '\0', sizeof(newbuf));
-	    ostrstream ost(newbuf, sizeof(newbuf));
-	    ost.width(8);
-	    ost << hex << offset;
-	    ost << " <_EIP+" << hex << offset << ">: " << &buf[6] << ends;
-	    strcpy(buf, newbuf);
-	}
-	if (!strnequ(&buf[9], "<_EIP", 5))
-	    continue;
-	eip_seen = 1;
-	if (strstr(buf, " is out of bounds"))
-	    break;
-	lines++;
-	cout << "Code: ";
-	if (!valid()) {
-	    cout << buf;
-	    continue;
-	}
-	offset = strtol(buf, 0, 16);
-	char* bp_0 = strchr(buf, '>');
-	KSym* ksym = find(eip_addr + offset);
-	if (bp_0)
-	    bp_0 += 2;
-	else
-	    bp_0 = strchr(buf, ':');
-	if (ksym)
-	    cout << *ksym << ' ';
-	char *bp_1 = strstr(bp_0, "\t");        // objdump from binutils 2.8...
-	if (bp_1)
-	    ++bp_1;
-	else
-	    bp_1 = bp_0;
-	char *bp = bp_1;
-	while (!isspace(*bp))
-	    bp++;
-	while (isspace(*bp))
-	    bp++;
-	if (!isxdigit(*bp)) {
-	    cout << bp_0;
-#ifdef i386
-	} else if (*bp_1 == 'j' || strnequ(bp_1, "call", 4)) { // a jump or call insn
-	    long rel_addr = strtol(bp, 0, 16);
-	    ksym = find(eip_addr + rel_addr);
-	    if (ksym) {
-		*bp++ = '\0';
-		cout << bp_0 << *ksym << endl;
-	    } else
-		cout << bp_0;
-#endif
-#ifdef mc68000
-	} else if ((bp_1[0] == 'b' && bp_1[4] == ' ' && strchr("swl", bp_1[3]))
-		   || (bp_1[0] == 'd' && bp_1[1] == 'b')) {
-	    // a branch or decr-and-branch insn
-	    if (bp_1[0] == 'd') // skip register
-		while (*bp && *bp++ != ',');
-	    long rel_addr = strtoul(bp, 0, 16);
-	    ksym = find(eip_addr + rel_addr);
-	    if (ksym) {
-		*bp++ = '\0';
-		cout << bp_0 << *ksym << endl;
-	    } else
-	      cout << bp_0;
-#endif
-	} else {
-	    cout << bp_0;
-	}
-    }
-    if (!lines)
-	clog << "Sorry, your " << objdump_command << " can't disassemble--you must upgrade your binutils." << endl;
-    pclose(objdump_FILE);
-    unlink(objfile_name);
-}
-
-istream&
-NameList::scan(istream& is)
-{
-    KSym* ksyms = ksyms_0_;
-    int cardinality = 0;
-    while (!is.eof()) {
-	is >> *ksyms;
-	if (cardinality++ > 0)
-	    ksyms[-1].set_extent(*ksyms);
-	ksyms++;
-    }
-    cardinality_ = --cardinality;
-    return is;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-char const* program_name;
-
-void
-usage()
-{
-    clog << "Usage: " << program_name << " [ System.map ] < oops-log" << endl;
-    exit(1);
-}
-
-int
-main(int argc, char** argv)
-{
-    char c;
-    char *oops_column = NULL;
-    program_name = (argc--, *argv++);
-
-    NameList names;
-    if (argc > 1)
-	usage();
-    else if (argc == 1) {
-	char const* map_file_name = (argc--, *argv++);
-	ifstream map(map_file_name);
-	if (map.bad())
-	    clog << program_name << ": Can't open `" << map_file_name << "'" << endl;
-	else {
-	    map >> names;
-	    cout << "Using `" << map_file_name << "' to map addresses to symbols." << endl;
-	}
-    }
-    if (!names.valid())
-	cout << "No symbol map.  I'll only show you disassembled code." << endl;
-    cout << endl;
-
-    char buffer[1024];
-    while (1) {
-	long eip_addr;
-	cin.get(buffer, sizeof(buffer));
-	if (cin.eof())
-	    break;
-	cin.get(c);	/* swallow newline */
-#ifdef i386
-	if (strstr(buffer, "EIP:") && names.valid()) {
-	    oops_column =  strstr(buffer, "EIP:");
-	    if (sscanf(oops_column+13, "[<%x>]", &eip_addr) != 1) {
-	    	cout << "Cannot read eip address from EIP: line.  Is this a valid oops file?" << endl;
-		exit(1);
-	    }
-	    cout << ">>EIP: ";
-	    KSym* ksym = names.find(eip_addr);
-	    if (ksym)
-		cout << *ksym << endl;
-	    else
-		cout << ::hex << eip_addr << " cannot be resolved" << endl;
-	}
-#endif
-#ifdef mc68000
-	if (strstr(buffer, "PC:") && names.valid()) {
-	    oops_column =  strstr(buffer, "PC:");
-	    if (sscanf(oops_column+4, "[<%x>]", &eip_addr) != 1) {
-	    	cout << "Cannot read pc address from PC: line.  Is this a valid oops file?" << endl;
-		exit(1);
-	    }
-	    cout << ">>PC: ";
-	    KSym* ksym = names.find(eip_addr);
-	    if (ksym)
-		cout << *ksym << endl;
-	    else
-		cout << ::hex << eip_addr << " cannot be resolved" << endl;
-	}
-#endif
-	else if (oops_column && strstr(oops_column, "[<") && names.valid()) {
-	    unsigned long address;
-	    while (strstr(oops_column, "[<")) {
-		char *p = oops_column;
-		while (1) {
-		    while (*p && *p++ != '[')
-			;
-		    if (sscanf(p, "<%x>]", &address) != 1)
-			break;
-		    cout << "Trace: ";
-		    KSym* ksym = names.find(address);
-		    if (ksym)
-			cout << *ksym;
-		    else
-			cout << ::hex << address;
-		    cout << endl;
-		}
-		cin.get(buffer, sizeof(buffer));
-		if (cin.eof())
-		    break;
-		cin.get(c);	/* swallow newline */
-	    }
-	}
-	if (oops_column && strnequ(oops_column, "Code:", 5)) {
-	    unsigned char code[code_size];
-	    unsigned char* cp = code;
-	    unsigned char* end = &code[code_size];
-	    char *p = oops_column + 5;
-	    int c;
-	    memset(code, '\0', sizeof(code));
-	    while (*p && cp < end) {
-	    	while (*p == ' ')
-		    ++p;
-		if (sscanf(p, "%x", &c) != 1)
-		    break;
-#ifdef mc68000
-		*cp++ = c >> 8;
-#endif
-		*cp++ = c;
-	    	while (*p && *p++ != ' ')
-		    ;
-	    }
-	    names.decode(code, eip_addr);
-	}
-    }
-    cout << flush;
-
-    return 0;
-}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov