#include #include #include #include #include "o.h" /*----- Comment Record Types ------*/ #define MSLANG 0 /* 00h - MS Language Name */ #define MSDOSV 156 /* BCh - MS DOS Level Number (?) */ #define MSMODL 157 /* BDh - MS Memory Model (+opts) */ #define MSDSEG 158 /* BEh - MS Forced 'DOSSEG' switch */ #define MSILIB 159 /* A0h - MS INCLUDELIB directive */ #define MSEXTN 161 /* A1h - MS Extensions Enabled */ #define UNKNWN 162 /* A2h - (?) */ #define MSLNAM 163 /* A3h - MS Library Module Name */ #define PATIME 221 /* DDh - Phoenix Time Stamp */ #define PACMNT 255 /* FFh - Phoenix Comment */ #define TCXSYMTYPIX 0xe0 #define TCPUBSYMTYP 0xe1 #define TCSTRUCT 0xe2 #define TCTYPDEF 0xe3 #define TCENUM 0xe4 #define TCBEGSCP 0xe5 #define TCLOCDEF 0xE6 #define TCENDSCP 0xe7 #define TCSOURCE 0xe8 #define TCDEPFIL 0xe9 #define TCXLATOR 0xea #define TCMANGLE 0xf8 static char *models[] = { "tiny","small","medium","compact","large","huge" }; typedef struct { word seconds:5; word minute:6; word hour:5; } TIME; typedef struct { word day:5; word month:4; word year:7; } DATE; static char *months[] = { "(nul)", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static void sprint_date(char*string,char*datestr) { TIME time; DATE date; time = *(TIME*)datestr; date = *(DATE*)&datestr[2]; sprintf(string, "%02d:%02d:%02d on %.3s %d, %04d", time.hour, time.minute, time.seconds, months[date.month], date.day, date.year+1980); } int scope_compare(SCOPE_T *btreescope, SCOPE_T *scope) { if ( btreescope->hex_offset > scope->hex_offset ) { return( LEFT ); } else { if ( btreescope->hex_offset < scope->hex_offset ) { return( RIGHT ); } else { return( EQUAL ); } } } void coment( word length) { char junk[3]; char *comment; char text[80]; char temp[80]; int type; int class; char cksum; uchar *prt_char; int i; int w; char *p; LOCAL_VAR *local_var; static word scope_type = VT_VAR; static NODE_T **ppScope_tree; static SCOPE_T *pScope; static SCOPE_T **ppScope; static SCOPE_T *arg_scope; static SCOPE_T *loc_scope; type = get_byte(); class = get_byte(); length -= 3; if (length) comment = o_malloc(length); else comment = junk; get_str( length, comment); switch( class ) { case MSLANG: out_line( "", "; Compiler:", comment, "" ); break; case MSMODL: processor_type_comment_occurred = TRUE; switch( comment[0] ) { case '3': out_line( "", ".386p", "", "" ); out_line( "", ".387", "", "" ); processor_mode = 386; break; case '2': out_line( "", ".286p", "", "" ); out_line( "", ".287", "", "" ); processor_mode = 286; break; case '1': out_line( "", ".186", "", "" ); out_line( "", ".187", "", "" ); processor_mode = 186; break; case '0': out_line( "", ".8086", "", "" ); out_line( "", ".8087", "", "" ); processor_mode = 8086; break; default: fmt_error( "Unknown Processor Type" ); break; } switch( comment[1] ) { case 'c': out_line( "", "; Compact Memory Model", "", "" ); break; case 's': out_line( "", "; Small Memory Model", "", "" ); break; case 'm': out_line( "", "; Medium Memory Model", "", "" ); break; case 'l': out_line( "", "; Large Memory Model", "", "" ); break; case 'h': out_line( "", "; Huge Memory Model", "", "" ); break; default: fmt_error( "Unknown Model" ); break; } if ( comment[2] == 'O' ) out_line( "", "; Optimizations Enabled", "", "" ); break; case MSDSEG: out_line( "", "; Force DOSSEG linker option", "", "" ); break; case MSILIB: out_line( "", "includelib", comment, "" ); break; case MSEXTN: if (length) { if ( !strcmp( comment, "\001CV" ) ) { out_line( "", "; CodeView Enabled", "", "" ); } else { fmt_error( "Unknown CodeView Option" ); } } break; case UNKNWN: out_line( "", "; Linker - Pass two marker","",""); break; case PATIME: if ( comment[0] != 16 ) fmt_error( "Unknown Phoenix Time Stamp Prefix" ); out_line( "", "; Time: ", &comment[1], "" ); break; case PACMNT: out_line( "", ";", comment, "" ); break; /* Extensions to COMENT record defined by Borland. Note that these have been deduced using TDUMP (and lots of examples) and consequently may be completely wrong. [rh] */ case TCXSYMTYPIX: sprintf(text, "; External symbol type index %02X", *comment, comment[1]&1); out_line(text,"","",""); break; case TCPUBSYMTYP: sprintf(text, "; Public symbol type %02X, function return offset %02X", *comment, comment[1]&1); out_line(text,"","",""); break; case TCSTRUCT: out_line("; typedef struct:","","",""); i = 1; while (ihex_offset = *(int*)comment; pScope = insert(pScope, end_scope_tree,TC scope_compare)->data; sprintf(text, "; End of scope at offset %04X",*(int*)comment); out_line(text,"","",""); break; case TCBEGSCP: if (scope_type==VT_ARG) scope_type = VT_VAR; else scope_type = VT_ARG; if (scope_type==VT_ARG) { ppScope_tree = &arg_scope_tree; ppScope = &arg_scope; } else { ppScope_tree = &loc_scope_tree; ppScope = &loc_scope; } *ppScope = o_malloc(sizeof(SCOPE_T)); (*ppScope)->hex_offset = *(int*)&comment[1]; *ppScope = insert(*ppScope,*ppScope_tree, TC scope_compare)->data; sprintf(text,"; Begin scope segment %04X, offset %04X",(int)*comment,*(int*)&comment[1]); out_line(text,"","",""); break; case TCLOCDEF: out_line("; Local definitions:","","",""); i = 0; local_var = (*ppScope)->head = o_malloc(sizeof(LOCAL_VAR)); while (i+1next = o_malloc(sizeof(LOCAL_VAR)); out_newline(); sprintf(text,"; \"%.*s\"",comment[i],&comment[i+1]); sprintf(local_var->vname,"%.*s",comment[i],&comment[i+1]); i+=comment[i]+1; sprintf(temp,", type %02X, class %02X",comment[i],comment[i+1]&7); strcat(text,temp); *temp = 0; i++; local_var->class = comment[i]&7; switch (comment[i]&7) { case 7: sprintf(temp, " (instance of typed variable)"); local_var->bInfo1 = comment[i+1]; i++; break; case 6: /* local typedef ? */ sprintf(temp, " (local typedef)"); local_var->bInfo1 = comment[i+1]; i++; break; case 4: /* register variable */ i++; switch (comment[i]) { case 0x06: p = "si"; break; case 0x07: p = "di"; break; default : p = "[unknown]"; break; } local_var->bInfo1 = comment[i]; sprintf(temp," variable in register %s",p); i++; local_var->bInfo2 = comment[i]; break; case 2: /* variable */ local_var->bInfo1 = comment[i]; /* argument or local */ sprintf(temp," (var) %s stored in ",comment[i]&8?"argument":"local"); strcat(text,temp); switch (comment[i++]&7) { case 2 : /* stored on stack */ local_var->bInfo2 = (comment[i-1]&7)==2; /* stored on stack */ local_var->wInfo1 = *(int*)&comment[i]; /* address */ w = *(int*)&comment[i++]; if (w<0) sprintf(temp,"[bp-%04X]",-w); else sprintf(temp,"[bp+%04X]",w); break; default : strcpy(temp,"[unknown]"); break; } i++; break; case 0: /* static function */ sprintf(temp, " (static func) index %04X, word %04X", *(int*)&comment[i+1],*(int*)&comment[i+3]); i+=5; } strcat(text,temp); out_line(text,"","",""); } break; case TCTYPDEF: sprintf(text, "; Type definition: index %02X ",*(int*)&comment[0]); i = 1; if (comment[1]) { sprintf(temp, "\"%.*s\", ",comment[1],&comment[2]); /* name */ strcat(text,temp); } i+=comment[i]+1; sprintf(temp, "size %04X, TID %02X",*(int*)&comment[i],comment[i+2]); strcat(text,temp); out_line(text,"","",""); break; case TCSOURCE : if (!*comment) { i = 1; sprintf(text, "; Source file %.*s",comment[1],&comment[2]); i+=comment[1]+1; sprint_date(temp,&comment[i]); out_line(text,temp,"",""); } else { out_line("; Source file","","",""); } break; case TCXLATOR : strcpy(text, "; Compiler: "); switch (*comment) { case 0x01: strcat(text,"'C'"); break; case 0x04: strcat(text,"Assembler"); break; default : strcat(text,"[unknown]"); break; } sprintf(temp, " using %s model with underscores %s", models[comment[1]&7],comment[1]&8?"on":"off"); strcat(text,temp); out_line(text,"","",""); break; case TCENUM : i = 1; out_line("; ENUM member list","","",""); while (i