cramer@optilink.UUCP (Clayton Cramer) (08/18/90)
I asked a few days back for advice on tricking the Microsoft linker into overlaying data. Here is the solution worked out in house. The last SEGDEF record in the .OBJ file containing the data you wish overlaid with the code has a segment class of FAR_DATA. Look in the LNAMES record (near the beginning of the .OBJ file), and find the corresponding number for the CODE segment class. Then alter the segment class in the last SEGDEF record to be CODE, not FAR_DATA. Sounds difficult? Well, every .OBJ file we have examined produced by Microsoft C 6.0 uses the same basic header, with the same number of SEGDEF records, and the same order for the LNAMES record. So I wrote a little program that does the editing needed -- all you have to do it add it to your MAKE file immediately after the .OBJ file is produced. The READOBJ program I am using to interpret the .OBJ files whines that the checksums don't match in the SEGDEF we edit, but the linker doesn't object (other than giving warning messages), and this DOES work to put data and code into overlays. Note, of course, that any data altered that is in an overlay will be lost when the overlay is swapped out, so you have to be a little careful when using this technique. (The resulting bugs can be VERY unobvious). ----cut here------------------------------------------------------------ /* This program edits the FAR_DATA SEGDEF records of Microsoft C .obj files so that the FAR_DATA segment is grouped with the _TEXT segment, allowing the FAR_DATA contents to be overlaid with the code. Doing it in this manner is crude and disgusting, rather akin to shaking someone's hand by stuffing your hand the entire length of their alimentary canal to get to their hand. Unfortunately, the Microsoft Linker is so brain-damaged, there's no other way to do it. To do this, we make the assumption that everything that goes in the FAR_DATA segment is constant data. We also assume that the sequence of Microsoft OMF records in an .obj file is roughly constant. */ #include <stdio.h> #include "std.h" main (Argc, Argv) int Argc; char* Argv[]; { FILE* ObjFile; int SegdefRecordCount = 0; int RecLength; bool FileEdited; int Ch; /* Search through the file until we find the first SEGDEF record. */ ObjFile = fopen(Argv[Argc-1], "r+b"); if(ObjFile) { FileEdited = FALSE; while(!FileEdited && !feof(ObjFile) && !ferror(ObjFile)) { switch(Ch = fgetc(ObjFile)) { case 0x98: SegdefRecordCount++; if(SegdefRecordCount == 7) { /* We have found the SEGDEF we want to alter. */ fseek(ObjFile, (long)6, SEEK_CUR); fputc(0x4, ObjFile); FileEdited = TRUE; } else { /* Not yet where we want to be. Skip past this record. */ fread(&RecLength, sizeof(int), 1, ObjFile); fseek(ObjFile, RecLength, SEEK_CUR); } break; case EOF: break; default: fread(&RecLength, sizeof(int), 1, ObjFile); fseek(ObjFile, RecLength, SEEK_CUR); break; } } } fclose(ObjFile); } ----cut here------------------------------------------------------------ -- Clayton E. Cramer {pyramid,pixar,tekbspa}!optilink!cramer "The tree of liberty must be watered periodically with the blood of tyrants and patriots alike. It is its natural manure." -- Thomas Jefferson You must be kidding! No company would hold opinions like mine!