summaryrefslogtreecommitdiffstats
path: root/scripts/ksymoops.cc
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/ksymoops.cc')
-rw-r--r--scripts/ksymoops.cc82
1 files changed, 51 insertions, 31 deletions
diff --git a/scripts/ksymoops.cc b/scripts/ksymoops.cc
index d1edca9c1..b0aa76c82 100644
--- a/scripts/ksymoops.cc
+++ b/scripts/ksymoops.cc
@@ -2,6 +2,9 @@
// 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
@@ -26,8 +29,6 @@
//////////////////////////////////////////////////////////////////////////////
// BUGS:
-// * Doesn't deal with line-prefixes prepended by syslog--strip
-// these off first, before submitting to ksymoops.
// * Only resolves operands of jump and call instructions.
#include <fstream.h>
@@ -39,7 +40,6 @@
#include <unistd.h>
#include <ctype.h>
-inline int strequ(char const* x, char const* y) { return (::strcmp(x, y) == 0); }
inline int strnequ(char const* x, char const* y, size_t n) { return (::strncmp(x, y, n) == 0); }
const int code_size = 20;
@@ -188,6 +188,8 @@ NameList::decode(unsigned char* code, long eip_addr)
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);
@@ -279,6 +281,7 @@ int
main(int argc, char** argv)
{
char c;
+ char *oops_column = NULL;
program_name = (argc--, *argv++);
NameList names;
@@ -299,46 +302,63 @@ main(int argc, char** argv)
cout << endl;
char buffer[1024];
- while (!cin.eof())
- {
+ while (1) {
long eip_addr;
- cin >> buffer;
- if (strequ(buffer, "EIP:") && names.valid()) {
- cin >> ::hex >> eip_addr;
- cin >> c >> c >> c;
- cin >> ::hex >> eip_addr;
- cin >> c >> c >> buffer;
- if (!strequ(buffer, "EFLAGS:")) {
- clog << "Please strip the line-prefixes and rerun " << program_name << endl;
+ cin.get(buffer, sizeof(buffer));
+ if (cin.eof())
+ break;
+ cin.get(c); /* swallow newline */
+ 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 << ">>EIP: " << *ksym << endl;
- } else if (strequ(buffer, "Trace:") && names.valid()) {
+ cout << *ksym << endl;
+ else
+ cout << ::hex << eip_addr << " cannot be resolved" << endl;
+ }
+ else if (oops_column && strstr(oops_column, "[<") && names.valid()) {
unsigned long address;
- while ((cin >> buffer) &&
- (sscanf(buffer, " [<%x>]", &address) == 1) &&
- address > 0xc) {
- cout << "Trace: ";
- KSym* ksym = names.find(address);
- if (ksym)
- cout << *ksym;
- else
- cout << ::hex << address;
- cout << endl;
+ 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 */
}
- cout << endl;
}
- if (strequ(buffer, "ode:") || strequ(buffer, "Code:")) {
- // The 'C' might have been consumed as a hex number
+ if (oops_column && strnequ(oops_column, "Code:", 5)) {
unsigned char code[code_size];
unsigned char* cp = code;
unsigned char* end = &code[code_size];
- while (cp < end) {
- int c;
- cin >> ::hex >> c;
+ 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;
*cp++ = c;
+ while (*p && *p++ != ' ')
+ ;
}
names.decode(code, eip_addr);
}