|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T o
Length: 6749 (0x1a5d) Types: TextFile Names: »objdump.c«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦4ef0278ca⟧ »./binutils.tar.Z« └─⟦3761b9c35⟧ └─⟦this⟧ »binutils/objdump.c«
/* dump information about an object file. Copyright (C) 1988, 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. */ /* * 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 "getopt.h" #ifndef COFF_ENCAPSULATE #include "a.out.gnu.h" #else #include "a.out.encap.h" #endif char *malloc(); int nsyms; struct nlist *symtbl; char *strtbl; int strsize; read_symbols (execp, f) struct exec *execp; FILE *f; { int i; struct nlist *sp; if (symtbl) return; nsyms = execp->a_syms / sizeof (struct nlist); if (nsyms == 0) return; symtbl = (struct nlist *)malloc (nsyms * sizeof (struct nlist)); if (symtbl == NULL) { fprintf (stderr, "can't malloc for %d symbols\n", nsyms); exit (1); } fseek (f, N_STROFF(*execp), 0); if (fread ((char *)&strsize, sizeof strsize, 1, f) != 1) { fprintf (stderr, "can't get string table size\n"); exit (1); } strtbl = malloc (strsize); if (strtbl == NULL) { fprintf (stderr, "can't malloc %d bytes for string table\n"); exit (1); } fseek (f, N_STROFF (*execp), 0); if (fread (strtbl, 1, strsize, f) != strsize) { fprintf (stderr, "error reading string table\n"); exit (1); } fseek (f, N_SYMOFF (*execp), 0); if (fread ((char *)symtbl, sizeof (struct nlist), nsyms, f) != nsyms) { fprintf (stderr, "error reading symbol table\n"); exit (1); } 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; } } free_symbols () { if (symtbl) free (symtbl); symtbl = NULL; if (strtbl) free (strtbl); strtbl = NULL; } usage () { fprintf (stderr, "usage: dump [-h] [-n] [-r] [-t] obj ...\n"); exit (1); } int hflag; int nflag; int rflag; int tflag; main (argc, argv) char **argv; { int c; extern char *optarg; extern int optind; int seenflag = 0; int ind = 0; struct option long_options[] = {{"syms", 0, &tflag, 1}, {"reloc", 0, &rflag, 1}, {"nstuff", 0, &nflag, 1}, {"header", 0, &hflag, 1}}; while ((c = getopt_long (argc, argv, "hnrt", long_options, &ind)) != EOF) { seenflag = 1; switch (c) { case 0 : break; /* we've been given a long option */ case 't': tflag = 1; break; case 'r': rflag = 1; break; case 'n': nflag = 1; break; case 'h': hflag = 1; break; default: usage (); } } if (seenflag == 0 || optind == argc) usage (); while (optind < argc) doit (argv[optind++]); } doit (name) char *name; { FILE *f; struct exec exec; printf ("%s:\n", name); f = fopen (name, "r"); if (f == NULL) { fprintf (stderr, "can't open %s\n", name); return; } #ifdef HEADER_SEEK HEADER_SEEK (f); #endif if (fread ((char *)&exec, sizeof exec, 1, f) != 1) { fprintf (stderr, "can't read header for %s\n", name); return; } if (N_BADMAG (exec)) { fprintf (stderr, "%s is not an object file\n", name); return; } if (hflag) dump_header (&exec); if (nflag) dump_nstuff (&exec); if (tflag) dump_sym (&exec, f); if (rflag) dump_reloc (&exec, f); free_symbols (); } dump_header (execp) struct exec *execp; { int x; #ifdef __GNU_EXEC_MACROS__ printf ("info: 0x%x (magic %o)\n", execp->a_info, N_MAGIC(*execp)); #else printf ("magic: 0x%x (%o) ", execp->a_magic, execp->a_magic); #endif 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); if (x) printf (" (+ %d bytes)", x); printf (" entry 0x%x ", execp->a_entry); printf ("trsize 0x%x ", execp->a_trsize); printf ("drsize 0x%x\n", execp->a_drsize); } dump_nstuff (execp) struct exec *execp; { 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)); } dump_sym (execp, f) struct exec *execp; FILE *f; { int i; struct nlist *sp; read_symbols (execp, f); if (nsyms == 0) { printf ("no symbols\n"); return; } printf ("%3s: %4s %5s %4s %8s\n", "#", "type", "other", "desc", "val"); for (i = 0, sp = symtbl; i < nsyms; i++, sp++) { printf ("%3d: %4x %5x %4x %8x %s\n", i, sp->n_type & 0xff, sp->n_other & 0xff, sp->n_desc & 0xffff, sp->n_value, sp->n_un.n_name); } } dump_reloc (execp, f) struct exec *execp; FILE *f; { read_symbols (execp, f); if (execp->a_trsize) { printf ("text reloc\n"); dump_reloc1 (execp, f, N_TRELOFF (*execp), execp->a_trsize); } if (execp->a_drsize) { printf ("data reloc\n"); dump_reloc1 (execp, f, N_DRELOFF (*execp), execp->a_drsize); } } dump_reloc1 (execp, f, off, size) struct exec *execp; FILE *f; { int nreloc; struct relocation_info reloc; int i; nreloc = size / sizeof (struct relocation_info); printf ("%3s: %3s %8s %4s\n", "#", "len", "adr", "sym"); fseek (f, off, 0); for (i = 0; i < nreloc; i++) { if (fread ((char *)&reloc, sizeof reloc, 1, f) != 1) { fprintf (stderr, "error reading reloc\n"); return; } printf ("%3d: %3d %8x ", i, 1 << reloc.r_length, reloc.r_address); if (reloc.r_extern) { printf ("%4d ", reloc.r_symbolnum); if (reloc.r_symbolnum < nsyms) printf ("%s ", symtbl[reloc.r_symbolnum].n_un.n_name); } else { printf (" "); switch (reloc.r_symbolnum & ~N_EXT) { 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; } } if (reloc.r_pcrel) printf ("PCREL "); #if 0 if (reloc.r_pad) printf ("PAD %x ", reloc.r_pad); #endif printf ("\n"); } }