130855Sbostic /* 239109Sbostic * Copyright (c) 1989 The Regents of the University of California. 339109Sbostic * All rights reserved. 439109Sbostic * 539109Sbostic * This code is derived from software contributed to Berkeley by 639109Sbostic * Hans Huebner. 739109Sbostic * 839109Sbostic * Redistribution and use in source and binary forms are permitted 939109Sbostic * provided that the above copyright notice and this paragraph are 1039109Sbostic * duplicated in all such forms and that any documentation, 1139109Sbostic * advertising materials, and other materials related to such 1239109Sbostic * distribution and use acknowledge that the software was developed 1339109Sbostic * by the University of California, Berkeley. The name of the 1439109Sbostic * University may not be used to endorse or promote products derived 1539109Sbostic * from this software without specific prior written permission. 1639109Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1739109Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1839109Sbostic * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1930855Sbostic */ 2030855Sbostic 2112672Ssam #ifndef lint 2239109Sbostic char copyright[] = 2339109Sbostic "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 2439109Sbostic All rights reserved.\n"; 2539109Sbostic #endif /* not lint */ 2630855Sbostic 2739109Sbostic #ifndef lint 28*39143Sbostic static char sccsid[] = "@(#)nm.c 5.2 (Berkeley) 09/13/89"; 2939109Sbostic #endif /* not lint */ 3030855Sbostic 31619Sbill #include <sys/types.h> 32653Sbill #include <a.out.h> 33619Sbill #include <stab.h> 3439109Sbostic #include <ar.h> 3530855Sbostic #include <ranlib.h> 3639109Sbostic #include <unistd.h> 3739109Sbostic #include <errno.h> 3839109Sbostic #include <ctype.h> 3939109Sbostic #include <stdio.h> 4039109Sbostic #include <strings.h> 41619Sbill 4239109Sbostic int ignore_bad_archive_entries = 1; 4339109Sbostic int print_only_external_symbols; 4439109Sbostic int print_only_undefined_symbols; 4539109Sbostic int print_all_symbols; 4639109Sbostic int print_file_each_line; 4739109Sbostic int cmp_value(), cmp_name(); 4839109Sbostic int (*sort_func)() = cmp_name; 49619Sbill 5039109Sbostic enum { FORWARD, BACKWARD } sort_direction = FORWARD; 5139109Sbostic int fcount; 5230855Sbostic 5339109Sbostic /* some macros for symbol type (nlist.n_type) handling */ 5439109Sbostic #define IS_DEBUGGER_SYMBOL(x) ((x) & N_STAB) 5539109Sbostic #define IS_EXTERNAL(x) ((x) & N_EXT) 5639109Sbostic #define SYMBOL_TYPE(x) ((x) & (N_TYPE | N_STAB)) 5730855Sbostic 5839109Sbostic /* 5939109Sbostic * main() 6039109Sbostic * parse command line, execute process_file() for each file 6139109Sbostic * specified on the command line. 6239109Sbostic */ 63619Sbill main(argc, argv) 6439109Sbostic int argc; 6539109Sbostic char **argv; 66619Sbill { 6739109Sbostic extern int optind; 6839109Sbostic int ch, errors; 69619Sbill 7039109Sbostic while ((ch = getopt(argc, argv, "agnopruw")) != EOF) { 7139109Sbostic switch (ch) { 7230855Sbostic case 'a': 7339109Sbostic print_all_symbols = 1; 7430855Sbostic break; 7530855Sbostic case 'g': 7639109Sbostic print_only_external_symbols = 1; 7730855Sbostic break; 78619Sbill case 'n': 7939109Sbostic sort_func = cmp_value; 8030855Sbostic break; 8130855Sbostic case 'o': 8239109Sbostic print_file_each_line = 1; 8330855Sbostic break; 8430855Sbostic case 'p': 8539109Sbostic sort_func = NULL; 8630855Sbostic break; 87619Sbill case 'r': 8839109Sbostic sort_direction = BACKWARD; 8930855Sbostic break; 9030855Sbostic case 'u': 9139109Sbostic print_only_undefined_symbols = 1; 9230855Sbostic break; 9339109Sbostic case 'w': 9439109Sbostic ignore_bad_archive_entries = 0; 9539109Sbostic break; 9630855Sbostic case '?': 97619Sbill default: 9839109Sbostic usage(); 99619Sbill } 10039109Sbostic } 10139109Sbostic fcount = argc - optind; 10230855Sbostic argv += optind; 10339109Sbostic 10439109Sbostic if (!fcount) 10539109Sbostic errors = process_file("a.out"); 10639109Sbostic else { 10739109Sbostic errors = 0; 10839109Sbostic do { 10939109Sbostic errors |= process_file(*argv); 11039109Sbostic } while (*++argv); 111619Sbill } 11239109Sbostic exit(errors); 113619Sbill } 114619Sbill 11539109Sbostic /* 11639109Sbostic * process_file() 11739109Sbostic * show symbols in the file given as an argument. Accepts archive and 11839109Sbostic * object files as input. 11939109Sbostic */ 12039109Sbostic process_file(fname) 12139109Sbostic char *fname; 122619Sbill { 12339109Sbostic struct exec exec_head; 12439109Sbostic FILE *fp; 12539109Sbostic int retval; 12639109Sbostic char magic[SARMAG]; 12739109Sbostic 12839109Sbostic if (!(fp = fopen(fname, "r"))) { 12939109Sbostic (void)fprintf(stderr, "nm: cannot read %s.\n", fname); 13039109Sbostic return(1); 13139109Sbostic } 132619Sbill 13339109Sbostic if (fcount > 1) 13439109Sbostic (void)printf("\n%s:\n", fname); 13539109Sbostic 13630855Sbostic /* 13739109Sbostic * first check whether this is an object file - read a object 13839109Sbostic * header, and skip back to the beginning 13930855Sbostic */ 14039109Sbostic if (fread((char *)&exec_head, 1, sizeof(exec_head), fp) != 14139109Sbostic sizeof(exec_head)) { 14239109Sbostic (void)fprintf(stderr, "nm: %s: bad format.\n", fname); 14339109Sbostic (void)fclose(fp); 14439109Sbostic return(1); 145619Sbill } 14639109Sbostic rewind(fp); 14739109Sbostic 14839109Sbostic /* this could be an archive */ 14939109Sbostic if (N_BADMAG(exec_head)) { 15039109Sbostic if (fread(magic, 1, sizeof(magic), fp) != sizeof(magic) || 15139109Sbostic strncmp(magic, ARMAG, SARMAG)) { 15239109Sbostic (void)fprintf(stderr, 15339109Sbostic "nm: %s: not object file or archive.\n", fname); 15439109Sbostic (void)fclose(fp); 15539109Sbostic return(1); 15630855Sbostic } 15739109Sbostic retval = show_archive(fname, fp); 15839109Sbostic } else 15939109Sbostic retval = show_objfile(fname, fp); 16039109Sbostic (void)fclose(fp); 16139109Sbostic return(retval); 16239109Sbostic } 16339109Sbostic 16439109Sbostic /* 16539109Sbostic * show_archive() 16639109Sbostic * show symbols in the given archive file 16739109Sbostic */ 16839109Sbostic show_archive(fname, fp) 16939109Sbostic char *fname; 17039109Sbostic FILE *fp; 17139109Sbostic { 17239109Sbostic extern int errno; 17339109Sbostic struct ar_hdr ar_head; 17439109Sbostic struct exec exec_head; 17539109Sbostic off_t esize; 17639109Sbostic int i, last_ar_off, rval; 17739109Sbostic char *p, *name, *emalloc(); 17839109Sbostic long atol(); 17939109Sbostic 18039109Sbostic name = emalloc((u_int)(sizeof(ar_head.ar_name) + strlen(fname) + 3)); 18139109Sbostic 18239109Sbostic rval = 0; 18339109Sbostic 18439109Sbostic /* while there are more entries in the archive */ 18539109Sbostic while (fread((char *)&ar_head, 1, sizeof(ar_head), fp) == 18639109Sbostic sizeof(ar_head)) { 18739109Sbostic /* bad archive entry - stop processing this archive */ 18839109Sbostic if (strncmp(ar_head.ar_fmag, ARFMAG, sizeof(ar_head.ar_fmag))) { 18939109Sbostic (void)fprintf(stderr, 19039109Sbostic "nm: %s: bad format archive header", fname); 19139109Sbostic (void)free(name); 19239109Sbostic return(1); 19339109Sbostic } 19439109Sbostic 19530855Sbostic /* 196*39143Sbostic * construct a name of the form "archive.a:obj.o:" for the 19739109Sbostic * current archive entry if the object name is to be printed 19839109Sbostic * on each output line 19930855Sbostic */ 20039109Sbostic if (print_file_each_line) { 201*39143Sbostic (void)sprintf(name, "%s:", fname); 20239109Sbostic p = name + strlen(name); 20339109Sbostic } else 20439109Sbostic p = name; 20539109Sbostic for (i = 0; i < sizeof(ar_head.ar_name); ++i) 20639109Sbostic if (ar_head.ar_name[i] && ar_head.ar_name[i] != ' ') 20739109Sbostic *p++ = ar_head.ar_name[i]; 20839109Sbostic *p++ = '\0'; 20930855Sbostic 21039109Sbostic /* remember start position of current archive object */ 21139109Sbostic last_ar_off = ftell(fp); 21230855Sbostic 21339109Sbostic /* get and check current object's header */ 21439109Sbostic if (fread((char *)&exec_head, 1, sizeof(exec_head), fp) != 21539109Sbostic sizeof(exec_head)) { 21639109Sbostic (void)fprintf(stderr, "nm: %s: premature EOF.\n", name); 21739109Sbostic (void)free(name); 21839109Sbostic return(1); 219619Sbill } 22039109Sbostic if (strcmp(name, RANLIBMAG)) 22139109Sbostic if (N_BADMAG(exec_head)) { 22239109Sbostic if (!ignore_bad_archive_entries) { 22339109Sbostic (void)fprintf(stderr, 22439109Sbostic "nm: %s: bad format.\n", name); 22539109Sbostic rval = 1; 22639109Sbostic } 22739109Sbostic } else { 22839109Sbostic (void)fseek(fp, (long)-sizeof(exec_head), 22939109Sbostic SEEK_CUR); 23039109Sbostic if (!print_file_each_line) 23139109Sbostic (void)printf("\n%s:\n", name); 23239109Sbostic rval |= show_objfile(name, fp); 23339109Sbostic } 23439109Sbostic esize = atol(ar_head.ar_size); 23530855Sbostic 23639109Sbostic /* 23739109Sbostic * skip to next archive object - esize&1 is added to stay 23839109Sbostic * on even starting points relative to the start of the 23939109Sbostic * archive file 24039109Sbostic */ 24139109Sbostic if (fseek(fp, (long)(last_ar_off + esize + (esize&1)), 24239109Sbostic SEEK_SET)) { 24339109Sbostic (void)fprintf(stderr, 24439109Sbostic "nm: %s: %s\n", fname, strerror(errno)); 24539109Sbostic (void)free(name); 24639109Sbostic return(1); 24730855Sbostic } 24839109Sbostic } 24939109Sbostic (void)free(name); 25039109Sbostic return(rval); 25139109Sbostic } 25230855Sbostic 25339109Sbostic /* 25439109Sbostic * show_objfile() 25539109Sbostic * show symbols from the object file pointed to by fp. The current 25639109Sbostic * file pointer for fp is expected to be at the beginning of an a.out 25739109Sbostic * header. 25839109Sbostic */ 25939109Sbostic show_objfile(objname, fp) 26039109Sbostic char *objname; 26139109Sbostic FILE *fp; 26239109Sbostic { 26339109Sbostic register struct nlist *names; 26439109Sbostic register int i, nnames, nrawnames; 26539109Sbostic struct exec head; 26639109Sbostic long stabsize; 26739109Sbostic char *stab, *emalloc(); 26839109Sbostic 26939109Sbostic /* read a.out header */ 27039109Sbostic if (fread((char *)&head, sizeof(head), 1, fp) != 1) { 27139109Sbostic (void)fprintf(stderr, 27239109Sbostic "nm: %s: cannot read header.\n", objname); 27339109Sbostic return(1); 27439109Sbostic } 27539109Sbostic 27639109Sbostic /* 27739109Sbostic * skip back to the header - the N_-macros return values relative 27839109Sbostic * to the beginning of the a.out header 27939109Sbostic */ 28039109Sbostic if (fseek(fp, (long)-sizeof(head), SEEK_CUR)) { 28139109Sbostic (void)fprintf(stderr, 28239109Sbostic "nm: %s: %s\n", objname, strerror(errno)); 28339109Sbostic return(1); 28439109Sbostic } 28539109Sbostic 28639109Sbostic /* stop if this is no valid object file */ 28739109Sbostic if (N_BADMAG(head)) { 28839109Sbostic (void)fprintf(stderr, 28939109Sbostic "nm: %s: bad format.\n", objname); 29039109Sbostic return(1); 29139109Sbostic } 29239109Sbostic 29339109Sbostic /* stop if the object file contains no symbol table */ 29439109Sbostic if (!head.a_syms) { 29539109Sbostic (void)fprintf(stderr, 29639109Sbostic "nm: %s: no name list.\n", objname); 29739109Sbostic return(1); 29839109Sbostic } 29939109Sbostic 30039109Sbostic if (fseek(fp, (long)N_SYMOFF(head), SEEK_CUR)) { 30139109Sbostic (void)fprintf(stderr, 30239109Sbostic "nm: %s: %s\n", objname, strerror(errno)); 30339109Sbostic return(1); 30439109Sbostic } 30539109Sbostic 30639109Sbostic /* get memory for the symbol table */ 30739109Sbostic names = (struct nlist *)emalloc((u_int)head.a_syms); 30839109Sbostic nrawnames = head.a_syms / sizeof(*names); 30939109Sbostic if (fread((char *)names, 1, (int)head.a_syms, fp) != head.a_syms) { 31039109Sbostic (void)fprintf(stderr, 31139109Sbostic "nm: %s: cannot read symbol table.\n", objname); 31239109Sbostic (void)free((char *)names); 31339109Sbostic return(1); 31439109Sbostic } 31539109Sbostic 31639109Sbostic /* 31739109Sbostic * Following the symbol table comes the string table. The first 31839109Sbostic * 4-byte-integer gives the total size of the string table 31939109Sbostic * _including_ the size specification itself. 32039109Sbostic */ 32139109Sbostic if (fread((char *)&stabsize, sizeof(stabsize), 1, fp) != 1) { 32239109Sbostic (void)fprintf(stderr, 32339109Sbostic "nm: %s: cannot read stab size.\n", objname); 32439109Sbostic (void)free((char *)names); 32539109Sbostic return(1); 32639109Sbostic } 32739109Sbostic stab = emalloc((u_int)stabsize); 32839109Sbostic 32939109Sbostic /* 33039109Sbostic * read the string table offset by 4 - all indices into the string 33139109Sbostic * table include the size specification. 33239109Sbostic */ 333*39143Sbostic stabsize -= 4; /* we already have the size */ 33439109Sbostic if (fread(stab + 4, 1, (int)stabsize, fp) != stabsize) { 33539109Sbostic (void)fprintf(stderr, 33639109Sbostic "nm: %s: stab truncated..\n", objname); 33739109Sbostic (void)free((char *)names); 33839109Sbostic (void)free(stab); 33939109Sbostic return(1); 34039109Sbostic } 34139109Sbostic 34239109Sbostic /* 34339109Sbostic * fix up the symbol table and filter out unwanted entries 34439109Sbostic * 34539109Sbostic * common symbols are characterized by a n_type of N_UNDF and a 34639109Sbostic * non-zero n_value -- change n_type to N_COMM for all such 34739109Sbostic * symbols to make life easier later. 34839109Sbostic * 34939109Sbostic * filter out all entries which we don't want to print anyway 35039109Sbostic */ 35139109Sbostic for (i = nnames = 0; i < nrawnames; ++i) { 35239109Sbostic if (SYMBOL_TYPE(names[i].n_type) == N_UNDF && names[i].n_value) 35339109Sbostic names[i].n_type = N_COMM | (names[i].n_type & N_EXT); 35439109Sbostic if (!print_all_symbols && IS_DEBUGGER_SYMBOL(names[i].n_type)) 35530855Sbostic continue; 35639109Sbostic if (print_only_external_symbols && 35739109Sbostic !IS_EXTERNAL(names[i].n_type)) 358619Sbill continue; 35939109Sbostic if (print_only_undefined_symbols && 36039109Sbostic (SYMBOL_TYPE(names[i].n_type) != N_UNDF)) 36139109Sbostic continue; 36230855Sbostic 36339109Sbostic /* 36439109Sbostic * make n_un.n_name a character pointer by adding the string 36539109Sbostic * table's base to n_un.n_strx 36639109Sbostic * 36739109Sbostic * don't mess with null offsets 36839109Sbostic */ 36939109Sbostic if (names[i].n_un.n_name) 37039109Sbostic names[i].n_un.n_name = stab + names[i].n_un.n_strx; 37139109Sbostic else 37239109Sbostic names[i].n_un.n_name = ""; 37339109Sbostic if (nnames != i) 37439109Sbostic names[nnames] = names[i]; 37539109Sbostic ++nnames; 37639109Sbostic } 37730855Sbostic 37839109Sbostic /* sort the symbol table if applicable */ 37939109Sbostic if (sort_func) 38039109Sbostic qsort((char *)names, (int)nnames, sizeof(*names), sort_func); 38130855Sbostic 38239109Sbostic /* print out symbols */ 38339109Sbostic for (i = 0; i < nnames; ++i) 38439109Sbostic print_symbol(objname, &names[i]); 38530855Sbostic 38639109Sbostic (void)free((char *)names); 38739109Sbostic (void)free(stab); 38839109Sbostic return(0); 389619Sbill } 390619Sbill 39139109Sbostic /* 39239109Sbostic * print_symbol() 39339109Sbostic * show one symbol 39439109Sbostic */ 39539109Sbostic print_symbol(objname, sym) 39639109Sbostic char *objname; 39739109Sbostic struct nlist *sym; 398619Sbill { 39939109Sbostic char *typestring(), typeletter(); 400619Sbill 40139109Sbostic if (print_file_each_line) 402*39143Sbostic printf("%s:", objname); 40339109Sbostic 40439109Sbostic /* 40539109Sbostic * handle undefined-only format seperately (no space is 40639109Sbostic * left for symbol values, no type field is printed) 40739109Sbostic */ 40839109Sbostic if (print_only_undefined_symbols) { 40939109Sbostic printf("%s\n", sym->n_un.n_name); 41039109Sbostic return; 411619Sbill } 41239109Sbostic 41339109Sbostic /* print symbol's value */ 41439109Sbostic if (SYMBOL_TYPE(sym->n_type) == N_UNDF) 41539109Sbostic (void)printf(" "); 41639109Sbostic else 41739109Sbostic (void)printf("%08lx", sym->n_value); 41839109Sbostic 41939109Sbostic /* print type information */ 42039109Sbostic if (IS_DEBUGGER_SYMBOL(sym->n_type)) 42139109Sbostic (void)printf(" - %02x %04x %5s ", sym->n_other, 42239109Sbostic sym->n_desc&0xffff, typestring(sym->n_type)); 42339109Sbostic else 42439109Sbostic (void)printf(" %c ", typeletter(sym->n_type)); 42539109Sbostic 42639109Sbostic /* print the symbol's name */ 42739109Sbostic (void)printf("%s\n", sym->n_un.n_name ? sym->n_un.n_name : ""); 428619Sbill } 429619Sbill 43039109Sbostic /* 43139109Sbostic * typestring() 43239109Sbostic * return the a description string for an STAB entry 43339109Sbostic */ 43439109Sbostic char * 43539109Sbostic typestring(type) 43639109Sbostic register u_char type; 437619Sbill { 43839109Sbostic switch(type) { 43939109Sbostic case N_BCOMM: 44039109Sbostic return("BCOMM"); 44139109Sbostic case N_ECOML: 44239109Sbostic return("ECOML"); 44339109Sbostic case N_ECOMM: 44439109Sbostic return("ECOMM"); 44539109Sbostic case N_ENTRY: 44639109Sbostic return("ENTRY"); 44739109Sbostic case N_FNAME: 44839109Sbostic return("FNAME"); 44939109Sbostic case N_FUN: 45039109Sbostic return("FUN"); 45139109Sbostic case N_GSYM: 45239109Sbostic return("GSYM"); 45339109Sbostic case N_LBRAC: 45439109Sbostic return("LBRAC"); 45539109Sbostic case N_LCSYM: 45639109Sbostic return("LCSYM"); 45739109Sbostic case N_LENG: 45839109Sbostic return("LENG"); 45939109Sbostic case N_LSYM: 46039109Sbostic return("LSYM"); 46139109Sbostic case N_PC: 46239109Sbostic return("PC"); 46339109Sbostic case N_PSYM: 46439109Sbostic return("PSYM"); 46539109Sbostic case N_RBRAC: 46639109Sbostic return("RBRAC"); 46739109Sbostic case N_RSYM: 46839109Sbostic return("RSYM"); 46939109Sbostic case N_SLINE: 47039109Sbostic return("SLINE"); 47139109Sbostic case N_SO: 47239109Sbostic return("SO"); 47339109Sbostic case N_SOL: 47439109Sbostic return("SOL"); 47539109Sbostic case N_SSYM: 47639109Sbostic return("SSYM"); 47739109Sbostic case N_STSYM: 47839109Sbostic return("STSYM"); 479619Sbill } 48039109Sbostic return("???"); 481619Sbill } 482619Sbill 48339109Sbostic /* 48439109Sbostic * typeletter() 48539109Sbostic * return a description letter for the given basic type code of an 48639109Sbostic * symbol table entry. The return value will be upper case for 48739109Sbostic * external, lower case for internal symbols. 48839109Sbostic */ 48939109Sbostic char 49039109Sbostic typeletter(type) 49139109Sbostic u_char type; 492619Sbill { 49339109Sbostic switch(SYMBOL_TYPE(type)) { 49439109Sbostic case N_ABS: 49539109Sbostic return(IS_EXTERNAL(type) ? 'A' : 'a'); 49639109Sbostic case N_BSS: 49739109Sbostic return(IS_EXTERNAL(type) ? 'B' : 'b'); 49839109Sbostic case N_COMM: 49939109Sbostic return(IS_EXTERNAL(type) ? 'C' : 'c'); 50039109Sbostic case N_DATA: 50139109Sbostic return(IS_EXTERNAL(type) ? 'D' : 'd'); 50239109Sbostic case N_FN: 50339109Sbostic return(IS_EXTERNAL(type) ? 'F' : 'f'); 50439109Sbostic case N_TEXT: 50539109Sbostic return(IS_EXTERNAL(type) ? 'T' : 't'); 50639109Sbostic case N_UNDF: 50739109Sbostic return(IS_EXTERNAL(type) ? 'U' : 'u'); 50839109Sbostic } 50939109Sbostic return('?'); 51039109Sbostic } 511619Sbill 51239109Sbostic /* 51339109Sbostic * cmp_name() 51439109Sbostic * compare two symbols by their names 51539109Sbostic */ 51639109Sbostic cmp_name(a, b) 51739109Sbostic struct nlist *a, *b; 51839109Sbostic { 51939109Sbostic return(sort_direction == FORWARD ? 52039109Sbostic strcmp(a->n_un.n_name, b->n_un.n_name) : 52139109Sbostic strcmp(b->n_un.n_name, a->n_un.n_name)); 522619Sbill } 523619Sbill 52439109Sbostic /* 52539109Sbostic * cmp_value() 52639109Sbostic * compare two symbols by their values 52739109Sbostic */ 52839109Sbostic cmp_value(a, b) 52939109Sbostic struct nlist *a, *b; 53039109Sbostic { 53139109Sbostic if (SYMBOL_TYPE(a->n_type) == N_UNDF) 53239109Sbostic if (SYMBOL_TYPE(b->n_type) == N_UNDF) 53339109Sbostic return(0); 53439109Sbostic else 53539109Sbostic return(-1); 53639109Sbostic else if (SYMBOL_TYPE(b->n_type) == N_UNDF) 53739109Sbostic return(1); 53839109Sbostic if (a->n_value == b->n_value) 53939109Sbostic return(cmp_name(a, b)); 54039109Sbostic return(sort_direction == FORWARD ? a->n_value > b->n_value : 54139109Sbostic a->n_value < b->n_value); 54239109Sbostic } 543619Sbill 544619Sbill char * 54539109Sbostic emalloc(size) 54639109Sbostic u_int size; 547619Sbill { 54839109Sbostic char *p, *malloc(); 549619Sbill 55039109Sbostic /* NOSTRICT */ 55139109Sbostic if (!(p = malloc(size))) { 55239109Sbostic (void)fprintf(stderr, "nm: no more memory.\n"); 55339109Sbostic exit(1); 55439109Sbostic } 55539109Sbostic return(p); 556619Sbill } 55730855Sbostic 55839109Sbostic usage() 55930855Sbostic { 56039109Sbostic (void)fprintf(stderr, "usage: nm [-agnopruw] [file ...]"); 56139109Sbostic exit(1); 56230855Sbostic } 563