diff options
Diffstat (limited to 'gas/objdump.c')
-rwxr-xr-x | gas/objdump.c | 2232 |
1 files changed, 2232 insertions, 0 deletions
diff --git a/gas/objdump.c b/gas/objdump.c new file mode 100755 index 0000000..20ad39e --- /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 <stdio.h> +#include <assert.h> + +#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 = "<bad string table index>"; + 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 */ |