This is symbols.c in view mode; [Download] [Up]
/* symbols.c - symbols (labels) printing and handling, NeXT disassembler.
*
* Copyright (C) 1989 by Bill Spitzak
* See Copyright notice in makefile
*
* See also symtab.c for the routines which sort symbols.
*/
/* $Log: symbols.c,v $
* Revision 1.7 94/05/31 22:12:25 ediger
* use bsearch() to do lookups.
*
* Revision 1.6 94/05/30 23:06:55 ediger
* clarity, cut, color
*
* Revision 1.5 94/01/25 23:37:57 ediger
* cleanup, reformatting removal of "magic" non-symbolic constants
*
* Revision 1.4 94/01/19 00:12:06 ediger
* bug fixes, reformatting
*
* Revision 1.3 94/01/16 21:11:03 ediger
* fixed bug in parameters sent to disasmblock()
*
* Revision 1.2 94/01/16 17:17:48 ediger
* ditched phony nlist struct def
*
* Revision 1.1 94/01/16 16:48:29 ediger
* Initial revision
* */
static char rcsident[] = "$Id: symbols.c,v 1.7 94/05/31 22:12:25 ediger Exp Locker: ediger $";
#include "dis.h"
struct nlist *sourcesymtab = NULL;
char *symnametable = NULL;
/* fwd declarations */
void printstab(struct nlist *);
struct nte {
unsigned char symbol_type;
char *symbol;
};
/* SORTED symbol type to name table - for use with bsearch() library routine */
static struct nte nametable[] = {
{N_UNDF, "N_UNDF"},
{N_ABS, "N_ABS"},
{N_INDR, "N_INDR"},
{N_SECT, "N_SECT"},
{N_GSYM, "N_GSYM"},
{N_FNAME, "N_FNAME"},
{N_FUN, "N_FUN"},
{N_STSYM, "N_STSYM"},
{N_LCSYM, "N_LCSYM"},
{N_PC, "N_PC"},
{N_RSYM, "N_RSYM"},
{N_SLINE, "N_SLINE"},
{N_SSYM, "N_SSYM"},
{N_SO, "N_SO"},
{N_LSYM, "N_LSYM"},
{N_SOL, "N_SOL"},
{N_PSYM, "N_PSYM"},
{N_ENTRY, "N_ENTRY"},
{N_LBRAC, "N_LBRAC"},
{N_RBRAC, "N_RBRAC"},
{N_BCOMM, "N_BCOMM"},
{N_ECOMM, "N_ECOMM"},
{N_ECOML, "N_ECOML"},
{N_LENG, "N_LENG"},
};
/*
* compares two struct nte entries: for use with bsearch(3)
*/
static int
cmp(struct nte *a, struct nte *b)
{
if (a->symbol_type > b->symbol_type)
return 1;
if (a->symbol_type < b->symbol_type)
return -1;
return 0;
}
/* Print an assembler directive that will produce an arbitrary symbol
* table entry. This is printed when we don't know anything better
* to do with a symbol.
*/
void
printstab(struct nlist * s)
{
struct nte *n, dummy;
sprint(s->n_sect ? ".stabd " : ".stabs ");
if (s->n_un.n_name)
fprint("\"%s\",", s->n_un.n_name);
else
sprint("0,");
dummy.symbol_type = (s->n_type & (~N_EXT));
n = bsearch((void *)&dummy, (void *)nametable,
sizeof(nametable)/sizeof(struct nte),
sizeof(struct nte),
(int (*)(const void *, const void *))cmp);
if (n->symbol != NULL)
{
sprint(n->symbol);
if (s->n_type & N_EXT)
sprint("+N_EXT");
} else
fprint("0x%2x", s->n_type);
fprint(",%d", s->n_desc);
if (!s->n_sect)
fprint(",%d", s->n_value);
}
/* Print a line containing a symbol. If the symbol could properly be
* imbedded in a tab before disassembled code, return TRUE. Otherwise
* return false to force the disassembler to start a new line after it.
*/
int
printsymbol(struct nlist *s)
{
extern char *symnametable;
extern flag noextern;
if (noextern && s->n_type == (N_UNDF | 1) && (s->n_value == 0))
return (FALSE);
if (s->n_sect)
startline(s->n_value);
else
startlinenoaddress();
switch (s->n_type & (~N_EXT))
{
case N_UNDF:
if (s->n_value)
fprint(".comm %s, %d", s->n_un.n_name, s->n_value);
else
fprint(".globl %s", s->n_un.n_name);
break;
case N_ABS:
if (s->n_type & 1)
sprint(".globl ");
fprint("%s = %x", s->n_un.n_name, s->n_value);
break;
case N_INDR:
if (s->n_type & 1)
{
fprint(".globl %s", s->n_un.n_name);
startlinenoaddress();
}
fprint("%s = %s", s->n_un.n_name, symnametable + s->n_value);
break;
case N_SECT:
if (s->n_type & 1)
{
fprint(".globl %s", s->n_un.n_name);
startline(s->n_value);
}
fprint(s->n_un.n_name ? s->n_un.n_name : "D%x", s->n_value);
cprint(':');
return (!s->n_un.n_name || strlen(s->n_un.n_name) < 7);
break;
case N_SLINE:
fprint("| line %d", s->n_desc);
break;
case N_SO:
fprint("| source file \"%s\"", s->n_un.n_name);
break;
case N_SOL:
fprint("| include file \"%s\"", s->n_un.n_name);
break;
default:
printstab(s);
break;
}
return (FALSE);
}
/* This is the usual method to create a disassembly symbol. For
* now it is unlikely we will produce any other types of symbols
* than these static labels. Make sure the name is in static storage!
*/
struct nlist *
createlabel(unsigned address, unsigned sn, unsigned type, char *name)
{
struct nlist *s;
s = malloc(sizeof(struct nlist));
s->n_un.n_name = name;
s->n_type = N_SECT;
if (sn == 0)
sn = 1;
s->n_sect = sn;
s->n_desc = type;
s->n_value = address;
addsymbol(s);
return (s);
}
/* load the symbol table */
void
load_symbol_table(char *map, struct symtab_command *p, int sectn)
{
struct nlist *n;
int j;
assert(map != NULL);
assert(p != NULL);
sourcesymtab = (struct nlist *)(map + p->symoff);
symnametable = map + p->stroff;
printf("| section %d: %d symbols\n", sectn, p->nsyms);
for (n = sourcesymtab, j = p->nsyms; j > 0; j--, n++)
{
if (n->n_un.n_strx)
n->n_un.n_name = symnametable + n->n_un.n_strx;
if ((n->n_type & (~N_EXT)) == N_ABS && (n->n_sect == NO_SECT))
n->n_sect = sectn + 1;
addsymbol(n);
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.