home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
GEMini Atari
/
GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso
/
zip
/
gnu
/
utlsrc33.lzh
/
UTLSRC33
/
CNM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-30
|
7KB
|
381 lines
/* Copyright (c) 1988 by Sozobon, Limited. Author: Johann Ruegg
*
* Permission is granted to anyone to use this software for any purpose
* on any computer system, and to redistribute it freely, with the
* following restrictions:
* 1) No charge may be made other than reasonable charges for reproduction.
* 2) Modified versions must be clearly marked as such.
* 3) The authors are not responsible for any harmful consequences
* of using this software, even if they result from defects in it.
*
* Alternative ST symbol table lister.
*/
/* highly munged from above, VERY quick and dirty nm, just enough
here to find _stksize for fixstk.c and printstk.c, may be
useful for other stuff.
WARNING: -g option will not work with gcc-ld produced a.out
++jrb
*/
/*
* Modified to handle expanded, GST linker derived, format for symbols.
* This format is produced with -G flag to a proper version of gcc-ld.
* -g flag also will work if ld coached properly.
*
* --mj
*/
/*
* ++jrb rework and cleanup while adding A_TFILE A_TFARC
*/
#include <compiler.h>
#include <stdio.h>
#include <st-out.h>
#if __STDC__
#include <stdlib.h>
#else
extern char *malloc(), *realloc();
#endif
#ifdef atarist
# define READB "rb"
#else
# define READB "r"
#endif
#if !__STDC__ && !defined(hpux)
typedef unsigned long size_t;
#endif
#ifndef WORD_ALIGNED
# define SIZEOF_SYM ((size_t)sizeof(struct asym))
#else
# define SIZEOF_SYM ((size_t)14)
#endif
struct xsym {
char name[8];
union {
unsigned char _flags[2];
unsigned short _sflgs;
} u;
unsigned long value;
char tail[SIZEOF_SYM];
};
#define flags u._flags[0]
#define xflags u._flags[1]
#define sflgs u._sflgs
#ifdef __STDC__
# define P(s) s
#else
# define P(s) ()
#endif
int main P((int argc , char **argv ));
int cmp P((struct xsym *s1 , struct xsym *s2 ));
int doname P((char *s , int many ));
long dohdr P((FILE *fd ));
void dosym P((struct xsym *s ));
int not_glob P((unsigned int x ));
void sflags P((struct xsym *s ));
void ckfread P((void *buf , int siz , int n , FILE *fp ));
long readhead P((struct aexec *h , int n , FILE *fd ));
int readsyms P((struct xsym *syms , int n , FILE *fd ));
void usage P((void ));
#undef P
int gflag;
int main(argc, argv)
int argc;
char **argv;
{
int c, status = 0;
extern char *optarg;
extern int optind;
while ((c = getopt(argc, argv, "g")) != -1)
switch (c)
{
case 'g':
gflag = 1;
break;
case '?':
usage();
}
c = argc - optind;
if(c <= 0)
usage();
for (; optind < argc; optind++)
status |= doname(argv[optind], (c > 1));
return status;
}
int cmp(s1, s2)
struct xsym *s1, *s2;
{
return(s1->value - s2->value);
}
int doname(s, many)
char *s;
int many;
{
FILE *fd, *fopen();
long i, count;
if(!(fd = fopen(s, READB)))
{
perror(s);
return 2;
}
if (many)
printf("\n%s:\n", s);
if (i = dohdr(fd))
{
struct xsym *syms, *savesyms;
struct xsym *currsym;
printf("%ld slots mem %ld\n", i, (long)(i*sizeof(struct xsym)));
if((savesyms = syms = (struct xsym *)malloc(i*sizeof(struct xsym))) == NULL)
{
perror("Outa mem");
exit(4);
}
count = i;
currsym = syms;
while (count)
{
if(readsyms(currsym, 1, fd) != 1)
{
perror("reading syms");
exit(8);
}
if (--count)
{
if (A_LNAM == (currsym->xflags & A_LNAM))
{
if(fread(currsym->tail, SIZEOF_SYM, 1, fd) != 1)
{
perror("reading syms");
exit(16);
}
--i;
--count;
}
}
else /* object was partially stripped */
currsym->xflags &= ~A_LNAM;
if (gflag && not_glob((unsigned int)(currsym->flags)))
--i;
else
currsym++;
}
fclose(fd);
printf("%ld %s symbol(s)\n", i, (gflag ? "global ": ""));
qsort(syms, i, sizeof(struct xsym), cmp);
while (i--)
{
dosym(syms);
syms += 1;
}
free(savesyms);
}
return 0;
}
long dohdr(fd)
FILE *fd;
{
struct aexec h;
long i;
i = readhead(&h, 1, fd);
if (i != 1 || h.a_magic != CMAGIC)
{
fprintf(stderr, "Bad header\n");
return 0L;
}
fseek(fd, (h.a_text + h.a_data), 1);
return h.a_syms / SIZEOF_SYM;
}
void
dosym(s)
struct xsym *s;
{
printf("%-8.8s", s->name);
printf("%-14.14s", (A_LNAM == (s->xflags & A_LNAM) ? s->tail : ""));
printf("\t%8lx ", s->value);
s->xflags &= ~A_LNAM;
sflags(s);
putchar('\n');
}
char *fname[] = {
"?0?", " bss", " text", "?3?", " data",
"?5?", "?6?", "?7?"
};
char *Fname[] = {
"?0?", "Bss", "Text", "?3?", "Data",
"?5?", "?6?", "?7?"
};
int not_glob(x)
unsigned int x;
{
x &= 0xff;
if (x & 0x20)
return 0;
x &= ~0x20;
if (x == 0x88)
return 0;
return 1;
}
void
sflags(s)
struct xsym *s;
{
unsigned int x = s->flags;
char **category;
int lflag;
if(s->sflgs == A_TFILE)
printf("text file");
else if (s->sflgs == A_TFARC)
printf("text file archive");
else
{
if (0 != (lflag = not_glob(x)))
category = fname;
else
category = Fname;
x &= 0xff;
if (x & 0x20)
printf("global ");
x &= ~0x20;
if (x & 0xd8)
{
if (x & 0x08)
printf (" external");
if (x & 0x50)
{
printf (" equ");
if (x & 0x10)
printf (" reg");
}
if (x & 0x80)
printf (" abs");
if (!lflag)
printf(" G");
}
else
{
x &= 7;
printf(category[x]);
}
}
printf(" (0x%04x)",(unsigned int)(s->sflgs));
}
void ckfread(buf, siz, n, fp)
void *buf;
int siz, n;
FILE *fp;
{
if(fread(buf, siz, n, fp) != n)
{
perror("reading");
exit(32);
}
}
long readhead(h, n, fd)
struct aexec *h;
int n;
FILE *fd;
{
short i;
long j;
int k;
for(k = 0; k < n; k++)
{
ckfread(&i, 2, 1, fd);
h->a_magic = i;
ckfread(&j, 4, 1, fd);
h->a_text = j;
ckfread(&j, 4, 1, fd);
h->a_data = j;
ckfread(&j, 4, 1, fd);
h->a_bss = j;
ckfread(&j, 4, 1, fd);
h->a_syms = j;
ckfread(&j, 4, 1, fd);
h->a_AZero1 = j;
ckfread(&j, 4, 1, fd);
h->a_ldflgs = j;
ckfread(&i, 2, 1, fd);
h->a_isreloc = i;
}
return k;
}
int readsyms(syms, n, fd)
struct xsym *syms;
int n;
FILE *fd;
{
int k;
for(k = 0; k < n; k++, syms++)
{
ckfread(syms->name, 8, 1, fd);
ckfread(&(syms->sflgs), 2, 1, fd);
ckfread(&(syms->value), 4, 1, fd);
}
return k;
}
void usage()
{
fprintf(stderr, "cnm [-g] files...\n");
exit(1);
}
#if !defined(__GNUC__) && defined(hpux)
char *xmalloc(n)
int n; /* sigh! */
{
char *ret = (char *)malloc(n);
if(ret) return ret;
perror("malloc");
exit(1);
}
char *xrealloc(b, n)
char * b;
int n; /* sigh! */
{
char *ret = (char *)realloc(b, n);
if(ret) return ret;
perror("realloc");
exit(2);
}
#endif