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.