1: /*
   2:  * netbind
   3:  *
   4:  * 1/6/95 -- remove 8 character limit on undefined symbol printf. sms.
   5:  * 1/8/94 -- revised for new object file format. sms.
   6:  *
   7:  * Resolve undefined inter-address-space references.
   8:  *
   9:  * Usage:
  10:  *	netbind unix.o netnix.o
  11:  *
  12:  * Produces two files as output:
  13:  *
  14:  *	d.unix.s	-- definitions of all symbols referenced by
  15:  *			   unix.o but defined in netnix.o
  16:  *	d.netnix.s	-- definitions of all symbols referenced by
  17:  *			   netnix.o but defined in unix.o
  18:  */
  19: #include <sys/param.h>
  20: #include <sys/file.h>
  21: #include <a.out.h>
  22: #include <stdio.h>
  23: 
  24: extern  char    *strdup(), *rindex();
  25: 
  26:     struct  xexec   refExec, defExec;
  27: 
  28: #define MAXSYMLEN 32
  29: 
  30: #define NSYMS   200
  31: struct symbol {
  32:     char    *s_name;
  33:     u_int   s_value;
  34:     u_int   s_type;
  35: } symtab[NSYMS], *symfree;
  36: 
  37: main(argc, argv)
  38:     int argc;
  39:     char **argv;
  40: {
  41:     if (argc != 3) {
  42:         printf("usage: %s unix.bo netnix.bo\n", *argv);
  43:         exit(2);
  44:     }
  45:     resolve(argv[1], argv[2]);  /* Produces d.unix.s */
  46:     resolve(argv[2], argv[1]);  /* Produces d.netnix.s */
  47:     exit(0);
  48: }
  49: 
  50: /*
  51:  * resolve --
  52:  *
  53:  * Resolve references made by ref to symbols defined in def.
  54:  *
  55:  * Side effects:
  56:  *	Prints a list of undefined symbols if there are any.
  57:  *	Produces the .s file corresponding to ref.
  58:  *	Adds the number of undefined symbols encountered to undef.
  59:  */
  60: resolve(ref, def)
  61:     char *ref;      /* Name of file referencing symbols */
  62:     char *def;      /* Name of file defining symbols */
  63: {
  64:     FILE *refIN, *defIN, *refSTR, *defSTR, *refOUT, *openobj();
  65:     struct nlist syment;
  66:     off_t stroff_ref, stroff_def;
  67:     int nundef;
  68:     char *rp, refout[MAXPATHLEN], name[MAXSYMLEN + 2];
  69: 
  70:     bzero(name, sizeof (name));
  71:     if (rp = rindex(ref, '.'))
  72:         *rp = '\0';
  73:     (void)sprintf(refout, "d.%s.s", ref);
  74:     if (rp)
  75:         *rp = '.';
  76:     if ((refIN = openobj(ref, &refExec, &refSTR)) == NULL)
  77:         return;
  78:     if ((defIN = openobj(def, &defExec, &defSTR)) == NULL) {
  79:         fclose(refIN);
  80:         fclose(refSTR);
  81:         return;
  82:     }
  83:     if ((refOUT = fopen(refout, "w")) == NULL) {
  84:         perror(refout);
  85:         fclose(refIN);
  86:         fclose(refSTR);
  87:         fclose(defIN);
  88:         fclose(defSTR);
  89:         return;
  90:     }
  91: 
  92:     /*
  93: 	 * Actually generate the .s file needed.
  94: 	 * Assumes that refExec and defExec have been set up to
  95: 	 * hold the a.out headers for the reference and definition
  96: 	 * object files.
  97: 	 *
  98: 	 * Algorithm:
  99: 	 *	Build a table of undefined symbols in refIN.
 100: 	 *	Define them by reading the symbol table of defIN.
 101: 	 *	Generate the .s file to refOUT.
 102: 	 */
 103:     syminit();
 104:     nundef = 0;
 105: 
 106:     /* Find the undefined symbols */
 107:     stroff_ref = N_STROFF(refExec);
 108:     fseek(refIN, N_SYMOFF(refExec), L_SET);
 109:     while (fread(&syment, sizeof(syment), 1, refIN) > 0) {
 110:         if (syment.n_type == (N_EXT|N_UNDF) && syment.n_value == 0)
 111:             {
 112:             fseek(refSTR, stroff_ref + syment.n_un.n_strx, L_SET);
 113:             fread(name, sizeof (name), 1, refSTR);
 114:             if (strcmp(name, "_end") &&
 115:                 strcmp(name, "_etext") &&
 116:                 strcmp(name, "_edata"))
 117:                 {
 118:                 nundef++;
 119:                 syment.n_un.n_name = name;
 120:                 symadd(&syment);
 121:                 }
 122:             }
 123:     }
 124: 
 125:     /* Define the undefined symbols */
 126:     stroff_def = N_STROFF(defExec);
 127:     fseek(defIN, N_SYMOFF(defExec), L_SET);
 128:     while (fread(&syment, sizeof(syment), 1, defIN) > 0) {
 129:         if ((syment.n_type & N_EXT) == 0)
 130:             continue;
 131:         fseek(defSTR, stroff_def + syment.n_un.n_strx, L_SET);
 132:         fread(name, sizeof (name), 1, defSTR);
 133:         syment.n_un.n_name = name;
 134:         nundef -= symdef(&syment, &defExec.e);
 135:     }
 136: 
 137:     /* Any undefined symbols left? */
 138:     if (nundef > 0) {
 139:         printf("%s: %d symbols undefined:\n", ref, nundef);
 140:         symundef();
 141:     }
 142:     symprdef(refOUT);
 143: 
 144:     fclose(refSTR);
 145:     fclose(defSTR);
 146:     fclose(refIN);
 147:     fclose(defIN);
 148:     fclose(refOUT);
 149: }
 150: 
 151: /*
 152:  * openobj --
 153:  *
 154:  * Open the indicated file, check to make sure that it is a
 155:  * valid object file with a symbol table, and read in the a.out header.
 156:  *
 157:  * Returns a pointer to an open FILE if successful, NULL if not.
 158:  * Prints its own error messages.
 159:  */
 160: FILE *
 161: openobj(filename, exechdr, strfp)
 162:     char *filename;
 163:     struct xexec *exechdr;
 164:     FILE **strfp;
 165: {
 166:     register FILE *f;
 167: 
 168:     if (!(f = fopen(filename, "r"))) {
 169:         perror(filename);
 170:         return((FILE *)NULL);
 171:     }
 172:     *strfp = fopen(filename, "r");      /* for strings */
 173:     if (fread(exechdr, sizeof(*exechdr), 1, f) <= 0) {
 174:         printf("%s: no a.out header\n", filename);
 175:         goto bad;
 176:     }
 177:     if (N_BADMAG(exechdr->e)) {
 178:         printf("%s: bad magic number\n", filename);
 179:         goto bad;
 180:     }
 181:     if (exechdr->e.a_syms == 0) {
 182:         printf("%s: no symbol table\n", filename);
 183:         goto bad;
 184:     }
 185:     return(f);
 186: bad:    fclose(f);
 187:     fclose(*strfp);
 188:     return((FILE *)NULL);
 189: }
 190: 
 191: /* -------------------- Symbol table management ----------------------- */
 192: 
 193: /*
 194:  * syminit --
 195:  *
 196:  * Clear and initialize the symbol table.
 197:  */
 198: syminit()
 199: {
 200:     symfree = symtab;
 201: }
 202: 
 203: /*
 204:  * symadd --
 205:  *
 206:  * Add a symbol to the table.
 207:  * We store both the symbol name and the symbol number.
 208:  */
 209: symadd(np)
 210:     struct nlist *np;
 211: {
 212:     if (symfree >= &symtab[NSYMS]) {
 213:         printf("Symbol table overflow.  Increase NSYMS.\n");
 214:         exit (1);
 215:     }
 216:     symfree->s_name = strdup(np->n_un.n_name);
 217:     if  (!symfree->s_name)
 218:         {
 219:         printf("netbind: out of memory for symbol strings\n");
 220:         exit(1);
 221:         }
 222:     symfree->s_type = N_UNDF;
 223:     symfree->s_value = 0;
 224:     symfree++;
 225: }
 226: 
 227: /*
 228:  * symdef --
 229:  *
 230:  * Use the supplied symbol to define an undefined entry in
 231:  * the symbol table.
 232:  *
 233:  * Returns 1 if the name of the symbol supplied was found in
 234:  * the table, 0 otherwise.
 235:  */
 236: symdef(np, ep)
 237:     struct nlist *np;
 238:     struct exec *ep;
 239: {
 240:     register struct symbol *sp;
 241: 
 242:     for (sp = symtab; sp < symfree; sp++)
 243:         if (!strcmp(sp->s_name, np->n_un.n_name)) {
 244:             int type = (np->n_type & N_TYPE);
 245: 
 246:             switch (type) {
 247:             case N_TEXT:
 248:             case N_ABS:
 249:                 sp->s_type = N_EXT|N_ABS;
 250:                 sp->s_value = np->n_value;
 251:                 break;
 252:             case N_DATA:
 253:             case N_BSS:
 254:                 sp->s_type = N_EXT|N_ABS;
 255:                 if (ep->a_flag)
 256:                     sp->s_value = np->n_value;
 257:                 else
 258:                     sp->s_value = np->n_value - ep->a_text;
 259:                 break;
 260:             case N_UNDF:
 261:                 return(0);
 262:             default:
 263:                 printf("netbind: symbol %s, bad type 0x%x\n",
 264:                     np->n_un.n_name, np->n_type);
 265:                 exit(1);
 266:             }
 267:             return (1);
 268:         }
 269:     return(0);
 270: }
 271: 
 272: /*
 273:  * symundef --
 274:  *
 275:  * Print all undefined symbols in the symbol table.
 276:  * First sorts the table before printing it.
 277:  */
 278: symundef()
 279: {
 280:     register struct symbol *sp;
 281:     int scmp();
 282: 
 283:     qsort(symtab, symfree - symtab, sizeof(struct symbol), scmp);
 284:     for (sp = symtab; sp < symfree; sp++)
 285:         if ((sp->s_type & N_TYPE) == N_UNDF)
 286:             printf("%s\n", sp->s_name);
 287: }
 288: 
 289: scmp(s1, s2)
 290:     register struct symbol *s1, *s2;
 291: {
 292:     return(strcmp(s1->s_name, s2->s_name));
 293: }
 294: 
 295: /*
 296:  * symprdef --
 297:  *
 298:  * Output all defined symbols in the symbol table.
 299:  * First sorts the table before printing it.
 300:  */
 301: symprdef(refOUT)
 302:     FILE *refOUT;
 303: {
 304:     register struct symbol *sp;
 305:     int scmp();
 306: 
 307:     qsort(symtab, symfree - symtab, sizeof (struct symbol), scmp);
 308:     for (sp = symtab; sp < symfree; sp++)
 309:         if ((sp->s_type & N_TYPE) != N_UNDF) {
 310:             fprintf(refOUT, ".globl %s\n", sp->s_name);
 311:             fprintf(refOUT, "%s = %o\n", sp->s_name, sp->s_value);
 312:         }
 313: }

Defined functions

main defined in line 37; never used
openobj defined in line 160; used 3 times
resolve defined in line 60; used 2 times
scmp defined in line 289; used 4 times
symadd defined in line 209; used 1 times
symdef defined in line 236; used 1 times
syminit defined in line 198; used 1 times
symprdef defined in line 301; used 1 times
symundef defined in line 278; used 1 times

Defined variables

defExec defined in line 26; used 4 times
refExec defined in line 26; used 3 times
symfree defined in line 35; used 12 times
symtab defined in line 35; used 9 times

Defined struct's

symbol defined in line 31; used 12 times

Defined macros

MAXSYMLEN defined in line 28; used 1 times
  • in line 68
NSYMS defined in line 30; used 2 times
Last modified: 1995-01-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4305
Valid CSS Valid XHTML 1.0 Strict