From 68a96e5326171a0ebdfc6c4a7a165449d45356a0 Mon Sep 17 00:00:00 2001 From: "K. Richard Pixley" Date: Mon, 8 Apr 1991 15:59:18 +0000 Subject: [PATCH] Initial revision --- gas/config/cplus-dem.c | 925 +++++++++++++++++ gas/config/ranlib.h | 17 + gas/config/signame.h | 41 + gas/config/stab.h | 16 + gas/objdump.c | 2232 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 3231 insertions(+) create mode 100644 gas/config/cplus-dem.c create mode 100755 gas/config/ranlib.h create mode 100755 gas/config/signame.h create mode 100755 gas/config/stab.h create mode 100755 gas/objdump.c diff --git a/gas/config/cplus-dem.c b/gas/config/cplus-dem.c new file mode 100644 index 0000000000..0ea6186656 --- /dev/null +++ b/gas/config/cplus-dem.c @@ -0,0 +1,925 @@ +/* Demangler for GNU C++ + Copyright (C) 1989 Free Software Foundation, Inc. + written by James Clark (jjc@jclark.uucp) + + 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 1, 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This is for g++ 1.36.1 (November 6 version). It will probably + require changes for any other version. */ + +/* This file exports one function + + char *cplus_demangle (const char *name) + + If `name' is a mangled function name produced by g++, then + a pointer to a malloced string giving a C++ representation + of the name will be returned; otherwise NULL will be returned. + It is the caller's responsibility to free the string which + is returned. + + For example, + + cplus_demangle ("_foo__1Ai") + + returns + + "A::foo(int)" + + This file imports xmalloc and xrealloc, which are like malloc and + realloc except that they generate a fatal error if there is no + available memory. */ + +/* #define nounderscore 1 /* define this is names don't start with _ */ + +#include +#include +#include + +#if !defined(sequent) && !defined(NeXT) +#include +#else +#define memcpy(s1, s2, n) strncpy(s1, s2, n) +#define memcmp(s1, s2, n) strncmp(s1, s2, n) +#define strchr(s, c) index(s, c) +#endif + +#ifndef __STDC__ +#define const +#endif + +#ifdef __STDC__ +extern char *cplus_demangle (const char *type); +#else +extern char *cplus_demangle (); +#endif + +#ifdef __STDC__ +extern char *xmalloc (int); +extern char *xrealloc (char *, int); +#else +extern char *xmalloc (); +extern char *xrealloc (); +#endif + +static char **typevec = 0; +static int ntypes = 0; +static int typevec_size = 0; + +static struct { + const char *in; + const char *out; +} optable[] = { + "new", " new", + "delete", " delete", + "ne", "!=", + "eq", "==", + "ge", ">=", + "gt", ">", + "le", "<=", + "lt", "<", + "plus", "+", + "minus", "-", + "mult", "*", + "negate", "-", + "trunc_mod", "%", + "trunc_div", "/", + "truth_andif", "&&", + "truth_orif", "||", + "postincrement", "++", + "postdecrement", "--", + "bit_ior", "|", + "bit_xor", "^", + "bit_and", "&", + "bit_not", "~", + "call", "()", + "cond", "?:", + "alshift", "<<", + "arshift", ">>", + "component", "->", + "nop", "", /* for operator= */ +}; + +/* Beware: these aren't '\0' terminated. */ + +typedef struct { + char *b; /* pointer to start of string */ + char *p; /* pointer after last character */ + char *e; /* pointer after end of allocated space */ +} string; + +#ifdef __STDC__ +static void string_need (string *s, int n); +static void string_delete (string *s); +static void string_init (string *s); +static void string_clear (string *s); +static int string_empty (string *s); +static void string_append (string *p, const char *s); +static void string_appends (string *p, string *s); +static void string_appendn (string *p, const char *s, int n); +static void string_prepend (string *p, const char *s); +#if 0 +static void string_prepends (string *p, string *s); +#endif +static void string_prependn (string *p, const char *s, int n); +static int get_count (const char **type, int *count); +static int do_args (const char **type, string *decl); +static int do_type (const char **type, string *result); +static int do_arg (const char **type, string *result); +static int do_args (const char **type, string *decl); +static void munge_function_name (string *name); +#else +static void string_need (); +static void string_delete (); +static void string_init (); +static void string_clear (); +static int string_empty (); +static void string_append (); +static void string_appends (); +static void string_appendn (); +static void string_prepend (); +static void string_prepends (); +static void string_prependn (); +static int get_count (); +static int do_args (); +static int do_type (); +static int do_arg (); +static int do_args (); +static void munge_function_name (); +#endif + +char * +cplus_demangle (type) + const char *type; +{ + string decl; + int n; + int success = 0; + int constructor = 0; + int const_flag = 0; + int i; + const char *p; + + if (type == NULL || *type == '\0') + return NULL; +#ifndef nounderscore + if (*type++ != '_') + return NULL; +#endif + p = type; + while (*p != '\0' && !(*p == '_' && p[1] == '_')) + p++; + if (*p == '\0') + { + /* destructor */ + if (type[0] == '_' && type[1] == '$' && type[2] == '_') + { + int n = (strlen (type) - 3)*2 + 3 + 2 + 1; + char *tem = (char *) xmalloc (n); + strcpy (tem, type + 3); + strcat (tem, "::~"); + strcat (tem, type + 3); + strcat (tem, "()"); + return tem; + } + /* static data member */ + if (*type != '_' && (p = strchr (type, '$')) != '\0') + { + int n = strlen (type) + 2; + char *tem = (char *) xmalloc (n); + memcpy (tem, type, p - type); + strcpy (tem + (p - type), "::"); + strcpy (tem + (p - type) + 2, p + 1); + return tem; + } + return NULL; + } + + string_init (&decl); + + if (p == type) + { + if (!isdigit (p[2])) + { + string_delete (&decl); + return NULL; + } + constructor = 1; + } + else + { + string_appendn (&decl, type, p - type); + munge_function_name (&decl); + } + p += 2; + + switch (*p) + { + case 'C': + /* a const member function */ + if (!isdigit (p[1])) + { + string_delete (&decl); + return NULL; + } + p += 1; + const_flag = 1; + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (strlen (p) < n) + { + string_delete (&decl); + return NULL; + } + if (constructor) + { + string_appendn (&decl, p, n); + string_append (&decl, "::"); + string_appendn (&decl, p, n); + } + else + { + string_prepend (&decl, "::"); + string_prependn (&decl, p, n); + } + p += n; + success = do_args (&p, &decl); + if (const_flag) + string_append (&decl, " const"); + break; + case 'F': + p += 1; + success = do_args (&p, &decl); + break; + } + + for (i = 0; i < ntypes; i++) + if (typevec[i] != NULL) + free (typevec[i]); + ntypes = 0; + if (typevec != NULL) + { + free ((char *)typevec); + typevec = NULL; + typevec_size = 0; + } + + if (success) + { + string_appendn (&decl, "", 1); + return decl.b; + } + else + { + string_delete (&decl); + return NULL; + } +} + +static int +get_count (type, count) + const char **type; + int *count; +{ + if (!isdigit (**type)) + return 0; + *count = **type - '0'; + *type += 1; + /* see flush_repeats in cplus-method.c */ + if (isdigit (**type)) + { + const char *p = *type; + int n = *count; + do + { + n *= 10; + n += *p - '0'; + p += 1; + } + while (isdigit (*p)); + if (*p == '_') + { + *type = p + 1; + *count = n; + } + } + return 1; +} + +/* result will be initialised here; it will be freed on failure */ + +static int +do_type (type, result) + const char **type; + string *result; +{ + int n; + int done; + int non_empty; + int success; + string decl; + const char *remembered_type; + + string_init (&decl); + string_init (result); + + done = 0; + success = 1; + while (success && !done) + { + int member; + switch (**type) + { + case 'P': + *type += 1; + string_prepend (&decl, "*"); + break; + + case 'R': + *type += 1; + string_prepend (&decl, "&"); + break; + + case 'T': + *type += 1; + if (!get_count (type, &n) || n >= ntypes) + success = 0; + else + { + remembered_type = typevec[n]; + type = &remembered_type; + } + break; + + case 'F': + *type += 1; + if (!string_empty (&decl) && decl.b[0] == '*') + { + string_prepend (&decl, "("); + string_append (&decl, ")"); + } + if (!do_args (type, &decl) || **type != '_') + success = 0; + else + *type += 1; + break; + + case 'M': + case 'O': + { + int constp = 0; + int volatilep = 0; + + member = **type == 'M'; + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + string_append (&decl, ")"); + string_prepend (&decl, "::"); + string_prependn (&decl, *type, n); + string_prepend (&decl, "("); + *type += n; + if (member) + { + if (**type == 'C') + { + *type += 1; + constp = 1; + } + if (**type == 'V') + { + *type += 1; + volatilep = 1; + } + if (*(*type)++ != 'F') + { + success = 0; + break; + } + } + if ((member && !do_args (type, &decl)) || **type != '_') + { + success = 0; + break; + } + *type += 1; + if (constp) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "const"); + } + if (volatilep) + { + if (non_empty) + string_append (&decl, " "); + else + non_empty = 1; + string_append (&decl, "volatilep"); + } + break; + } + + case 'C': + if ((*type)[1] == 'P') + { + *type += 1; + if (!string_empty (&decl)) + string_prepend (&decl, " "); + string_prepend (&decl, "const"); + break; + } + + /* fall through */ + default: + done = 1; + break; + } + } + + done = 0; + non_empty = 0; + while (success && !done) + { + switch (**type) + { + case 'C': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "const"); + break; + case 'U': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "unsigned"); + break; + case 'V': + *type += 1; + if (non_empty) + string_append (result, " "); + else + non_empty = 1; + string_append (result, "volatile"); + break; + default: + done = 1; + break; + } + } + + if (success) + switch (**type) + { + case '\0': + case '_': + break; + case 'v': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "void"); + break; + case 'l': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long"); + break; + case 'i': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "int"); + break; + case 's': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "short"); + break; + case 'c': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "char"); + break; + case 'r': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "long double"); + break; + case 'd': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "double"); + break; + case 'f': + *type += 1; + if (non_empty) + string_append (result, " "); + string_append (result, "float"); + break; + case 'G': + *type += 1; + if (!isdigit (**type)) + { + success = 0; + break; + } + /* fall through */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + n = 0; + do + { + n *= 10; + n += **type - '0'; + *type += 1; + } + while (isdigit (**type)); + if (strlen (*type) < n) + { + success = 0; + break; + } + if (non_empty) + string_append (result, " "); + string_appendn (result, *type, n); + *type += n; + break; + default: + success = 0; + break; + } + + if (success) + { + if (!string_empty (&decl)) + { + string_append (result, " "); + string_appends (result, &decl); + } + string_delete (&decl); + return 1; + } + else + { + string_delete (&decl); + string_delete (result); + return 0; + } +} + +/* `result' will be initialised in do_type; it will be freed on failure */ + +static int +do_arg (type, result) + const char **type; + string *result; +{ + char *tem; + int len; + const char *start; + const char *end; + + start = *type; + if (!do_type (type, result)) + return 0; + end = *type; + if (ntypes >= typevec_size) + { + if (typevec_size == 0) + { + typevec_size = 3; + typevec = (char **) xmalloc (sizeof (char*)*typevec_size); + } + else + { + typevec_size *= 2; + typevec = (char **) xrealloc ((char *)typevec, sizeof (char*)*typevec_size); + } + } + len = end - start; + tem = (char *) xmalloc (len + 1); + memcpy (tem, start, len); + tem[len] = '\0'; + typevec[ntypes++] = tem; + return 1; +} + +/* `decl' must be already initialised, usually non-empty; + it won't be freed on failure */ + +static int +do_args (type, decl) + const char **type; + string *decl; +{ + string arg; + int need_comma = 0; + + string_append (decl, "("); + + while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v') + { + if (**type == 'N') + { + int r; + int t; + *type += 1; + if (!get_count (type, &r) || !get_count (type, &t) || t >= ntypes) + return 0; + while (--r >= 0) + { + const char *tem = typevec[t]; + if (need_comma) + string_append (decl, ", "); + if (!do_arg (&tem, &arg)) + return 0; + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } + } + else + { + if (need_comma) + string_append (decl, ", "); + if (!do_arg (type, &arg)) + return 0; + string_appends (decl, &arg); + string_delete (&arg); + need_comma = 1; + } + } + + if (**type == 'v') + *type += 1; + else if (**type == 'e') + { + *type += 1; + if (need_comma) + string_append (decl, ","); + string_append (decl, "..."); + } + + string_append (decl, ")"); + return 1; +} + +static void +munge_function_name (name) + string *name; +{ + if (!string_empty (name) && name->p - name->b >= 3 + && name->b[0] == 'o' && name->b[1] == 'p' && name->b[2] == '$') + { + int i; + /* see if it's an assignment expression */ + if (name->p - name->b >= 10 /* op$assign_ */ + && memcmp (name->b + 3, "assign_", 7) == 0) + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 10; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 10, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + string_append (name, "="); + return; + } + } + } + else + { + for (i = 0; i < sizeof (optable)/sizeof (optable[0]); i++) + { + int len = name->p - name->b - 3; + if (strlen (optable[i].in) == len + && memcmp (optable[i].in, name->b + 3, len) == 0) + { + string_clear (name); + string_append (name, "operator"); + string_append (name, optable[i].out); + return; + } + } + } + return; + } + else if (!string_empty (name) && name->p - name->b >= 5 + && memcmp (name->b, "type$", 5) == 0) + { + /* type conversion operator */ + string type; + const char *tem = name->b + 5; + if (do_type (&tem, &type)) + { + string_clear (name); + string_append (name, "operator "); + string_appends (name, &type); + string_delete (&type); + return; + } + } +} + +/* a mini string-handling package */ + +static void +string_need (s, n) + string *s; + int n; +{ + if (s->b == NULL) + { + if (n < 32) + n = 32; + s->p = s->b = (char *) xmalloc (n); + s->e = s->b + n; + } + else if (s->e - s->p < n) + { + int tem = s->p - s->b; + n += tem; + n *= 2; + s->b = (char *) xrealloc (s->b, n); + s->p = s->b + tem; + s->e = s->b + n; + } +} + +static void +string_delete (s) + string *s; +{ + if (s->b != NULL) + { + free (s->b); + s->b = s->e = s->p = NULL; + } +} + +static void +string_init (s) + string *s; +{ + s->b = s->p = s->e = NULL; +} + +static void +string_clear (s) + string *s; +{ + s->p = s->b; +} + +static int +string_empty (s) + string *s; +{ + return s->b == s->p; +} + +static void +string_append (p, s) + string *p; + const char *s; +{ + int n; + if (s == NULL || *s == '\0') + return; + n = strlen (s); + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; +} + +static void +string_appends (p, s) + string *p, *s; +{ + int n; + if (s->b == s->p) + return; + n = s->p - s->b; + string_need (p, n); + memcpy (p->p, s->b, n); + p->p += n; +} + +static void +string_appendn (p, s, n) + string *p; + const char *s; + int n; +{ + if (n == 0) + return; + string_need (p, n); + memcpy (p->p, s, n); + p->p += n; +} + +static void +string_prepend (p, s) + string *p; + const char *s; +{ + if (s == NULL || *s == '\0') + return; + string_prependn (p, s, strlen (s)); +} + +#if 0 +static void +string_prepends (p, s) + string *p, *s; +{ + if (s->b == s->p) + return; + string_prependn (p, s->b, s->p - s->b); +} +#endif + +static void +string_prependn (p, s, n) + string *p; + const char *s; + int n; +{ + char *q; + + if (n == 0) + return; + string_need (p, n); + for (q = p->p - 1; q >= p->b; q--) + q[n] = q[0]; + memcpy (p->b, s, n); + p->p += n; +} diff --git a/gas/config/ranlib.h b/gas/config/ranlib.h new file mode 100755 index 0000000000..936ba3467c --- /dev/null +++ b/gas/config/ranlib.h @@ -0,0 +1,17 @@ +/* ranlib.h 4.1 83/05/03 */ + +/* + * Structure of the __.SYMDEF table of contents for an archive. + * __.SYMDEF begins with a word giving the number of ranlib structures + * which immediately follow, and then continues with a string + * table consisting of a word giving the number of bytes of strings + * which follow and then the strings themselves. + * The ran_strx fields index the string table whose first byte is numbered 0. + */ +struct ranlib { + union { + off_t ran_strx; /* string table index of */ + char *ran_name; /* symbol defined by */ + } ran_un; + off_t ran_off; /* library member at this offset */ +}; diff --git a/gas/config/signame.h b/gas/config/signame.h new file mode 100755 index 0000000000..549bab74f8 --- /dev/null +++ b/gas/config/signame.h @@ -0,0 +1,41 @@ +/* Convert between signal names and numbers. + Copyright (C) 1990 Free Software Foundation, Inc. + +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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Names for signals from 0 to NSIG-1. */ +extern char *sys_siglist[]; + +#ifdef __STDC__ +/* Return the abbreviation (e.g. ABRT, FPE, etc.) for signal NUMBER. + Do not return this as a const char *. The caller might want to + assign it to a char *. */ +char *sig_abbrev (int number); + +/* Return the signal number for an ABBREV, or -1 if there is no + signal by that name. */ +int sig_number (const char *abbrev); + +/* Print to standard error the name of SIGNAL, preceded by MESSAGE and + a colon, and followed by a newline. */ +void psignal (int signal, const char *message); + +#else + +char *sig_abbrev (); +int sig_number (); +void psignal (); + +#endif diff --git a/gas/config/stab.h b/gas/config/stab.h new file mode 100755 index 0000000000..77f2d411ce --- /dev/null +++ b/gas/config/stab.h @@ -0,0 +1,16 @@ +#ifndef __GNU_STAB__ + +/* Indicate the GNU stab.h is in use. */ + +#define __GNU_STAB__ + +#define __define_stab(NAME, CODE, STRING) NAME=CODE, + +enum __stab_debug_code +{ +#include "stab.def" +}; + +#undef __define_stab + +#endif /* __GNU_STAB_ */ diff --git a/gas/objdump.c b/gas/objdump.c new file mode 100755 index 0000000000..20ad39e509 --- /dev/null +++ b/gas/objdump.c @@ -0,0 +1,2232 @@ +/* objdump -- dump information about an object file. + Copyright (C) 1988, 1991 Free Software Foundation, Inc. + + 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 1, 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* $Id$ */ + +/* + * objdump + * + * dump information about an object file. Until there is other documentation, + * refer to the manual page dump(1) in the system 5 program's reference manual + */ +#include +#include + +#include "getopt.h" + +#include "as.h" + +/* #define COFF_ENCAPSULATE 1 */ + +typedef FILHDR fileheader; +typedef struct exec fileheader; + +#ifdef __STDC__ +static char *sym_pname(SYMENT *s); +static char *xmalloc(unsigned size); +static char *xrealloc(char *p, unsigned size); +static void doit(char *filename); +static void dump_data(fileheader *execp, FILE *f){}; +static void dump_header(fileheader *execp, FILE *f); +static void dump_lnno(fileheader *execp, FILE *f); +static void dump_nstuff(fileheader *execp){}; +static void dump_reloc(fileheader *execp, FILE *f); +static void dump_section_contents(fileheader *execp, FILE *f); +static void dump_section_headers(fileheader *execp, FILE *f); +static void dump_sym(fileheader *execp, FILE *f); +static void dump_text(fileheader *execp, FILE *f){}; +static void hex_dump(void *buffer, int size); +#endif /* __STDC__ */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +static void read_symbols (execp, f) +#else +read_symbols (execp, f) +#endif /* OBJ_BOUT */ +struct exec *execp; +#else +static void read_section_headers(execp, f) +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +{ +#ifndef OBJ_COFF + int i; + struct nlist *sp; + if (symtbl) + return; + nsyms = execp->a_syms / sizeof (struct nlist); + if (nsyms == 0) +#else + if (section_headers || execp->f_nscns == 0) { +#endif /* OBJ_COFF */ + return; +#ifdef OBJ_COFF + } /* already read them, or don't need to */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF + symtbl = (struct nlist *)xmalloc (nsyms * sizeof (struct nlist)); +#else + fseek(f, sizeof(*execp) + execp->f_opthdr, 0); + section_headers = (struct scnhdr *) xmalloc(execp->f_nscns * sizeof(*section_headers)); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + fseek(f, N_STROFF(*execp), 0); + if (fread((char *)&strsize, sizeof strsize, 1, f) != 1) { + fprintf(stderr, "%s: can not read string table size\n", +#else + fseek (f, N_STROFF(*execp), 0); + if (fread ((char *)&strsize, sizeof strsize, 1, f) != 1) { + fprintf (stderr, "%s: can not read string table size\n", +#endif /* OBJ_BOUT */ + program_name); + exit (1); + } + strtbl = xmalloc (strsize); +#ifndef OBJ_BOUT + fseek(f, N_STROFF (*execp), 0); + if (fread(strtbl, 1, strsize, f) != strsize) { + fprintf(stderr, "%s: error reading string table\n", +#else + fseek (f, N_STROFF (*execp), 0); + if (fread (strtbl, 1, strsize, f) != strsize) { + fprintf (stderr, "%s: error reading string table\n", +#endif /* OBJ_BOUT */ + program_name); + exit (1); + } +#else + if (fread(section_headers, execp->f_nscns * sizeof(*section_headers), 1, f) != 1) { + perror("error reading section headers"); + abort(); + } /* on error */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + fseek(f, N_SYMOFF (*execp), 0); + if (fread((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) { + fprintf(stderr, "%s: error reading symbol table\n", +#else + fseek (f, N_SYMOFF (*execp), 0); + if (fread ((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) { + fprintf (stderr, "%s: error reading symbol table\n", +#endif /* OBJ_BOUT */ + program_name); + exit (1); + } +#else + return; +} /* read_section_headers() */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF + for (i = 0, sp = symtbl; i < nsyms; i++, sp++) { + if (sp->n_un.n_strx == 0) + sp->n_un.n_name = ""; + else if (sp->n_un.n_strx < 0 || sp->n_un.n_strx > strsize) + sp->n_un.n_name = ""; + else + sp->n_un.n_name = strtbl + sp->n_un.n_strx; + } +#ifndef OBJ_BOUT +} /* read_symbols() */ +#else +} +#endif /* OBJ_BOUT */ +#else +static SYMENT *symbols = NULL; +static int longest_symbol_name = SYMNMLEN; +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +static void free_symbols () +#else +free_symbols () +#endif /* OBJ_BOUT */ +#else +static void read_symbols(execp, f) +fileheader *execp; +FILE *f; +#endif /* OBJ_COFF */ +{ +#ifdef OBJ_COFF + long here; + int bufsiz = execp->f_nsyms * sizeof(struct syment); + SYMENT *s; + + if (symbols || bufsiz == 0) { + return; + } /* already read, or don't need to */ + + symbols = (SYMENT *) xmalloc(bufsiz); + + /* read symbols */ + fseek(f, execp->f_symptr, 0); + if (fread(symbols, bufsiz, 1, f) != 1) { + fprintf(stderr, "error reading symbol table.\n"); + abort(); + } /* on error */ + + here = ftell(f); + fseek(f, 0, 2); /* find end of file */ + + if (here != ftell(f)) { + /* find string table size */ + fseek(f, here, 0); + if (fread(&strsize, sizeof(strsize), 1, f) != 1) { + perror("error reading string table size"); + abort(); + } /* on error */ + + /* read string table if there is one */ + if (strsize > 0) { + strtbl = xmalloc(strsize); + fseek(f, -sizeof(strsize), 1); /* backup over size count */ + + if (fread(strtbl, strsize, 1, f) != 1) { + perror("error reading string table"); + abort(); + } /* on error */ + + /* then connect the dots. */ + for (s = symbols; s < symbols + execp->f_nsyms; ++s) { + if (!s->n_zeroes) { + int l; + + s->n_offset = (long) strtbl + s->n_offset; + l = strlen((char *) s->n_offset); + if (l > longest_symbol_name) { + longest_symbol_name = l; + } /* keep max */ + } /* "long" name */ + + s += s->n_numaux; /* skip aux entries */ + } /* walk the symbol table */ + } else { + fprintf(stderr, "Well, now that's weird. I have a string table whose size is zero?\n"); + } /* if there is a string table */ + } /* if there is a string table */ + return; +} /* read_symbols() */ + +#ifdef comment +static void free_symbols() { +#endif /* OBJ_COFF */ + if (symtbl) + free (symtbl); + symtbl = NULL; + if (strtbl) + free (strtbl); + strtbl = NULL; +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +} /* free_symbols() */ +#ifndef OBJ_COFF +#else +} +#endif /* OBJ_BOUT */ +#else +#endif /* comment */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF + +#ifndef OBJ_BOUT +static void usage () +#else +usage () +#endif /* OBJ_BOUT */ +{ +#ifndef OBJ_BOUT +#else +static void usage() { +#endif /* OBJ_COFF */ + (void) fprintf(stderr, "Usage: %s\n", program_name); + (void) fprintf(stderr, "\t[-ahnrt] [+all] [+header] [+nstuff]\n"); + (void) fprintf(stderr, "\t[+reloc] [+symbols] [+text] [+data]\n"); + (void) fprintf(stderr, "\t[+omit-symbol-numbers] [+omit-reloc-numbers]\n"); + (void) fprintf(stderr, "\tfile...\n"); +#ifndef OBJ_COFF +#else + fprintf (stderr, "\ +Usage: %s [-hnrt] [+header] [+nstuff] [+reloc] [+symbols] file...\n", + program_name); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + exit (1); +#ifndef OBJ_COFF +} +#else +} /* usage() */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +static int aflag = 0; +static int hflag = 0; +#ifdef OBJ_COFF +static int lflag = 0; +#endif /* OBJ_COFF */ +static int nflag = 0; +static int rflag = 0; +#ifdef OBJ_COFF +static int sflag = 0; +#endif /* OBJ_COFF */ +static int tflag = 0; +static int Dflag = 0; +static int Tflag = 0; +static int omit_reloc_numbers_flag = 0; +static int omit_sym_numbers_flag = 0; +#ifndef OBJ_COFF +#else +int hflag; +int nflag; +int rflag; +int tflag; +#endif /* OBJ_BOUT */ +#else +static int section_headers_flag = 0; +static int section_contents_flag = 0; +#endif /* OBJ_COFF */ + +/* Size of a page. Required by N_DATADDR in a.out.gnu.h [VAX]. */ +int page_size; + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +int main (argc, argv) +#else +int main(argc, argv) +#endif /* OBJ_COFF */ +int argc; +#ifndef OBJ_COFF +#else +main (argc, argv) +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +char **argv; +{ + int c; +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +/* extern char *optarg; */ +#ifndef OBJ_COFF +#else + extern char *optarg; +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + extern int optind; + int seenflag = 0; + int ind = 0; +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + static struct option long_options[] = { +#ifdef OBJ_COFF + {"line-numbers", 0, &lflag, 1}, + {"section-contents", 0, §ion_contents_flag, 1}, + {"section-headers", 0, §ion_headers_flag, 1}, +#endif /* OBJ_COFF */ + {"symbols", 0, &tflag, 1}, + {"reloc", 0, &rflag, 1}, + {"nstuff", 0, &nflag, 1}, + {"header", 0, &hflag, 1}, + {"data", 0, &Dflag, 1}, + {"text", 0, &Tflag, 1}, + {"omit-relocation-numbers", 0, &omit_reloc_numbers_flag, 1}, + {"omit-symbol-numbers", 0, &omit_sym_numbers_flag, 1}, + {"all", 0, &aflag, 1}, + {NULL, 0, NULL, 0}, + }; +#ifndef OBJ_COFF +#else + static struct option long_options[] = + { + {"symbols", 0, &tflag, 1}, + {"reloc", 0, &rflag, 1}, + {"nstuff", 0, &nflag, 1}, + {"header", 0, &hflag, 1}, + {NULL, 0, NULL, 0} + }; +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF + page_size = getpagesize (); + +#endif /* OBJ_COFF */ + program_name = argv[0]; + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + while ((c = getopt_long (argc, argv, "ahnrt", long_options, &ind)) != EOF) { +#else + while ((c = getopt_long (argc, argv, "hnrt", long_options, &ind)) + != EOF) { +#endif /* OBJ_BOUT */ +#else + while ((c = getopt_long (argc, argv, "ahlonrt", long_options, &ind)) != EOF) { +#endif /* OBJ_COFF */ + seenflag = 1; +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + switch (c) { + case 0 : break; /* we've been given a long option */ +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + case 'a': aflag = 1; break; + case 'h': hflag = 1; break; +#ifdef OBJ_COFF + case 'o': hflag = 1; break; + case 'l': lflag = 1; break; +#endif /* OBJ_COFF */ + case 'n': nflag = 1; break; + case 'r': rflag = 1; break; +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + case 't': tflag = 1; break; +#ifndef OBJ_COFF +#ifdef OBJ_BOUT + case 'r': rflag = 1; break; + case 'n': nflag = 1; break; + case 'h': hflag = 1; break; +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + default: + usage (); +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + } /* switch on option */ + } /* while there are options */ +#ifndef OBJ_COFF +#else + } + } +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + + if (seenflag == 0 || optind == argc) + usage (); + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (aflag) { + hflag = 1; +#ifdef OBJ_COFF + lflag = 1; +#endif /* OBJ_COFF */ + nflag = 1; + rflag = 1; + tflag = 1; + Dflag = 1; + Tflag = 1; +#ifdef OBJ_COFF + section_headers_flag = 1; + section_contents_flag = 1; +#endif /* OBJ_COFF */ + } /* if all */ + +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + while (optind < argc) +#ifndef OBJ_COFF + doit (argv[optind++]); +#ifndef OBJ_BOUT +#else + doit(argv[optind++]); +#endif /* OBJ_COFF */ + + return(0); +} /* main() */ +#ifndef OBJ_COFF +#else +} +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +static void doit (name) +#else +doit (name) +#endif /* OBJ_BOUT */ +#else +static void doit(name) +#endif /* OBJ_COFF */ +char *name; +{ + FILE *f; +#ifndef OBJ_COFF + struct exec exec; +#ifndef OBJ_BOUT +#else + fileheader exec; + + if (section_headers) { + free(section_headers); + section_headers = NULL; + } /* free section headers */ + + if (symbols) { + free(symbols); + symbols = NULL; + } /* free symbols */ + +#endif /* OBJ_COFF */ + printf("%s:\n", name); +#ifndef OBJ_COFF +#else + printf ("%s:\n", name); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + f = fopen (name, "r"); + if (f == NULL) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + fprintf(stderr, "%s: can not open ", program_name); +#ifndef OBJ_COFF +#else + fprintf (stderr, "%s: can not open ", program_name); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + perror (name); + return; + } +#ifdef HEADER_SEEK + HEADER_SEEK (f); +#endif +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + if (fread((char *)&exec, sizeof exec, 1, f) != 1) { +#else + if (fread((char *)&exec, sizeof(exec), 1, f) != 1) { +#endif /* OBJ_COFF */ + fprintf(stderr, "%s: can not read header for %s\n", +#ifndef OBJ_COFF +#else + if (fread ((char *)&exec, sizeof exec, 1, f) != 1) { + fprintf (stderr, "%s: can not read header for %s\n", +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + program_name, name); + return; + } + +#ifdef OBJ_COFF +#ifdef I960ROMAGIC +#define N_BADMAG I960BADMAG +#endif /* I960ROMAGIC */ + +#endif /* OBJ_COFF */ + if (N_BADMAG (exec)) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + fprintf(stderr, "%s: %s is not a%s object file\n", + program_name, name, +#ifdef B_OUT + " b.out" +#else + "n a.out" +#endif /* B_OUT */ + ); +#ifndef OBJ_COFF +#else + fprintf (stderr, "%s: %s is not an object file\n", + program_name, name); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + return; + } + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (hflag) dump_header(&exec, f); +#ifdef OBJ_COFF + if (lflag) dump_lnno(&exec, f); +#endif /* OBJ_COFF */ + if (nflag) dump_nstuff(&exec); +#ifdef OBJ_COFF + if (section_headers_flag) dump_section_headers(&exec, f); + if (section_contents_flag) dump_section_contents(&exec, f); + if (sflag) dump_section_contents(&exec, f); +#endif /* OBJ_COFF */ + if (Tflag) dump_text(&exec, f); + if (Dflag) dump_data(&exec, f); + if (tflag) dump_sym(&exec, f); + if (rflag) dump_reloc(&exec, f); +#ifndef OBJ_COFF +#else + if (hflag) + dump_header (&exec); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF + if (nflag) + dump_nstuff (&exec); +#endif /* OBJ_BOUT */ +#else + printf("\n"); + fclose(f); + return; +} /* doit() */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + free_symbols(); +#else + if (tflag) + dump_sym (&exec, f); +#endif /* OBJ_BOUT */ +#else +static void dump_lnno(execp, f) +fileheader *execp; +FILE *f; +{ + int i = execp->f_nscns; + struct scnhdr *section; + char *buffer; + int bufsiz = 0; + + if (i) { + printf("Line numbers:\n"); + read_section_headers(execp, f); + read_symbols(execp, f); + + for (section = section_headers; i; ++section, --i) { + int size = section->s_nlnno * LINESZ; + LINENO *r; + + if (size > bufsiz) { + if (bufsiz) { + buffer = xrealloc(buffer, bufsiz = size); + } else { + buffer = xmalloc(bufsiz = size); + } /* if we had allocated anything before */ + } /* if bigger than our old buffer */ + + printf("%8.8s:", section->s_name); + fseek(f, section->s_lnnoptr, 0); + + if (size) { + int j; + + if (fread(buffer, size, 1, f) != 1) { + printf(" (error reading lnno)\n"); + continue; + } /* on read error */ + + printf("\n"); + + for (r = (LINENO *) buffer, j = 0; j < section->s_nlnno; ++j, ++r) { + printf("lnno = %d,", r->l_lnno); + + if (r->l_lnno) { + printf(" paddr = 0x%lx", (unsigned long) r->l_addr.l_paddr); + } else { + printf(" symndx = %ld, \"%s\"", + r->l_addr.l_symndx, + sym_pname(symbols + r->l_addr.l_symndx)); + } /* if not symbol'd */ + + if (r->padding[0] || r->padding[1]) { + printf(" (padding = %2x %2x)", + (unsigned) r->padding[0], + (unsigned) r->padding[1]); + } /* if padding not zero'd */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#else + printf("\n"); + } /* for each lnno record */ + } else { + printf(" (section has no line numbers.)\n"); + } /* if there really is something in the section */ + } /* for each section */ + } else { + printf("No Sections.\n"); + } /* if there are sections */ + + free(buffer); + printf("\n"); +#endif /* OBJ_COFF */ + return; +#ifndef OBJ_COFF +} /* doit() */ +#else + if (rflag) + dump_reloc (&exec, f); +#endif /* OBJ_BOUT */ +#else +} /* dump_lnno() */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +static void dump_header(execp, f) +#else + free_symbols (); +#else +static void dump_reloc(execp, f) +fileheader *execp; +FILE *f; +{ + int i = execp->f_nscns; + struct scnhdr *section; + char *buffer; + int bufsiz = 0; + + if (i) { + read_section_headers(execp, f); + + printf("Relocations:\n"); + for (section = section_headers; i; ++section, --i) { + int size = section->s_nreloc * RELSZ; + RELOC *r; + + if (size > bufsiz) { + if (bufsiz) { + buffer = xrealloc(buffer, bufsiz = size); + } else { + buffer = xmalloc(bufsiz = size); + } /* if we had allocated anything before */ + } /* if bigger than our old buffer */ + + printf("%8.8s:", section->s_name); + fseek(f, section->s_relptr, 0); + + if (size) { + int j; + + if (fread(buffer, size, 1, f) != 1) { + printf(" (error reading reloc)\n"); + continue; + } /* on read error */ + + printf("\n"); + + for (r = (RELOC *) buffer, j = 0; j < section->s_nreloc; ++j, ++r) { + printf("vaddr = 0x%lx, symndx = %ld, r_type = ", + (unsigned long) r->r_vaddr, + r->r_symndx); + + switch (r->r_type) { + case R_RELLONG: printf(" RELLONG"); break; + case R_IPRSHORT: printf("IPRSHORT"); break; + case R_IPRMED: printf(" IPRMED"); break; + case R_IPRLONG: printf(" IPRLONG"); break; + case R_OPTCALL: printf(" OPTCALL"); break; + case R_OPTCALLX: printf("OPTCALLX"); break; + case R_GETSEG: printf(" GETSEG"); break; + case R_GETPA: printf(" GETPA"); break; + case R_TAGWORD: printf(" TAGWORD"); break; + default: printf("unrecognized"); break; + } /* switch on reloc type */ + + printf("."); + + if (r->pad[0] || r->pad[1]) { + printf(" (padding = %2x %2x)", + (unsigned) r->pad[0], + (unsigned) r->pad[1]); + } /* if padding isn't zero */ + + printf("\n"); + } /* for each reloc record */ + } else { + printf(" (section has no relocations.)\n"); + } /* if there really is something in the section */ + } /* for each section */ + } else { + printf("No Sections.\n"); + } /* if there are sections */ + + /* free(buffer); */ + printf("\n"); + return; +} /* dump_reloc() */ + +static void dump_section_contents(execp, f) +fileheader *execp; +FILE *f; +{ + int i = execp->f_nscns; + struct scnhdr *section; + char *buffer; + int bufsiz = 0; + + if (i) { + read_section_headers(execp, f); + printf("Section Contents:\n"); + + for (section = section_headers; i; ++section, --i) { + if (section->s_size > bufsiz) { + if (bufsiz) { + buffer = xrealloc(buffer, bufsiz = section->s_size); + } else { + buffer = xmalloc(bufsiz = section->s_size); + } /* if we had allocated anything before */ + } /* if bigger than our old buffer */ + + printf("%8.8s:", section->s_name); + + if (section->s_flags & STYP_BSS) { + printf(" bss sections have no contents.\n"); + } else { + fseek(f, section->s_scnptr, 0); + + if (section->s_size) { + if (fread(buffer, section->s_size, 1, f) != 1) { + printf(" (error reading section contents)\n"); + } /* on read error */ + + printf("\n"); + hex_dump(buffer, section->s_size); + printf("\n"); + } else { + printf(" (section has a size of zero.)\n"); + } /* if there really is a section */ + } /* if bss else dump */ + } /* for each section */ + } else { + printf("No Sections.\n"); + } /* if there are sections */ + + free(buffer); + printf("\n"); + return; +} /* dump_section_contents() */ + +static void dump_section_headers(execp, f) +fileheader *execp; +FILE *f; +{ + int i = execp->f_nscns; + struct scnhdr *section; + + if (i > 0) { + read_section_headers(execp, f); + printf("Section Headers:\n"); + + for (section = section_headers; i; ++section, --i) { + long flags = section->s_flags; + + printf("\"%8.8s\"", section->s_name); + + printf(" physical address: 0x%x vma: 0x%x size: 0x%x (%ld)", + (unsigned) section->s_paddr, + (unsigned) section->s_vaddr, + (unsigned) section->s_size, + section->s_size); + + printf(" relocs: %d linenos: %d alignment: 0x%lx (%ld)", + section->s_nreloc, + section->s_nlnno, + section->s_align, + (long) section->s_align); + + printf(" flags: 0x%x = ", (unsigned) section->s_flags); + + if (flags & STYP_REG) { + printf(" REG"); + flags &= ~STYP_REG; + } /* STYP_REG */ + + if (flags & STYP_DSECT) { + printf(" DSECT"); + flags &= ~STYP_DSECT; + } /* STYP_DSECT */ + + if (flags & STYP_NOLOAD) { + printf(" NOLOAD"); + flags &= ~STYP_NOLOAD; + } /* STYP_NOLOAD */ + + if (flags & STYP_GROUP) { + printf(" GROUP"); + flags &= ~STYP_GROUP; + } /* STYP_GROUP */ + + if (flags & STYP_PAD) { + printf(" PAD"); + flags &= ~STYP_PAD; + } /* STYP_PAD */ + + if (flags & STYP_COPY) { + printf(" COPY"); + flags &= ~STYP_COPY; + } /* STYP_COPY */ + + if (flags & STYP_TEXT) { + printf(" TEXT"); + flags &= ~STYP_TEXT; + } /* STYP_TEXT */ + + if (flags & S_SHRSEG) { + printf(" SHRSEG"); + flags &= ~S_SHRSEG; + } /* S_SHRSEG */ + + if (flags & STYP_DATA) { + printf(" DATA"); + flags &= ~STYP_DATA; + } /* STYP_DATA */ + + if (flags & STYP_BSS) { + printf(" BSS"); + flags &= ~STYP_BSS; + } /* STYP_BSS */ + + if (flags & S_NEWFCN) { + printf(" NEWFCN"); + flags &= ~S_NEWFCN; + } /* S_NEWFCN */ + + if (flags & STYP_INFO) { + printf(" INFO"); + flags &= ~STYP_INFO; + } /* STYP_INFO */ + + if (flags & STYP_OVER) { + printf(" OVER"); + flags &= ~STYP_OVER; + } /* STYP_OVER */ + + if (flags & STYP_LIB) { + printf(" LIB"); + flags &= ~STYP_LIB; + } /* STYP_LIB */ + + if (flags & STYP_MERGE) { + printf(" MERGE"); + flags &= ~STYP_MERGE; + } /* STYP_MERGE */ + + if (flags & STYP_REVERSE_PAD) { + printf(" REVERSE_PAD"); + flags &= ~STYP_REVERSE_PAD; + } /* STYP_REVERSE_PAD */ + + if (flags) { + printf(" +unknown"); + } /* foo */ + + printf("\n"); + } /* for each section header */ + } else { + printf("No section headers.\n"); + } /* if there are any sections */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +} +#else + printf("\n"); + return; +} /* dump_section_headers() */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +dump_header (execp) +#endif /* OBJ_BOUT */ +struct exec *execp; +#ifndef OBJ_BOUT +#else +static void dump_header(execp, f) +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +{ +#ifdef OBJ_COFF +#ifdef COFF + printf("magic: 0x%x (%o) ", (unsigned) execp->f_magic, (unsigned) execp->f_magic); + printf("number of sections: %d number of syms: %ld ", execp->f_nscns, execp->f_nsyms); + printf("time stamp: %s", ctime(&(execp->f_timdat))); + printf("flags:"); + + if (execp->f_flags & F_RELFLG) { + printf(" RELFLG"); + } /* relflg */ + + if (execp->f_flags & F_EXEC) { + printf(" EXEC"); + } /* exec */ + + if (execp->f_flags & F_LNNO) { + printf(" LNNO"); + } /* lnno */ + + if (execp->f_flags & F_LSYMS) { + printf(" LSYMS"); + } /* lsyms */ + + if (execp->f_flags & F_AR32WR) { + printf(" AR32WR"); + } /* ar32wr */ + + assert(F_I960KB == F_I960SB); + assert(F_I960KA == F_I960SA); + + switch (execp->f_flags & F_I960TYPE) { + case F_I960CORE: printf(" I960CORE"); break; + case F_I960KB: printf(" I960KB (== I960SB)"); break; + case F_I960MC: printf(" I960MC"); break; + case F_I960XA: printf(" I960XA"); break; + case F_I960CA: printf(" I960CA"); break; + case F_I960KA: printf(" I960KA (== I960SA)"); break; + default: printf(" I960Unknown"); break; + } /* switch on i960 type */ + + if (execp->f_flags & ~(F_RELFLG | F_EXEC | F_LNNO | F_LSYMS | F_AR32WR | F_I960TYPE)) { + printf(" +unrecognized"); + } /* unrecognized */ + + printf("\n\n"); + + if (execp->f_opthdr) { + if (execp->f_opthdr == sizeof(AOUTHDR)) { + AOUTHDR hdr; + + fseek(f, sizeof(*execp), 0); + if (fread(&hdr, sizeof(AOUTHDR), 1, f) == 1) { + printf("aouthdr:\n"); + printf("magic: 0x%x (%o)", (unsigned) hdr.magic, (unsigned) hdr.magic); + printf(" vstamp: 0x%ld\n", (long) hdr.vstamp); + + printf("sizes: text 0x%lx (%ld), data 0x%lx (%ld), bss 0x%lx (%ld)\n", + hdr.tsize, + (long) hdr.tsize, + hdr.dsize, + (long) hdr.dsize, + hdr.bsize, + (long) hdr.bsize); + + printf("entry point: 0x%lx, starts: text 0x%lx (%ld), data 0x%lx (%ld)\n", + hdr.entry, + hdr.text_start, + (long) hdr.text_start, + hdr.data_start, + (long) hdr.data_start); + + printf("tag entries: %ld\n", + (long) hdr.tagentries); + } else { + fprintf(stderr, "%s: error reading optional header", program_name); + perror(NULL); + } /* on error */ + + } else { + printf("opthder != sizeof aouthdr?"); + } /* size mismatch */ + + } else { + printf("No optional header."); + } /* print optional header */ + + +#else /* COFF */ +#endif /* OBJ_COFF */ + int x; + +#if defined (__GNU_EXEC_MACROS__) && !defined (__STRUCT_EXEC_OVERRIDE__) +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("magic: 0x%x (%o)", N_MAGIC(*execp), N_MAGIC(*execp)); + printf("machine type: %d", N_MACHTYPE(*execp)); + printf("flags: 0x%x", N_FLAGS(*execp)); +#ifndef OBJ_COFF +#else + printf ("magic: 0x%x (%o)", N_MAGIC(*execp), N_MAGIC(*execp)); + printf ("machine type: %d", N_MACHTYPE(*execp)); + printf ("flags: 0x%x", N_FLAGS(*execp)); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +#else /* non-gnu struct exec. */ +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("magic: 0x%x (%o) ", (unsigned) execp->a_magic, (unsigned) execp->a_magic); +#ifndef OBJ_COFF +#else + printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +#endif /* non-gnu struct exec. */ +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("text 0x%x ", (unsigned) execp->a_text); + printf("data 0x%x ", (unsigned) execp->a_data); + printf("bss 0x%x\n", (unsigned) execp->a_bss); + printf("nsyms %ld", (long) (execp->a_syms / sizeof(struct nlist))); + x = execp->a_syms % sizeof(struct nlist); +#ifndef OBJ_COFF +#else + printf ("text 0x%x ", execp->a_text); + printf ("data 0x%x ", execp->a_data); + printf ("bss 0x%x\n", execp->a_bss); + printf ("nsyms %d", execp->a_syms / sizeof (struct nlist)); + x = execp->a_syms % sizeof (struct nlist); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + if (x) +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf(" (+ %d bytes)", x); + printf(" entry 0x%lx ", execp->a_entry); + +#ifdef B_OUT + printf(" talign 0x%x", (unsigned) execp->a_talign); + printf(" dalign 0x%x", (unsigned) execp->a_dalign); + printf(" balign 0x%x", (unsigned) execp->a_balign); + printf(" unused 0x%x", (unsigned) execp->unused); +#endif /* B_OUT */ + + printf(" trsize 0x%lx", execp->a_trsize); + printf(" drsize 0x%lx", execp->a_drsize); + + if (N_TXTOFF(*execp) != 0 && N_TXTOFF(*execp) != sizeof(*execp)) { + char *buffer; + char *i; + int size = N_TXTOFF(*execp) - sizeof(*execp); + + buffer = xmalloc(size); + + fseek(f, sizeof(*execp), 0); + if (fread(buffer, size, 1, f) != 1) { + fprintf(stderr, "%s: error reading between header and text", program_name); + perror(NULL); + } /* on error */ + + for (i = buffer; i < (buffer + size); ++i) { + if (*i != '\0') { + printf(" (garbage follows header)"); + break; + } /* non null */ + } /* walk the buffer looking for garbage */ + } /* check for garbage following header */ +#ifdef OBJ_COFF +#endif /* COFF */ +#endif /* OBJ_COFF */ + + printf("\n"); + return; +} /* dump_header() */ + +#ifdef OBJ_COFF +#ifdef comment +#endif /* OBJ_COFF */ +static void dump_nstuff(execp) +#ifndef OBJ_COFF +struct exec *execp; +#else +fileheader *execp; +#endif /* OBJ_COFF */ +{ + printf("N_BADMAG %d\n", N_BADMAG(*execp)); + printf("N_TXTOFF 0x%x\n", N_TXTOFF(*execp)); + printf("N_SYMOFF 0x%lx\n", N_SYMOFF(*execp)); + printf("N_STROFF 0x%lx\n", N_STROFF(*execp)); + printf("N_TXTADDR 0x%x\n", (unsigned) N_TXTADDR(*execp)); + printf("N_DATADDR 0x%lx\n", N_DATADDR(*execp)); + + return; +} /* dump_nstuff() */ +#ifndef OBJ_COFF +#else + printf (" (+ %d bytes)", x); + printf (" entry 0x%x ", execp->a_entry); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +static void dump_text(execp, f) +#ifndef OBJ_COFF +struct exec *execp; +#else +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +{ + void *buffer; + + if (execp->a_text) { + buffer = xmalloc(execp->a_text); + fseek(f, N_TXTOFF(*execp), 0); + + if (fread(buffer, execp->a_text, 1, f) != 1) { + fprintf(stderr, "%s: error reading text section.\n", program_name); + return; + } /* on error */ +#ifndef OBJ_COFF +#else + printf (" talign 0x%x ", execp->a_talign); + printf (" dalign 0x%x ", execp->a_dalign); + printf (" balign 0x%x ", execp->a_balign); + printf (" unused 0x%x ", execp->unused); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + hex_dump(buffer, execp->a_text); + free(buffer); + } else { + printf("No text section.\n"); + } /* if there is text */ + + return; +} /* dump_text() */ +#ifndef OBJ_COFF +#else + printf ("trsize 0x%x ", execp->a_trsize); + printf ("drsize 0x%x\n", execp->a_drsize); +} +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +static void dump_data(execp, f) +#ifndef OBJ_COFF +#else +dump_nstuff (execp) +#endif /* OBJ_BOUT */ +struct exec *execp; +#ifndef OBJ_BOUT +#else +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +{ + void *buffer; + + if (execp->a_data) { + buffer = xmalloc(execp->a_data); + fseek(f, N_TXTOFF(*execp), 0); + + if (fread(buffer, execp->a_data, 1, f) != 1) { + fprintf(stderr, "%s: error reading data section.\n", program_name); + return; + } /* on error */ + + hex_dump(buffer, execp->a_data); + free(buffer); + } else { + printf("No data section.\n"); + } /* if there is data */ + + return; +} /* dump_data() */ +#ifdef OBJ_COFF +#endif /* comment */ +#endif /* OBJ_COFF */ + +static void hex_dump(buffer, size) +void *buffer; +int size; +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +{ +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + FILE *f; + +#ifndef OBJ_COFF + if ((f = popen("od -x +0x0", "w")) != NULL) { +#else + fflush(stdout); + + if ((f = popen("hexl", "w")) != NULL) { +#endif /* OBJ_COFF */ + if (fwrite(buffer, size, 1, f) != 1) { + (void) fprintf(stderr, "%s: error writing to od(1) pipe:", program_name); + perror(NULL); + } /* on error */ + } else { + (void) fprintf(stderr, "%s: error opening pipe to od(1):", program_name); + perror(NULL); + } /* on successful popen */ + + (void) pclose(f); +#ifdef OBJ_COFF + fflush(stdout); +#endif /* OBJ_COFF */ + return; +} /* hex_dump() */ +#ifndef OBJ_COFF +#else + printf ("N_BADMAG %d\n", N_BADMAG (*execp)); + printf ("N_TXTOFF 0x%x\n", N_TXTOFF (*execp)); + printf ("N_SYMOFF 0x%x\n", N_SYMOFF (*execp)); + printf ("N_STROFF 0x%x\n", N_STROFF (*execp)); + printf ("N_TXTADDR 0x%x\n", N_TXTADDR (*execp)); + printf ("N_DATADDR 0x%x\n", N_DATADDR (*execp)); +} +#endif /* OBJ_BOUT */ +#else + +char *sym_class_pname(class) +char class; +{ + switch (class) { + case C_EFCN: return("EFCN"); + case C_NULL: return("NULL"); + case C_AUTO: return("AUTO"); + case C_EXT: return("EXT"); + case C_STAT: return("STAT"); + case C_REG: return("REG"); + case C_EXTDEF: return("EXTDEF"); + case C_LABEL: return("LABEL"); + case C_ULABEL: return("ULABEL"); + case C_MOS: return("MOS"); + case C_ARG: return("ARG"); + case C_STRTAG: return("STRTAG"); + case C_MOU: return("MOU"); + case C_UNTAG: return("UNTAG"); + case C_TPDEF: return("TPDEF"); + case C_USTATIC: return("USTATIC"); + case C_ENTAG: return("ENTAG"); + case C_MOE: return("MOE"); + case C_REGPARM: return("REGPARM"); + case C_FIELD: return("FIELD"); + case C_BLOCK: return("BLOCK"); + case C_FCN: return("FCN"); + case C_EOS: return("EOS"); + case C_FILE: return("FILE"); + case C_LINE: return("LINE"); + case C_ALIAS: return("ALIAS"); + case C_HIDDEN: return("HIDDEN"); + + case C_SCALL: return("SCALL"); + case C_LEAFEXT: return("LEAFEXT"); + case C_OPTVAR: return("OPTVAR"); + case C_DEFINE: return("DEFINE"); + case C_PRAGMA: return("PRAGMA"); + case C_SEGMENT: return("SEGMENT"); + case C_LEAFSTAT:return("LEAFSTAT"); + case C_AUTOARG: return("AUTOARG"); + + default: return("(???)"); + } /* switch on class */ +} /* sym_class_pname() */ + +char *sym_type_pname(type) +unsigned long type; +{ + switch (type) { + case T_NULL: return("NULL"); + case T_VOID: return("VOID"); + case T_CHAR: return("CHAR"); + case T_SHORT: return("SHORT"); + case T_INT: return("INT"); + case T_LONG: return("LONG"); + case T_FLOAT: return("FLOAT"); + case T_DOUBLE: return("DOUBLE"); + case T_STRUCT: return("STRUCT"); + case T_UNION: return("UNION"); + case T_ENUM: return("ENUM"); + case T_MOE: return("MOE"); + case T_UCHAR: return("UCHAR"); + case T_USHORT: return("USHORT"); + case T_UINT: return("UINT"); + case T_ULONG: return("ULONG"); + case T_LNGDBL: return("LNGDBL"); + + default: return("(???)"); + } /* switch on type */ +} /* sym_type_pname() */ + +char *sym_section_pname(scnum, execp) +short scnum; +fileheader *execp; +{ + switch (scnum) { + case N_UNDEF: return("UNDEF"); + case N_ABS: return("ABS"); + case N_DEBUG: return("DEBUG"); + case N_TV: return("NTV"); + case P_TV: return("PTV"); + + default: + assert(0 <= (scnum-1)); + assert((scnum-1) < execp->f_nscns); + return(section_headers[scnum-1].s_name); + } /* switch on scnum */ +} /* sym_section_pname() */ + +static char *sym_pname(s) +SYMENT *s; +{ + static char buffer[SYMNMLEN + 1]; + if (s->n_zeroes) { + bzero(buffer, SYMNMLEN + 1); + bcopy(s->n_name, buffer, SYMNMLEN); + return(buffer); + } else { + return((char *) s->n_offset); + } /* if "short" name */ +} /* sym_pname() */ + +/* + * Notes: .file must be first, .text, .data, .bss must be last. + */ + +static void dump_aux_fcn(aux) +AUXENT *aux; +{ + /* function symbol */ + printf(" tagndx %ld,", aux->x_sym.x_tagndx); + printf(" size %ld,", aux->x_sym.x_misc.x_fsize); + printf(" lnnoptr 0x%lx,", (unsigned long) aux->x_sym.x_fcnary.x_fcn.x_lnnoptr); + printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx); + printf(" tvndx 0x%x,", (unsigned) aux->x_sym.x_tvndx); + return; +} /* dump_aux_fcn() */ + +static void dump_aux_tagmember(aux) +AUXENT *aux; +{ + printf(" tagndx %ld,", aux->x_sym.x_tagndx); + printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size); + return; +} /* dump_aux_tagmember() */ + +static void dump_aux_array(aux) +AUXENT *aux; +{ + int i; +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#else + printf(" size %d, ", aux->x_sym.x_misc.x_lnsz.x_size); + + for (i = 0; i < 4; ++i) { + printf("[%d]", aux->x_sym.x_fcnary.x_ary.x_dimen[i]); + } /* four dimensions */ + + return; +} /* dump_aux_array() */ + +#endif /* OBJ_COFF */ +static void dump_sym(execp, f) +#ifndef OBJ_COFF +#else +dump_sym (execp, f) +#endif /* OBJ_BOUT */ +struct exec *execp; +#else +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +{ + int i; +#ifndef OBJ_COFF + struct nlist *sp; +#else + SYMENT *sp; +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT + read_symbols(execp, f); +#else + read_symbols (execp, f); +#endif /* OBJ_BOUT */ + if (nsyms == 0) { +#ifndef OBJ_BOUT +#else + read_section_headers(execp, f); + + if (execp->f_nsyms == 0) { +#endif /* OBJ_COFF */ + printf("no symbols\n"); +#ifndef OBJ_COFF +#else + printf ("no symbols\n"); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + return; +#ifndef OBJ_COFF + } +#else + } /* if there are any */ + + read_symbols(execp, f); + printf("Symbols:\n"); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (!omit_sym_numbers_flag) { +#ifndef OBJ_COFF + printf("%3s: ", "#"); +#else + printf("%3s:", "#"); +#endif /* OBJ_COFF */ + } /* printing symbol numbers */ + +#ifndef OBJ_COFF + printf("%4s %5s %4s %8s\n", + "type", "other", "desc", "val"); +#else + printf(" %*.*s %8.8s %3.3s %8.8s %7.7s %3.3s %s\n", + SYMNMLEN, SYMNMLEN, "name", + "value", "num", "sec-name", "class", "aux", "type"); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#else + printf ("%3s: %4s %5s %4s %8s\n", + "#", "type", "other", "desc", "val"); +#endif /* OBJ_BOUT */ + for (i = 0, sp = symtbl; i < nsyms; i++, sp++) { +#ifndef OBJ_BOUT +#else + for (i = 0, sp = symbols; sp < symbols + execp->f_nsyms; ++sp, ++i) { +#endif /* OBJ_COFF */ + if (!omit_sym_numbers_flag) { +#ifndef OBJ_COFF + printf("%3d: ", i); +#else + printf("%3d:", i); +#endif /* OBJ_COFF */ + } /* printing symbol numbers */ + +#ifndef OBJ_COFF + printf("%4x %5x %4x %8lx %s", + (unsigned) (sp->n_type & 0xff), + (unsigned) (sp->n_other & 0xff), + (unsigned) (sp->n_desc & 0xffff), +#else + printf ("%3d: %4x %5x %4x %8x %s", + i, + sp->n_type & 0xff, + sp->n_other & 0xff, + sp->n_desc & 0xffff, +#endif /* OBJ_BOUT */ + sp->n_value, + sp->n_un.n_name); +#ifndef OBJ_BOUT +#else + printf(" %*.*s", SYMNMLEN, SYMNMLEN, (sp->n_zeroes) ? sp->n_name : ""); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#else + +#endif /* OBJ_BOUT */ + if (sp->n_type & N_EXT) printf(" N_EXT"); + if (sp->n_type & N_STAB) printf(" N_STAB"); +#ifndef OBJ_BOUT +#else + printf(" %8lx", (unsigned long) sp->n_value); + printf(" %3d", sp->n_scnum); + printf(" %8.8s", sym_section_pname(sp->n_scnum, execp)); + printf(" %7.7s", sym_class_pname(sp->n_sclass)); + printf(" %1d", sp->n_numaux); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#else + +#endif /* OBJ_BOUT */ + if ((sp->n_type & N_TYPE) == N_UNDF) { + printf(" N_UNDF"); + } else { + if (sp->n_type & N_ABS) printf(" N_ABS"); + if (sp->n_type & N_TEXT) printf(" N_TEXT"); + if (sp->n_type & N_DATA) printf(" N_DATA"); + if (sp->n_type & N_BSS) printf(" N_BSS"); + if (sp->n_type & N_FN) printf(" N_FN"); + } /* if not undefined */ +#ifndef OBJ_BOUT +#else + printf(" %s", sym_type_pname(BTYPE(sp->n_type))); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifdef B_OUT +#else + +#endif /* OBJ_BOUT */ + if (sp->n_other) { + printf(" ["); +#ifndef OBJ_BOUT +#else + /* derived type */ + printf("%s", (ISPTR(sp->n_type) + ? "(PTR)" + : (ISFCN(sp->n_type) + ? "(FCN)" + : (ISARY(sp->n_type) + ? "(ARY)" + : "")))); + + if (sp->n_type & ~(N_BTMASK | N_TMASK)) { + printf("+"); + } /* if type isn't all */ + + if (!sp->n_zeroes) { + printf(" \"%s\"", sym_pname(sp)); + } /* if "long" name */ + + /* FIXME do something with the flags field */ +#ifdef comment + if (sp->pad1[0] != 0 || sp->pad1[1] != 0) { + printf(" (pad1 %2.2x%2.2x)", (unsigned) sp->pad1[0], (unsigned) sp->pad1[1]); + } /* if padding not zeroed */ +#endif /* comment */ + + if (sp->pad2[0] != 0 || sp->pad2[1] != 0) { + printf(" (pad2 %2.2x%2.2x)", (unsigned) sp->pad2[0], (unsigned) sp->pad2[1]); + } /* if padding not zeroed */ + +#define DTYPE(x) (((x) & N_TMASK) >> N_BTSHFT) + + if (sp->n_numaux > 0) { + int auxcountshouldbe = 1; + AUXENT *aux = (AUXENT *) (sp + 1); + AUXENT *aux2 = (AUXENT *) (sp + 2); +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#else +#else + switch (sp->n_sclass) { + + case C_FILE: /* file symbol */ + printf(" filename \"%s\"", aux->x_file.x_fname); + break; + + case C_UNTAG: + case C_ENTAG: + case C_STRTAG: { + if (DTYPE(sp->n_type) == DT_NON + && (BTYPE(sp->n_type) == T_NULL + || BTYPE(sp->n_type) == T_STRUCT + || BTYPE(sp->n_type) == T_UNION + || BTYPE(sp->n_type) == T_ENUM)) { + printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size); + printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx); + } else { + printf(" (don't know why this tag has an auxent)"); + abort(); + } /* if I understand */ + + break; + } /* tags */ + + case C_EOS: { + if (BTYPE(sp->n_type) == DT_NON && BTYPE(sp->n_type) == T_NULL) { + printf(" tagndx %ld,", aux->x_sym.x_tagndx); + printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size); + } else { + printf(" (don't know why this eos has an auxent)"); + abort(); + } /* if I understand */ + break; + } /* eos */ + + case C_FCN: + case C_BLOCK: { + if (BTYPE(sp->n_type) == DT_NON && BTYPE(sp->n_type) == T_NULL) { + if (!strcmp(sp->n_name, ".bb") || !strcmp(sp->n_name, ".bf")) { + printf(" lnno %d", aux->x_sym.x_misc.x_lnsz.x_lnno); + printf(" endndx %ld", aux->x_sym.x_fcnary.x_fcn.x_endndx); + break; + + } else if (!strcmp(sp->n_name, ".eb") || !strcmp(sp->n_name, ".ef")) { + printf(" lnno %d", aux->x_sym.x_misc.x_lnsz.x_lnno); + break; + + } /* beginning or ending */ + } /* if I understand */ + + printf(" (don't know why this fcn or block has an auxent)"); + abort(); + break; + } /* begin/end blocks */ + + case C_LEAFEXT: + case C_LEAFSTAT: + case C_SCALL: + case C_EXT: { + assert(BTYPE(sp->n_type) != T_MOE); + + if (ISFCN(sp->n_type) + || BTYPE(sp->n_type) == T_NULL) { + dump_aux_fcn(aux); + + if (sp->n_sclass == C_SCALL) { + printf(" stindx %ld", aux2->x_sc.x_stindx); + auxcountshouldbe = 2; + } else if (sp->n_sclass == C_LEAFEXT + || sp->n_sclass == C_LEAFSTAT) { + printf(" balentry 0x%lx", aux2->x_bal.x_balntry); + auxcountshouldbe = 2; + } /* special functions */ + } else if (ISARY(sp->n_type)) { + dump_aux_array(aux); + } else if (BTYPE(sp->n_type) == T_STRUCT) { + printf(" tagndx %ld,", aux->x_sym.x_tagndx); + printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size); + } else { + assert(0); + } /* on type */ + + break; + } /* function */ + + case C_STAT: { + switch (DTYPE(sp->n_type)) { + case DT_NON: + switch (BTYPE(sp->n_type)) { + case T_NULL: /* section symbol */ + printf(" length 0x%lx, relocs %d, lnnos %d", + (unsigned long) aux->x_scn.x_scnlen, + aux->x_scn.x_nreloc, + aux->x_scn.x_nlinno); + break; + case T_STRUCT: + case T_UNION: + case T_ENUM: + dump_aux_tagmember(aux); + break; + default: + printf(" (confused)."); + abort(); + } /* switch on btype */ + break; + + case DT_FCN: /* function */ + if (BTYPE(sp->n_type) == T_MOE) { + printf(" (confused)."); + abort(); + } else { + dump_aux_fcn(aux); + } /* if I understand */ + break; + + case DT_ARY: + assert(BTYPE(sp->n_type) != T_MOE); + dump_aux_array(aux); + /* intentional fall through */ + case DT_PTR: + assert(BTYPE(sp->n_type) == T_STRUCT + || BTYPE(sp->n_type) == T_UNION + || BTYPE(sp->n_type) == T_ENUM); + dump_aux_tagmember(aux); + break; + + default: + printf(" (confused.)"); + abort(); + } /* switch on derived type */ + + break; + } /* STAT */ + + case C_AUTO: + case C_MOS: + case C_MOU: + case C_TPDEF: + if (DTYPE(sp->n_type) == DT_ARY) { + assert(BTYPE(sp->n_type) != T_MOE); + dump_aux_array(aux); + } else { + dump_aux_tagmember(aux); + } /* if an array */ + break; +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ + if (sp->n_other == N_CALLNAME) { + printf(" N_CALLNAME"); + } else if (sp->n_other == N_BALNAME) { + printf(" N_BALNAME"); + } else if (1 <= sp->n_other && sp->n_other <= 32) { + printf(" \"trap\""); + } else { + printf(" !!!invalid \"other\" field"); + } /* what is it */ +#ifndef OBJ_BOUT +#else + case C_FIELD: + printf(" tagndx %ld,", aux->x_sym.x_tagndx); + printf(" size %d,", aux->x_sym.x_misc.x_lnsz.x_size); + break; + + default: + printf(" (don't know why this symbol has aux entries.)"); + abort(); + break; + } /* switch on class */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#else + +#endif /* OBJ_BOUT */ + printf(" ]"); + } /* is defined */ +#ifndef OBJ_BOUT +#endif /* B_OUT */ +#else + if (sp->n_numaux != auxcountshouldbe) { + printf(" (expecting %d auxents here)", auxcountshouldbe); + abort(); + } /* on miscount */ + } /* do aux entries */ + + i += sp->n_numaux; + sp += sp->n_numaux; +#endif /* OBJ_COFF */ + + printf("\n"); + } /* for each symbol */ +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#else + printf("\n"); +#endif /* OBJ_COFF */ + return; +} /* dump_sym() */ +#ifndef OBJ_COFF +#else + printf("\n"); + } +} +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#else +#ifdef comment +#endif /* OBJ_COFF */ +static void dump_reloc (execp, f) +#ifndef OBJ_COFF +#else +dump_reloc (execp, f) +#endif /* OBJ_BOUT */ +struct exec *execp; +#else +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +{ +#ifndef OBJ_COFF + read_symbols (execp, f); +#else + read_symbols(execp, f); +#endif /* OBJ_COFF */ + if (execp->a_trsize) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("text reloc\n"); +#ifndef OBJ_COFF +#else + printf ("text reloc\n"); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize); + } + if (execp->a_drsize) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("data reloc\n"); +#ifndef OBJ_COFF +#else + printf ("data reloc\n"); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize); + } +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + + return; +} /* dump_reloc() */ +#ifndef OBJ_COFF +#else +} +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +static void dump_reloc1 (execp, f, off, size) +#ifndef OBJ_COFF +#else +dump_reloc1 (execp, f, off, size) +#endif /* OBJ_BOUT */ +struct exec *execp; +#else +fileheader *execp; +#endif /* OBJ_COFF */ +FILE *f; +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +int off; +int size; +#ifndef OBJ_COFF +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +{ + int nreloc; + struct relocation_info reloc; + int i; + + nreloc = size / sizeof (struct relocation_info); + +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (!omit_reloc_numbers_flag) { + printf("%3s: ", "#"); + } /* if printing numbers */ + +#ifndef sparc + printf("%3s ", "len"); +#endif /* sparc */ + + printf("%8s %4s\n", "adr", "sym"); + + + fseek(f, off, 0); +#ifndef OBJ_COFF +#else + printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym"); + fseek (f, off, 0); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + for (i = 0; i < nreloc; i++) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (fread((char *)&reloc, sizeof reloc, 1, f) != 1) { + fprintf(stderr, "%s: error reading reloc\n", +#ifndef OBJ_COFF +#else + if (fread ((char *)&reloc, sizeof reloc, 1, f) != 1) { + fprintf (stderr, "%s: error reading reloc\n", +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + program_name); + return; + } +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + + if (!omit_reloc_numbers_flag) { + printf("%3d: ", i); + } /* if printing numbers */ + +#ifndef sparc + printf("%3d ", 1 << reloc.r_length); +#endif /* sparc */ + + printf("%8lx ", (long unsigned) reloc.r_address); + +#ifndef B_OUT +#ifndef OBJ_COFF +#else + printf ("%3d: %3d %8x ", i, 1 << reloc.r_length, + reloc.r_address); + +#ifdef NOT +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + if (reloc.r_extern) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (!omit_sym_numbers_flag) { + (void) printf("%4d ", reloc.r_symbolnum); + } else { + (void) printf(" "); + } /* if printing sym numbers */ + +#ifndef OBJ_COFF +#else + printf ("%4d ", reloc.r_symbolnum); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + if (reloc.r_symbolnum < nsyms) +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("%s ", symtbl[reloc.r_symbolnum].n_un.n_name); +#ifndef OBJ_COFF +#else + printf ("%s ", + symtbl[reloc.r_symbolnum].n_un.n_name); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + } else { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf(" "); +#ifndef OBJ_COFF +#else + printf (" "); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + switch (reloc.r_symbolnum & ~N_EXT) { +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + case N_TEXT: printf(".text "); break; + case N_DATA: printf(".data "); break; + case N_BSS: printf(".bss "); break; + case N_ABS: printf(".abs "); break; + default: printf("base %x ", (unsigned) reloc.r_symbolnum); break; +#ifndef OBJ_COFF +#else + case N_TEXT: printf (".text "); break; + case N_DATA: printf (".data "); break; + case N_BSS: printf (".bss "); break; + case N_ABS: printf (".abs "); break; + default: printf ("base %x ", reloc.r_symbolnum); break; +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ + } + } +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ +#endif /* not B_OUT */ + +#ifdef SPARC + if (reloc.r_addend) printf("+0x%x ", (unsigned) reloc.r_addend); + + switch (reloc.r_type) { + case RELOC_8: printf("R8 "); break; + case RELOC_16: printf("R16 "); break; + case RELOC_32: printf("R32 "); break; + case RELOC_DISP8: printf("DISP8 "); break; + case RELOC_DISP16: printf("DISP16 "); break; + case RELOC_DISP32: printf("DISP32 "); break; + case RELOC_WDISP30: printf("WDISP30 "); break; + case RELOC_WDISP22: printf("WDISP22 "); break; + case RELOC_HI22: printf("HI22 "); break; + case RELOC_22: printf("R22 "); break; + case RELOC_13: printf("R13 "); break; + case RELOC_LO10: printf("LO10 "); break; + case RELOC_SFA_BASE: printf("SFA_BASE "); break; + case RELOC_SFA_OFF13: printf("SFA_OFF13 "); break; + case RELOC_BASE10: printf("BASE10 "); break; + case RELOC_BASE13: printf("BASE13 "); break; + case RELOC_BASE22: printf("BASE22 "); break; + case RELOC_PC10: printf("PC10 "); break; + case RELOC_PC22: printf("PC22 "); break; + case RELOC_JMP_TBL: printf("JMP_TBL "); break; + case RELOC_SEGOFF16: printf("SEGOFF16 "); break; + case RELOC_GLOB_DAT: printf("GLOB_DAT "); break; + case RELOC_JMP_SLOT: printf("JMP_SLOT "); break; + case RELOC_RELATIVE: printf("RELATIVE "); break; + } /* switch on reloc type */ +#else /* SPARC */ + if (reloc.r_pcrel) printf("PCREL "); +#endif /* SPARC */ + +#ifdef B_OUT + if (reloc.r_bsr) printf("BSR "); + if (reloc.r_disp) printf("DISP "); + if (reloc.r_callj) printf("CALLJ "); + if (reloc.nuthin) printf("NUTHIN "); +#endif /* B_OUT */ + +#ifdef SPARC + { + struct reloc_info_sparc spare; + + bzero(&spare, sizeof(spare)); + + reloc.r_address = 0; + reloc.r_index = 0; + reloc.r_extern = 0; + reloc.r_type = 0; + reloc.r_addend = 0; + + if (bcmp(&reloc, &spare, sizeof(spare))) { + printf("(garbage in spare bits) "); + } /* if garbage in spare bits */ + } /* sparc */ +#endif /* SPARC */ + +#ifndef OBJ_COFF +#else +#endif /* NOT */ + if (reloc.r_pcrel) printf ("PCREL "); + if (reloc.r_bsr) printf ("BSR "); + if (reloc.r_disp) printf ("DISP "); + if (reloc.r_callj) printf ("CALLJ "); + if (reloc.nuthin) printf ("NUTHIN "); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +#if 0 +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + if (reloc.r_pad) printf("PAD %x ", reloc.r_pad); +#ifndef OBJ_COFF +#else + if (reloc.r_pad) printf ("PAD %x ", reloc.r_pad); +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */ +#endif +#ifndef OBJ_COFF +#ifndef OBJ_BOUT +#endif /* OBJ_COFF */ + printf("\n"); + } /* for each reloc record */ + + return; +} /* dump_reloc1() */ +#ifndef OBJ_COFF +#else + printf ("\n"); + } +} +#endif /* OBJ_BOUT */ +#else +#endif /* comment */ +#endif /* OBJ_COFF */ + +/* Allocate `n' bytes of memory dynamically, with error checking. */ + +#ifndef OBJ_COFF +char * +xmalloc (n) + unsigned n; +{ + char *p; + + p = malloc (n); + if (p == 0) + { +#ifndef OBJ_BOUT + fprintf(stderr, "%s: virtual memory exhausted\n", program_name); +#else + fprintf (stderr, "%s: virtual memory exhausted\n", program_name); +#endif /* OBJ_BOUT */ + exit (1); + } +#ifndef OBJ_BOUT + bzero(p, n); +#endif /* OBJ_BOUT */ + return p; +#ifndef OBJ_BOUT +#else +static char *xmalloc (n) +unsigned n; +{ + char *p; + + p = malloc (n); + if (p == NULL) + { + fprintf(stderr, "%s: virtual memory exhausted\n", program_name); + exit (1); + } + bzero(p, n); + return p; +#endif /* OBJ_COFF */ +} /* xmalloc() */ + +#ifdef OBJ_COFF +static char *xrealloc(p, size) +char *p; +unsigned size; +{ + p = realloc(p, size); + + if (p == NULL) { + fprintf(stderr, "%s: virtual memory exhausted\n", program_name); + exit (1); + } /* on malloc failure */ + + bzero(p, size); + return(p); +} /* xrealloc() */ + +#endif /* OBJ_COFF */ +/* + * Local Variables: + * comment-column: 0 + * fill-column: 131 + * End: + */ + +/* end of objdump.c */ +#ifndef OBJ_COFF +#else +} +#endif /* OBJ_BOUT */ +#endif /* OBJ_COFF */