ftp.nice.ch/pub/next/developer/objc/mach/dis.N.bs.tar.gz#/symbols.c

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.