| [9] | 1 | /*
 | 
|---|
 | 2 |  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
|---|
 | 3 |  * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
|---|
 | 4 |  */
 | 
|---|
 | 5 | /* $Id: anm.c,v 1.2 2005/06/23 09:50:54 philip Exp $ */
 | 
|---|
 | 6 | /*
 | 
|---|
 | 7 | **      print symbol tables for
 | 
|---|
 | 8 | **      ACK object files
 | 
|---|
 | 9 | **
 | 
|---|
 | 10 | **      anm [-gopruns] [name ...]
 | 
|---|
 | 11 | */
 | 
|---|
 | 12 | 
 | 
|---|
 | 13 | #include        "out.h"
 | 
|---|
 | 14 | #include        "arch.h"
 | 
|---|
 | 15 | #include        "ranlib.h"
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 | #include        <stdio.h>
 | 
|---|
 | 18 | #include        <ctype.h>
 | 
|---|
 | 19 | 
 | 
|---|
 | 20 | int     numsort_flg;
 | 
|---|
 | 21 | int     sectsort_flg;
 | 
|---|
 | 22 | int     undef_flg;
 | 
|---|
 | 23 | int     revsort_flg = 1;
 | 
|---|
 | 24 | int     globl_flg;
 | 
|---|
 | 25 | int     nosort_flg;
 | 
|---|
 | 26 | int     arch_flg;
 | 
|---|
 | 27 | int     prep_flg;
 | 
|---|
 | 28 | int     read_error;
 | 
|---|
 | 29 | struct  outhead hbuf;
 | 
|---|
 | 30 | struct  outsect sbuf;
 | 
|---|
 | 31 | long    off;
 | 
|---|
 | 32 | char    *malloc();
 | 
|---|
 | 33 | char    *realloc();
 | 
|---|
 | 34 | long    s_base[S_MAX];  /* for specially encoded bases */
 | 
|---|
 | 35 | char    *filename;
 | 
|---|
 | 36 | int     narg;
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 | main(argc, argv)
 | 
|---|
 | 39 | char **argv;
 | 
|---|
 | 40 | {
 | 
|---|
 | 41 | 
 | 
|---|
 | 42 |         if (--argc>0 && argv[1][0]=='-' && argv[1][1]!=0) {
 | 
|---|
 | 43 |                 argv++;
 | 
|---|
 | 44 |                 while (*++*argv) switch (**argv) {
 | 
|---|
 | 45 |                 case 'n':               /* sort numerically */
 | 
|---|
 | 46 |                         numsort_flg++;
 | 
|---|
 | 47 |                         continue;
 | 
|---|
 | 48 | 
 | 
|---|
 | 49 |                 case 's':               /* sort in section order */
 | 
|---|
 | 50 |                         sectsort_flg++;
 | 
|---|
 | 51 |                         continue;
 | 
|---|
 | 52 | 
 | 
|---|
 | 53 |                 case 'g':               /* globl symbols only */
 | 
|---|
 | 54 |                         globl_flg++;
 | 
|---|
 | 55 |                         continue;
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 |                 case 'u':               /* undefined symbols only */
 | 
|---|
 | 58 |                         undef_flg++;
 | 
|---|
 | 59 |                         continue;
 | 
|---|
 | 60 | 
 | 
|---|
 | 61 |                 case 'r':               /* sort in reverse order */
 | 
|---|
 | 62 |                         revsort_flg = -1;
 | 
|---|
 | 63 |                         continue;
 | 
|---|
 | 64 | 
 | 
|---|
 | 65 |                 case 'p':               /* don't sort -- symbol table order */
 | 
|---|
 | 66 |                         nosort_flg++;
 | 
|---|
 | 67 |                         continue;
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 |                 case 'o':               /* prepend a name to each line */
 | 
|---|
 | 70 |                         prep_flg++;
 | 
|---|
 | 71 |                         continue;
 | 
|---|
 | 72 | 
 | 
|---|
 | 73 |                 default:                /* oops */
 | 
|---|
 | 74 |                         fprintf(stderr, "anm: invalid argument -%c\n", *argv[0]);
 | 
|---|
 | 75 |                         exit(1);
 | 
|---|
 | 76 |                 }
 | 
|---|
 | 77 |                 argc--;
 | 
|---|
 | 78 |         }
 | 
|---|
 | 79 |         if (argc == 0) {
 | 
|---|
 | 80 |                 argc = 1;
 | 
|---|
 | 81 |                 argv[1] = "a.out";
 | 
|---|
 | 82 |         }
 | 
|---|
 | 83 |         narg = argc;
 | 
|---|
 | 84 | 
 | 
|---|
 | 85 |         while(argc--) {
 | 
|---|
 | 86 |                 int fd;
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 |                 filename = *++argv;
 | 
|---|
 | 89 |                 if ((fd = open(filename, 0)) < 0) {
 | 
|---|
 | 90 |                         fprintf(stderr, "anm: cannot open %s\n", filename);
 | 
|---|
 | 91 |                         continue;
 | 
|---|
 | 92 |                 }
 | 
|---|
 | 93 |                 process(fd);
 | 
|---|
 | 94 |                 close(fd);
 | 
|---|
 | 95 |         }
 | 
|---|
 | 96 |         exit(0);
 | 
|---|
 | 97 | }
 | 
|---|
 | 98 | 
 | 
|---|
 | 99 | extern int rd_unsigned2();
 | 
|---|
 | 100 | extern long lseek();
 | 
|---|
 | 101 | extern char *strncpy();
 | 
|---|
 | 102 | 
 | 
|---|
 | 103 | process(fd)
 | 
|---|
 | 104 |         int     fd;
 | 
|---|
 | 105 | {
 | 
|---|
 | 106 |         unsigned int    magic;
 | 
|---|
 | 107 |         long            nextpos;
 | 
|---|
 | 108 |         struct ar_hdr   archive_header;
 | 
|---|
 | 109 |         static char     buf[sizeof(archive_header.ar_name)+1];
 | 
|---|
 | 110 | 
 | 
|---|
 | 111 |         if (narg > 1) printf("\n%s:\n", filename);
 | 
|---|
 | 112 | 
 | 
|---|
 | 113 |         magic = rd_unsigned2(fd);
 | 
|---|
 | 114 |         switch(magic) {
 | 
|---|
 | 115 |         case O_MAGIC:
 | 
|---|
 | 116 |                 lseek(fd, 0L, 0);
 | 
|---|
 | 117 |                 do_file(fd);
 | 
|---|
 | 118 |                 break;
 | 
|---|
 | 119 |         case ARMAG:
 | 
|---|
 | 120 |         case AALMAG:
 | 
|---|
 | 121 |                 while (rd_arhdr(fd, &archive_header)) {
 | 
|---|
 | 122 |                         nextpos = lseek(fd, 0L, 1) + archive_header.ar_size;
 | 
|---|
 | 123 |                         if (nextpos & 1) nextpos++;
 | 
|---|
 | 124 |                         strncpy(buf,archive_header.ar_name,sizeof(archive_header.ar_name));
 | 
|---|
 | 125 |                         filename = buf;
 | 
|---|
 | 126 |                         if ( strcmp(filename, SYMDEF)) {
 | 
|---|
 | 127 |                                 printf("\n%s:\n", filename);
 | 
|---|
 | 128 |                                 do_file(fd);
 | 
|---|
 | 129 |                         }
 | 
|---|
 | 130 |                         lseek(fd, nextpos, 0);
 | 
|---|
 | 131 |                 }
 | 
|---|
 | 132 |                 break;
 | 
|---|
 | 133 |         default:
 | 
|---|
 | 134 |                 fprintf(stderr, "anm: %s -- bad format\n", filename);
 | 
|---|
 | 135 |                 break;
 | 
|---|
 | 136 |         }
 | 
|---|
 | 137 | }
 | 
|---|
 | 138 | 
 | 
|---|
 | 139 | do_file(fd)
 | 
|---|
 | 140 |         int     fd;
 | 
|---|
 | 141 | {
 | 
|---|
 | 142 |         struct  outname *nbufp = NULL;
 | 
|---|
 | 143 |         struct  outname nbuf;
 | 
|---|
 | 144 |         char            *cbufp;
 | 
|---|
 | 145 |         long            fi_to_co;
 | 
|---|
 | 146 |         long            n;
 | 
|---|
 | 147 |         unsigned        readcount;
 | 
|---|
 | 148 |         int             i,j;
 | 
|---|
 | 149 |         int             compare();
 | 
|---|
 | 150 | 
 | 
|---|
 | 151 |         read_error = 0;
 | 
|---|
 | 152 |         rd_fdopen(fd);
 | 
|---|
 | 153 | 
 | 
|---|
 | 154 |         rd_ohead(&hbuf);
 | 
|---|
 | 155 |         if (read_error) {
 | 
|---|
 | 156 |                 return;
 | 
|---|
 | 157 |         }
 | 
|---|
 | 158 |         if (BADMAGIC(hbuf)) {
 | 
|---|
 | 159 |                 return;
 | 
|---|
 | 160 |         }
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 |         n = hbuf.oh_nname;
 | 
|---|
 | 163 |         if (n == 0) {
 | 
|---|
 | 164 |                 fprintf(stderr, "anm: %s -- no name list\n", filename);
 | 
|---|
 | 165 |                 return;
 | 
|---|
 | 166 |         }
 | 
|---|
 | 167 | 
 | 
|---|
 | 168 |         if (hbuf.oh_nchar == 0) {
 | 
|---|
 | 169 |                 fprintf(stderr, "anm: %s -- no names\n", filename);
 | 
|---|
 | 170 |                 return;
 | 
|---|
 | 171 |         }
 | 
|---|
 | 172 |         if ((readcount = hbuf.oh_nchar) != hbuf.oh_nchar) {
 | 
|---|
 | 173 |                 fprintf(stderr, "anm: string area too big in %s\n", filename);
 | 
|---|
 | 174 |                 exit(2);
 | 
|---|
 | 175 |         }
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 |         /* store special section bases ??? */
 | 
|---|
 | 178 |         if (hbuf.oh_flags & HF_8086) {
 | 
|---|
 | 179 |                 rd_sect(&sbuf, hbuf.oh_nsect);
 | 
|---|
 | 180 |                 if (read_error) {
 | 
|---|
 | 181 |                         return;
 | 
|---|
 | 182 |                 }
 | 
|---|
 | 183 |                 for (i=0; i<hbuf.oh_nsect; i++) {
 | 
|---|
 | 184 |                         s_base[i+S_MIN] =
 | 
|---|
 | 185 |                                 (sbuf.os_base>>12) & 03777760;
 | 
|---|
 | 186 |                 }
 | 
|---|
 | 187 |         }
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 |         if ((cbufp = (char *)malloc(readcount)) == NULL) {
 | 
|---|
 | 190 |                 fprintf(stderr, "anm: out of memory on %s\n", filename);
 | 
|---|
 | 191 |                 exit(2);
 | 
|---|
 | 192 |         }
 | 
|---|
 | 193 |         rd_string(cbufp, hbuf.oh_nchar);
 | 
|---|
 | 194 |         if (read_error) {
 | 
|---|
 | 195 |                 free(cbufp);
 | 
|---|
 | 196 |                 return;
 | 
|---|
 | 197 |         }
 | 
|---|
 | 198 | 
 | 
|---|
 | 199 |         fi_to_co = (long) (cbufp - OFF_CHAR(hbuf));
 | 
|---|
 | 200 |         i = 0;
 | 
|---|
 | 201 |         while (--n >= 0) {
 | 
|---|
 | 202 |                 rd_name(&nbuf, 1);
 | 
|---|
 | 203 |                 if (read_error) {
 | 
|---|
 | 204 |                         break;
 | 
|---|
 | 205 |                 }
 | 
|---|
 | 206 | 
 | 
|---|
 | 207 |                 if (globl_flg && (nbuf.on_type&S_EXT)==0)
 | 
|---|
 | 208 |                         continue;
 | 
|---|
 | 209 | 
 | 
|---|
 | 210 |                 if (undef_flg
 | 
|---|
 | 211 |                     &&
 | 
|---|
 | 212 |                     ((nbuf.on_type&S_TYP)!=S_UND || (nbuf.on_type&S_ETC)!=0))
 | 
|---|
 | 213 |                         continue;
 | 
|---|
 | 214 | 
 | 
|---|
 | 215 |                 if (nbuf.on_foff == 0) nbuf.on_mptr = 0;
 | 
|---|
 | 216 |                 else nbuf.on_mptr = (char *) (nbuf.on_foff + fi_to_co);
 | 
|---|
 | 217 | 
 | 
|---|
 | 218 |                 /* adjust value for specially encoded bases */
 | 
|---|
 | 219 |                 if (hbuf.oh_flags & HF_8086) {
 | 
|---|
 | 220 |                     if (((nbuf.on_type&S_ETC) == 0) ||
 | 
|---|
 | 221 |                         ((nbuf.on_type&S_ETC) == S_SCT)) {
 | 
|---|
 | 222 |                         j = nbuf.on_type&S_TYP;
 | 
|---|
 | 223 |                         if ((j>=S_MIN) && (j<=S_MAX))
 | 
|---|
 | 224 |                             nbuf.on_valu += s_base[j];
 | 
|---|
 | 225 |                     }
 | 
|---|
 | 226 |                 }
 | 
|---|
 | 227 | 
 | 
|---|
 | 228 |                 if (nbufp == NULL)
 | 
|---|
 | 229 |                         nbufp = (struct outname *)malloc(sizeof(struct outname));
 | 
|---|
 | 230 |                 else
 | 
|---|
 | 231 |                         nbufp = (struct outname *)realloc(nbufp, (i+1)*sizeof(struct outname));
 | 
|---|
 | 232 |                 if (nbufp == NULL) {
 | 
|---|
 | 233 |                         fprintf(stderr, "anm: out of memory on %s\n", filename);
 | 
|---|
 | 234 |                         exit(2);
 | 
|---|
 | 235 |                 }
 | 
|---|
 | 236 |                 nbufp[i++] = nbuf;
 | 
|---|
 | 237 |         }
 | 
|---|
 | 238 | 
 | 
|---|
 | 239 |         if (nbufp && nosort_flg==0)
 | 
|---|
 | 240 |                 qsort(nbufp, i, sizeof(struct outname), compare);
 | 
|---|
 | 241 | 
 | 
|---|
 | 242 |         for (n=0; n<i; n++) {
 | 
|---|
 | 243 |                 char    cs1[4];
 | 
|---|
 | 244 |                 char    cs2[4];
 | 
|---|
 | 245 | 
 | 
|---|
 | 246 |                 if (prep_flg)
 | 
|---|
 | 247 |                         printf("%s:", filename);
 | 
|---|
 | 248 | 
 | 
|---|
 | 249 |                 switch(nbufp[n].on_type&S_ETC) {
 | 
|---|
 | 250 |                 case S_SCT:
 | 
|---|
 | 251 |                         sprintf(cs1, "%2d", (nbufp[n].on_type&S_TYP) - S_MIN);
 | 
|---|
 | 252 |                         sprintf(cs2, " S");
 | 
|---|
 | 253 |                         break;
 | 
|---|
 | 254 |                 case S_FIL:
 | 
|---|
 | 255 |                         sprintf(cs1, " -");
 | 
|---|
 | 256 |                         sprintf(cs2, " F");
 | 
|---|
 | 257 |                         break;
 | 
|---|
 | 258 |                 case S_MOD:
 | 
|---|
 | 259 |                         sprintf(cs1, " -");
 | 
|---|
 | 260 |                         sprintf(cs2, " M");
 | 
|---|
 | 261 |                         break;
 | 
|---|
 | 262 |                 case S_COM:
 | 
|---|
 | 263 |                         sprintf(cs1, " C");
 | 
|---|
 | 264 |                         if (nbufp[n].on_type&S_EXT)
 | 
|---|
 | 265 |                                 sprintf(cs2, " E");
 | 
|---|
 | 266 |                         else
 | 
|---|
 | 267 |                                 sprintf(cs2, " -");
 | 
|---|
 | 268 |                         break;
 | 
|---|
 | 269 |                 case 0:
 | 
|---|
 | 270 |                         if (nbufp[n].on_type&S_EXT)
 | 
|---|
 | 271 |                                 sprintf(cs2, " E");
 | 
|---|
 | 272 |                         else
 | 
|---|
 | 273 |                                 sprintf(cs2, " -");
 | 
|---|
 | 274 | 
 | 
|---|
 | 275 |                         switch(nbufp[n].on_type&S_TYP) {
 | 
|---|
 | 276 |                         case S_UND:
 | 
|---|
 | 277 |                                 sprintf(cs1, " U");
 | 
|---|
 | 278 |                                 break;
 | 
|---|
 | 279 |                         case S_ABS:
 | 
|---|
 | 280 |                                 sprintf(cs1, " A");
 | 
|---|
 | 281 |                                 break;
 | 
|---|
 | 282 |                         default:
 | 
|---|
 | 283 |                                 sprintf(cs1, "%2d", (nbufp[n].on_type&S_TYP) - S_MIN);
 | 
|---|
 | 284 |                         }
 | 
|---|
 | 285 |                         break;
 | 
|---|
 | 286 |                 default:
 | 
|---|
 | 287 |                         sprintf(cs1, "??");
 | 
|---|
 | 288 |                         sprintf(cs2, " ?");
 | 
|---|
 | 289 |                 }
 | 
|---|
 | 290 | 
 | 
|---|
 | 291 |                 printf("%8lx %s %s %s\n",nbufp[n].on_valu,cs1,cs2,nbufp[n].on_mptr ? nbufp[n].on_mptr : "(NULL)");
 | 
|---|
 | 292 |         }
 | 
|---|
 | 293 | 
 | 
|---|
 | 294 |         if (nbufp)
 | 
|---|
 | 295 |                 free((char *)nbufp);
 | 
|---|
 | 296 |         if (cbufp)
 | 
|---|
 | 297 |                 free((char *)cbufp);
 | 
|---|
 | 298 | }
 | 
|---|
 | 299 | 
 | 
|---|
 | 300 | compare(p1, p2)
 | 
|---|
 | 301 | struct outname  *p1, *p2;
 | 
|---|
 | 302 | {
 | 
|---|
 | 303 |         int     i;
 | 
|---|
 | 304 | 
 | 
|---|
 | 305 |         if (sectsort_flg) {
 | 
|---|
 | 306 |                 if ((p1->on_type&S_TYP) > (p2->on_type&S_TYP))
 | 
|---|
 | 307 |                         return(revsort_flg);
 | 
|---|
 | 308 |                 if ((p1->on_type&S_TYP) < (p2->on_type&S_TYP))
 | 
|---|
 | 309 |                         return(-revsort_flg);
 | 
|---|
 | 310 |         }
 | 
|---|
 | 311 | 
 | 
|---|
 | 312 |         if (numsort_flg) {
 | 
|---|
 | 313 |                 if (p1->on_valu > p2->on_valu)
 | 
|---|
 | 314 |                         return(revsort_flg);
 | 
|---|
 | 315 |                 if (p1->on_valu < p2->on_valu)
 | 
|---|
 | 316 |                         return(-revsort_flg);
 | 
|---|
 | 317 |         }
 | 
|---|
 | 318 | 
 | 
|---|
 | 319 |         if (! p1->on_mptr) {
 | 
|---|
 | 320 |                 if (! p2->on_mptr) return 0;
 | 
|---|
 | 321 |                 return -revsort_flg;
 | 
|---|
 | 322 |         }
 | 
|---|
 | 323 |         if (! p2->on_mptr) return revsort_flg;
 | 
|---|
 | 324 | 
 | 
|---|
 | 325 |         i = strcmp(p1->on_mptr, p2->on_mptr);
 | 
|---|
 | 326 | 
 | 
|---|
 | 327 |         if (i > 0)
 | 
|---|
 | 328 |                 return(revsort_flg);
 | 
|---|
 | 329 |         if (i < 0)
 | 
|---|
 | 330 |                 return(-revsort_flg);
 | 
|---|
 | 331 | 
 | 
|---|
 | 332 |         return(0);
 | 
|---|
 | 333 | }
 | 
|---|
 | 334 | 
 | 
|---|
 | 335 | rd_fatal()
 | 
|---|
 | 336 | {
 | 
|---|
 | 337 |         fprintf(stderr,"read error on %s\n", filename);
 | 
|---|
 | 338 |         read_error = 1;
 | 
|---|
 | 339 | }
 | 
|---|