home *** CD-ROM | disk | FTP | other *** search
- /*****************************************/
- /* */
- /* COPYRIGHT (c) 1991 SAS Institute, Inc */
- /* SAS Campus Drive */
- /* Cary, NC 27513 */
- /* USA */
- /* */
- /* Written by Doug Walker */
- /* bix: djwalker portal: djwalker */
- /* usenet: walker@unx.sas.com */
- /* */
- /* Please do not redistribute any */
- /* modified versions of this source */
- /* without permission from the copyright */
- /* holder! */
- /* */
- /*****************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <libraries/dosextens.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #define HUNKHEAD " num hunk size filename punit type base alv"
-
- void gethead(char *buf, int size, FILE *fp);
- int doomd(char *oname, char *cname, long targoff);
-
- char buf[300];
-
- #define WORKFILE "ram:hitme.tmp"
-
- char *omdfile = WORKFILE;
- char *cfiles = "";
- char *ofiles = "";
-
- int keepfile;
-
- #define EMSG(x) fprintf(stderr, x);
-
- void main(int argc, char **argv)
- {
- FILE *fp;
- char *p;
- char *cmdname;
- char fname[2][50], punit[2][50], type[2][10];
- int hunk, cur, base, lbase, offset, toggle;
- int rc = 69;
-
- if(argc > 0) cmdname = argv[0];
- else cmdname = NULL;
-
- if(argc < 3)
- {
- usage:
- if(cmdname)
- {
- fprintf(stderr, "USAGE: %s <options> <mapfilename> <offset> [<hunk>]\n",
- cmdname);
- EMSG(" <options> is one or more of\n");
- EMSG(" -n Do not run OMD\n");
- EMSG(" -d Keep OMD output\n");
- EMSG(" -d<file> Keep OMD output in <file>\n");
- EMSG(" -t Delete OMD output (default)\n");
- EMSG(" -t<file> Use <file> for OMD output, then delete\n");
- EMSG(" -o<dir> Directory for object files (default current directory)\n");
- EMSG(" -c<dir> Directory for C source files (default current directory)\n");
- EMSG(" <mapfilename> is a BLINK-produced map of your executable\n");
- EMSG(" <offset> is the offset reported by ENFORCER\n");
- EMSG(" <hunk> is the hunk reported by ENFORCER (default 0)\n");
- }
- exit(99);
- }
-
- while(argv[1][0] == '-')
- {
- switch(argv[1][1])
- {
- case 'c': case 'C': /* C source file path */
- cfiles = argv[1]+2;
- break;
-
- case 'o': case 'O': /* Object file path */
- ofiles = argv[1]+2;
- break;
-
- case 'd': case 'D': /* Disassembly output */
- keepfile = 1;
- if(argv[1][2]) omdfile = argv[1]+2;
- break;
-
- case 't': case 'T': /* Temp file name */
- keepfile = 0;
- if(argv[1][2]) omdfile = argv[1]+2;
- break;
-
- case 'n': case 'N':
- keepfile = 0;
- omdfile = NULL;
- break;
- }
- argv++, argc--;
- }
-
- if(argc < 2) goto usage;
-
- if(!(fp = fopen(argv[1], "r")))
- {
- fprintf(stderr, "ERROR: Can't open file '%s'\n", argv[1]);
- exit(89);
- }
-
- stch_i(argv[2], &offset);
-
- if(argc >= 4)
- stcd_i(argv[3], &hunk);
- else
- hunk = 0;
-
- buf[0] = 0x0c; /* Force a gethead call */
- do
- {
- if(buf[0] == 0x0c) gethead(buf, sizeof(buf)-1, fp);
-
- for(p=buf; *p == ' '; p++);
-
- if(stcd_i(p, &cur) && cur == hunk)
- {
- /* Bingo - found the right hunk */
- base = 0;
- toggle = 0;
- do
- {
- if(buf[0] == 0x0c) gethead(buf, sizeof(buf)-1, fp);
-
- for(p=buf; *p == ' '; p++);
-
- if(stcd_i(buf, &cur) && cur != hunk) break; /* New hunk */
- lbase = base;
- sscanf(buf+23, "%s %s %s %lx",
- fname[toggle], punit[toggle], type[toggle], &base);
- toggle = !toggle;
- }
- while(base < offset && fgets(buf, sizeof(buf)-1, fp));
-
- if(base < offset)
- {
- fprintf(stderr, "ERROR: Can't find offset 0x%08lx in hunk %d\n",
- offset, hunk);
- rc = 79;
- goto endit;
- }
- if(base == offset)
- {
- toggle = !toggle;
- lbase = base;
- }
-
- offset -= lbase;
-
- if(strcmp(type[toggle], "code") ||
- doomd(fname[toggle], punit[toggle], offset))
- {
- printf("Offset 0x%08lx file '%s' punit '%s' type %s\n",
- offset, fname[toggle], punit[toggle], type[toggle]);
- if(keepfile) printf("No OMD output available\n");
- }
- rc = 0;
- goto endit;
- }
- }
- while(fgets(buf, sizeof(buf)-1, fp));
-
- fprintf(stderr, "Can't find hunk %d\n", hunk);
-
- endit:
- if(fp) fclose(fp);
-
- exit(rc);
- }
-
- void gethead(char *buf, int size, FILE *fp)
- {
- while(fgets(buf, size, fp))
- {
- if(!memcmp(buf, HUNKHEAD, strlen(HUNKHEAD)))
- break;
- }
- fgets(buf, size, fp);
- }
-
-
- char onambuf[256];
- char cnambuf[304];
-
- int doomd(char *oname, char *cname, long targoff)
- {
- BPTR ofp, ifp;
- FILE *fp;
- char *p;
- int lno, offset;
- int rc;
-
- lno = -1;
-
- if(!omdfile) return(1);
-
- strcpy(onambuf, ofiles);
- if(ofiles[0] && ofiles[0] != ':') strcat(onambuf, "/");
- strcat(onambuf, oname);
-
- if(!(ifp = Open(onambuf, MODE_NEWFILE)))
- {
- omdfile = onambuf;
- goto errfile;
- }
- if(Read(ifp, cnambuf, sizeof(cnambuf)) > 0)
- cname = cnambuf + 8;
- Close(ifp);
-
- if(!(ofp = Open(omdfile, MODE_NEWFILE)))
- {
- errfile:
- fprintf(stderr, "ERROR: Can't open file '%s'\n", omdfile);
- return(1);
- }
-
- ifp = Open("NIL:", MODE_NEWFILE);
-
- sprintf(buf, "LC:OMD %s %s%s%s", onambuf,
- cfiles, (cfiles[0] && cfiles[0] != ':' ? "/" : ""), cname);
- Execute(buf, ifp, ofp);
-
- Close(ofp);
- if(ifp) Close(ifp);
-
- if(!(fp = fopen(omdfile, "r"))) goto errfile;
-
- rc = 1;
- while(fgets(buf, sizeof(buf)-1, fp))
- {
- if(buf[0] == ';')
- {
- for(p=buf+1; *p == ' '; p++);
- stcd_i(p, &lno);
- }
- else if(buf[7] == '|')
- {
- if(lno < 0) break; /* No debug */
-
- stch_i(buf+9, &offset);
- if(offset >= targoff)
- {
- printf("Line %d file '%s'\n", lno, cname);
- rc = 0;
- break;
- }
- }
- }
-
- fclose(fp);
-
- if(!keepfile) DeleteFile(omdfile);
- else if(!rc) printf("OMD output is in '%s'\n", omdfile);
-
- return(rc);
- }
-