/* SCCSID = @(#)newpri.c 4.7 86/09/23 */ /* * Copyright Microsoft Corporation, 1983-1987 * * This Module contains Proprietary Information of Microsoft * Corporation and should be treated as Confidential. */ /* MAP file printer */ /**************************************************************** * * * NEWPRI.C * * * ****************************************************************/ #include /* Types and constants */ #include /* Basic type & const declarations */ #include /* Types and constants */ #include /* Linker I/O definitions */ #include /* Error messages */ #include #include /* External declarations */ #include #if EXE386 #include #endif #include #define parent(i) (((i) - 1) >> 1)/* Parent of i */ #define lchild(i) (((i) << 1) + 1)/* Left child of i */ #define rchild(i) (((i) << 1) + 2)/* Right child of i */ #define isleft(i) ((i) & 1) /* True if i is a left child */ RBTYPE *mpsymrbExtra; /* Sort table for extra symbols */ RBTYPE *ompsymrb; /* Stack-allocated sort table */ WORD stkMax; /* Max # of symbols on stack */ LOCAL FTYPE fGrps; /* True if there are groups */ /* * LOCAL FUNCTION PROTOTYPES */ LOCAL void NEAR ChkMapErr(void); LOCAL void NEAR PrintOne(BYTE *sbName, APROPNAMEPTR apropName); LOCAL void NEAR PrintProp(RBTYPE rb, FTYPE attr); LOCAL void NEAR PrintSyms(WORD irbMac, FTYPE attr); LOCAL void SaveHteSym(APROPNAMEPTR prop, RBTYPE rhte, RBTYPE rprop, WORD fNewHte); LOCAL void NEAR PutSpaces(int HowMany); LOCAL void NEAR HdrExport(FTYPE attr); LOCAL void NEAR ShowExp(AHTEPTR ahte, RBTYPE rprop); LOCAL void NEAR PrintExps(WORD irbMac, FTYPE attr); LOCAL void NEAR HdrName(FTYPE attr); LOCAL void NEAR HdrValue(FTYPE attr); LOCAL void NEAR PrintContributors(SNTYPE gsn); #if AUTOVM extern BYTE FAR * NEAR FetchSym1(RBTYPE rb, WORD Dirty); #define FETCHSYM FetchSym1 #else #define FETCHSYM FetchSym #endif LOCAL void NEAR ChkMapErr(void) { if (ferror(bsLst)) { ExitCode = 4; Fatal(ER_spclst); /* Fatal error */ } } LOCAL void NEAR PrintOne(sbName,apropName) BYTE *sbName; /* Symbol name */ REGISTER APROPNAMEPTR apropName; /* Symbol definition record pointer */ { SBTYPE sbImp; /* Import name */ SATYPE sa; /* Symbol base */ RATYPE ra; /* Symbol offset */ SEGTYPE seg; /* Segment number */ BYTE FAR *pb; #if EXE386 typedef struct impMod { DWORD am_Name; // Imported module name RBTYPE am_1stImp; // Head of imported names list RBTYPE am_lastImp; // Tail of imported names list DWORD am_count; // Module number/count of imports } IMPMOD; DWORD entry; IMPMOD *curMod; // Imported module #else WORD entry; #endif WORD module; WORD flags; SNTYPE gsn; #if NOT OIAPX286 APROPSNPTR papropSn; SATYPE saGroup; #endif SBTYPE sbUndecor; /* * Store all needed fields in local variables, because * page containing symbol definition record can be * swapped out. */ ra = apropName->an_ra; gsn = apropName->an_gsn; flags = apropName->an_flags; #if OSEGEXE #if EXE386 entry = apropName->an_name; #else entry = apropName->an_entry; #endif module = apropName->an_module; #endif if(gsn) /* If not absolute symbol */ { seg = mpgsnseg[gsn]; /* Get segment number */ sa = mpsegsa[seg]; /* Get base value */ #if NOT OIAPX286 if(!fNewExe && seg <= segLast) { papropSn = (APROPSNPTR ) FETCHSYM(mpgsnrprop[gsn], FALSE); if(papropSn->as_ggr != GRNIL) { saGroup = mpsegsa[mpgsnseg[mpggrgsn[papropSn->as_ggr]]]; ra += (sa - saGroup) << 4; sa = saGroup; } } #endif } else sa = 0; /* Else no base */ if (flags & FUNREF) { sa = 0; ra = 0L; } #if EXE386 fprintf(bsLst," %04X:%08lX",sa,ra); #else #if O68K if (f386 || f68k) #else if (f386) #endif fprintf(bsLst," %04X:%08lX",sa,ra); else fprintf(bsLst," %04X:%04X",sa, (WORD) ra); #endif /* Write address */ #if OSEGEXE if (fNewExe && (flags & FIMPORT)) fputs(" Imp ",bsLst); /* If public is an import */ else #endif if (flags & FUNREF) fputs(" Unr ", bsLst); else if ((!gsn || seg > segLast)) fputs(" Abs ",bsLst); /* Segment type */ #if OVERLAYS else if (fOverlays) { if(mpsegiov[seg] != IOVROOT) fputs(" Ovl ",bsLst); else fputs(" Res ",bsLst); } #endif else PutSpaces(7); OutSb(bsLst,sbName); /* Output the symbol */ #if NOT WIN_NT if (fFullMap && sbName[1] == '?') { fputs("\n", bsLst); UndecorateSb(sbName, sbUndecor, sizeof(sbUndecor)); #if EXE386 PutSpaces(24); #else #if O68K if (f386 || f68k) #else if (f386) #endif PutSpaces(24); else PutSpaces(20); #endif OutSb(bsLst, sbUndecor); fputs("\n", bsLst); #if OSEGEXE if (fNewExe && flags & FIMPORT) PutSpaces(24); #endif } #endif #if OSEGEXE if (fNewExe && flags & FIMPORT) { /* If public is an import */ PutSpaces(20 - B2W(sbName[0])); /* Space fill */ /* Print the module name */ #if EXE386 // Get known import module descriptor curMod = (IMPMOD *) mapva(AREAMOD + module * sizeof(IMPMOD), FALSE); strcpy(&sbImp[1], mapva(AREAIMPMOD + curMod->am_Name, FALSE)); /* Get module name */ sbImp[0] = (BYTE) strlen((char *) &sbImp[1]); #else pb = &(ImportedName.rgByte[ModuleRefTable.rgWord[module-1]]); FMEMCPY(sbImp, pb, pb[0] + 1); #endif fputs(" (",bsLst); /* Print module name */ OutSb(bsLst,sbImp); if(!(flags & FIMPORD)) { /* If not imported by ordinal */ /* Print the entry name */ #if EXE386 strnset((char *) sbImp, '\0', sizeof(sbImp)); vmmove(sizeof(sbImp) - 1, &sbImp[1], AREAIMPS + entry + sizeof(WORD), FALSE); sbImp[0] = (BYTE) strlen((char *) &sbImp[1]); fputc('!',bsLst); #else pb = &(ImportedName.rgByte[entry]); FMEMCPY(sbImp, pb, pb[0]+1); fputc('.',bsLst); #endif OutSb(bsLst,sbImp); fputc(')',bsLst); } else fprintf(bsLst,".%u)",entry); /* Else print entry number */ NEWLINE(bsLst); return; } #endif /* OSEGEXE */ #if OVERLAYS if (fOverlays && gsn && seg <= segLast && mpsegiov[seg] != IOVROOT) fprintf(bsLst," (%XH)",mpsegiov[seg]); #endif NEWLINE(bsLst); ChkMapErr(); } /* * PrintProp: * * Print a symbol, given a virtual property address or hash table * entry. Called by PrintSyms. */ LOCAL void NEAR PrintProp (rb, attr) RBTYPE rb; ATTRTYPE attr; /* Symbol attribute */ { #if NOT NEWSYM APROPNAMETYPE apropName; /* Buffer for symbol def */ #endif AHTEPTR pahte; /* Pointer to hash table entry */ APROPPTR paprop; /* Pointer to property cell */ SBTYPE sbName; /* Public symbol text */ RBTYPE rprop; /* Property cell virtual address */ paprop = (APROPPTR ) FETCHSYM(rb,FALSE); /* Fetch property cell from VM */ if(paprop->a_attr == ATTRNIL) /* If we have a hash table entry */ { pahte = (AHTEPTR ) paprop; /* Recast pointer */ memcpy(sbName,GetFarSb(pahte->cch),B2W(pahte->cch[0]) + 1); /* Copy the symbol */ paprop = (APROPPTR ) FETCHSYM(pahte->rprop,FALSE); /* Get pointer to property list */ while(paprop->a_attr != ATTRNIL) { /* Look through properties */ rprop = paprop->a_next; /* Save link to next cell */ if(paprop->a_attr == attr) { /* If match found */ #if NEWSYM PrintOne(sbName,(APROPNAMEPTR)paprop); #else memcpy(&apropName,paprop,CBPROPNAME); /* Copy record from virtual memory */ PrintOne(sbName,&apropName); /* Print the symbol entry */ #endif } paprop = (APROPPTR ) FETCHSYM(rprop,FALSE); /* Try next in list */ } return; /* Done */ } #if NOT NEWSYM memcpy(&apropName,paprop,CBPROPNAME); /* Save record in buffer */ #endif while(paprop->a_attr != ATTRNIL) /* Find symbol */ paprop = (APROPPTR ) FETCHSYM(paprop->a_next,FALSE); pahte = (AHTEPTR ) paprop; /* Recast pointer */ memcpy(sbName,GetFarSb(pahte->cch),B2W(pahte->cch[0]) + 1); /* Copy the symbol */ /* Print the symbol entry */ #if NEWSYM PrintOne(sbName,(APROPNAMEPTR)FETCHSYM(rb,FALSE)); #else PrintOne(sbName,&apropName); #endif } /**************************************************************** * * * PrintSyms: * * * ****************************************************************/ LOCAL void NEAR PrintSyms(irbMac,attr) WORD irbMac; /* Table size */ ATTRTYPE attr; /* Symbol attribute */ { WORD x; /* Sort table index */ for (x = irbMac; x > 0; x--) PrintProp(ExtractMin(x), attr); } /*************************************************************** * * * SavePropSym: * * * ****************************************************************/ void SavePropSym(APROPNAMEPTR prop, RBTYPE rhte, RBTYPE rprop, WORD fNewHte) { if(prop->an_attr != ATTRPNM || (prop->an_flags & FPRINT)) { /* If printable, save ptr to info */ Store(rprop); } return; } /**************************************************************** * * * SaveHteSym: * * * ****************************************************************/ LOCAL void SaveHteSym(APROPNAMEPTR prop, RBTYPE rhte, RBTYPE rprop, WORD fNewHte) { if(fNewHte && (prop->an_attr != ATTRPNM || (prop->an_flags & FPRINT))) { /* If first time and printable */ Store(rhte); } return; } /* * FGtAddr: * * Compare addresses of symbols pointed to by rb1 and rb2. Return * -1, 0, or 1 as the address of rb1 is less than, equal to, or greater * than the address of rb2. */ int cdecl FGtAddr(const RBTYPE *rb1, const RBTYPE *rb2) { APROPNAMEPTR paprop; /* Property cell pointer */ REGISTER SEGTYPE seg1; /* Segment number */ REGISTER SEGTYPE seg2; WORD sa1; /* Segment base */ WORD sa2; RATYPE ra1; RATYPE ra2; DWORD ibMem1; /* Memory address */ DWORD ibMem2; paprop = (APROPNAMEPTR ) FETCHSYM(*rb1,FALSE); /* Fetch from VM */ seg1 = paprop->an_gsn? mpgsnseg[paprop->an_gsn]: SEGNIL; /* Get segment number */ sa1 = seg1 != SEGNIL? mpsegsa[seg1]: 0; /* Get frame number */ ra1 = paprop->an_ra; paprop = (APROPNAMEPTR ) FETCHSYM(*rb2,FALSE); /* Fetch from VM */ seg2 = paprop->an_gsn? mpgsnseg[paprop->an_gsn]: SEGNIL; /* Get segment number */ sa2 = seg2 != SEGNIL? mpsegsa[seg2]: 0; /* Get frame number */ ra2 = paprop->an_ra; #if OXOUT OR OIAPX286 if(seg1 != SEGNIL && seg2 != SEGNIL) { if((mpsegFlags[seg1] & FCODE) && !(mpsegFlags[seg2] & FCODE)) return(-1); /* Code before data */ if((mpsegFlags[seg2] & FCODE) && !(mpsegFlags[seg1] & FCODE)) return(1); /* Data after code */ } #endif #if OVERLAYS if(fOverlays && seg1 != SEGNIL && seg2 != SEGNIL) { if(mpsegiov[seg1] > mpsegiov[seg2]) return(1); if(mpsegiov[seg2] > mpsegiov[seg1]) return(-1); } #endif #if OSEGEXE if (fNewExe) { #if EXE386 if (sa1 == sa2) { ibMem1 = ra1; ibMem2 = ra2; } else ibMem1 = ibMem2 = 0L; #else ibMem1 = ((long) sa1 << 16) + ra1; ibMem2 = ((long) sa2 << 16) + ra2; #endif } else { #endif ibMem1 = ((long) sa1 << 4) + ra1; ibMem2 = ((long) sa2 << 4) + ra2; #if OSEGEXE } #endif #ifdef LATER if ((sa1 != 0 || sa2 != 0) && (sa1 != 0xa9 || sa2 != 0xa9)) fprintf(stderr, "%x:%x %x:%x (%d)\r\n", sa1, paprop1->an_ra, sa2, paprop2->an_ra, (ibMem1 > ibMem2) ? 1 : ((ibMem1 < ibMem2) ? -1 : 0)); #endif /*!LATER*/ if (ibMem1 < ibMem2) return(-1); if (ibMem1 > ibMem2) return(1); #if EXE386 if (sa1 < sa2) return(-1); if (sa1 > sa2) return(1); #endif return(0); } /* * FGtName: * * Compare names of two symbols pointed to by rb1 and rb2. Return * -1, 0, 1 as the name of rb1 is alphabetically less than, equal to, * or greater than the name of rb2. * Ignore case. */ int cdecl FGtName(const RBTYPE *rb1, const RBTYPE *rb2) { AHTEPTR pahte1; /* Hash table pointer */ AHTEPTR pahte2; REGISTER BYTE *ps1; /* Pointer to first symbol */ REGISTER BYTE FAR *ps2; /* Pointer to second symbol */ WORD len1; /* Symbol length */ WORD len2; /* Symbol length */ WORD length; /* No. of char.s to compare */ int value; /* Comparison value */ pahte1 = (AHTEPTR ) FETCHSYM(*rb1,FALSE); /* Fetch from VM */ ps1 = GetFarSb((BYTE FAR *) pahte1->cch); /* Get pointer to first */ pahte2 = (AHTEPTR ) FETCHSYM(*rb2,FALSE); /* Fetch from VM */ ps2 = (BYTE FAR *) pahte2->cch; /* Get pointer to second */ if((len1 = B2W(*ps1)) < (len2 = B2W(*ps2))) length = len1; else length = len2; /* Get smallest length */ while(length--) /* While not at end of symbol */ if(value = (*++ps1 & 0137) - (*++ps2 & 0137)) return(value < 0 ? -1 : 1); if(len1 < len2) return(-1); if(len1 > len2) return(1); return(0); } #if OWNSORT /* * An implementation of heapsort follows. It is only used if * quicksort() from the runtime library is not used. */ LOCAL reheap(a,n,i) /* Reheapify */ RBTYPE *a; /* Array to reheapify */ WORD n; /* Size of array */ REGISTER WORD i; /* Subtree to start with */ { REGISTER WORD j; /* Index */ RBTYPE t; /* Temporary */ for(; (j = rchild(i)) < n; i = j) /* Loop through array */ { if((*cmpf)(&a[i],&a[j]) > 0 && (*cmpf)(&a[i],&a[j - 1]) > 0) return; /* Done if subtree is heap */ if((*cmpf)(&a[j - 1],&a[j]) > 0) --j; /* Pick "greater" child */ t = a[i]; /* Swap parent and child */ a[i] = a[j]; a[j] = t; } if(--j < n && (*cmpf)(&a[j],&a[i]) > 0) /* If swap needed */ { t = a[i]; /* Swap parent and child */ a[i] = a[j]; a[j] = t; } } LOCAL heap(a,n) /* Heapify */ RBTYPE *a; /* Array to heapify */ WORD n; /* Size of array */ { REGISTER WORD k; /* Index to "kid" */ REGISTER WORD p; /* Index to "parent" */ RBTYPE t; /* Temporary */ if(n && (k = n - 1)) /* If there are kids */ { if(isleft(k)) /* If youngest kid an only child */ { p = parent(k); /* Find the parent */ if((*cmpf)(&a[k],&a[p]) > 0) /* If swap necessary */ { t = a[k]; /* Swap parent and kid */ a[k] = a[p]; a[p] = t; } --k; /* Index a righty */ } while(k) /* While there are parents */ { p = parent(k); /* Find the parent */ if((*cmpf)(&a[k],&a[p]) > 0 || (*cmpf)(&a[k - 1],&a[p]) > 0) { /* If a kid is "greater" */ t = a[p]; /* Swap parent... */ if((*cmpf)(&a[k],&a[k - 1]) > 0) { /* ...with "greater" kid */ a[p] = a[k]; a[k] = t; reheap(a,n,k--); /* And reheapify */ } else { a[p] = a[--k]; a[k] = t; reheap(a,n,k); /* And reheapify */ } } else --k; /* Point at left kid */ --k; /* Point at right kid */ } } } #endif /* OWNSORT */ /**************************************************************** * * * PrintGroupOrigins: * * * ****************************************************************/ void PrintGroupOrigins(APROPNAMEPTR papropGroup, RBTYPE rhte, RBTYPE rprop, WORD fNewHte) { AHTEPTR hte; APROPGROUPPTR pGroup; pGroup = (APROPGROUPPTR) papropGroup; if (mpggrgsn[pGroup->ag_ggr] != SNNIL) { /* If group has members */ if (!fGrps) /* If no groups yet */ { fputs(GetMsg(MAP_group), bsLst); /* Header */ fGrps = (FTYPE) TRUE; /* Yes, there are groups */ } fprintf(bsLst," %04X:0 ", mpsegsa[mpgsnseg[mpggrgsn[pGroup->ag_ggr]]]); /* Write the group base */ hte = (AHTEPTR ) FETCHSYM(rhte,FALSE); /* Fetch group name */ OutSb(bsLst,GetFarSb(hte->cch));/* Output name */ NEWLINE(bsLst); ChkMapErr(); } } #if OSEGEXE LOCAL void NEAR HdrExport(ATTRTYPE attr) { ASSERT(attr == ATTREXP); /* Must be an export */ fputs(GetMsg(MAP_expaddr), bsLst); #if EXE386 PutSpaces(7); #else if (f386) PutSpaces(7); else PutSpaces(3); #endif fputs(GetMsg(MAP_expexp), bsLst); PutSpaces(18); fputs(GetMsg(MAP_expalias), bsLst); /* Header */ ChkMapErr(); } LOCAL void NEAR ShowExp(ahte,rprop) AHTEPTR ahte; /* Pointer to hash table entry */ RBTYPE rprop; /* Property cell address */ { SBTYPE sbExport; /* Export name */ APROPNAMEPTR apropnam; /* Public definition record */ short i; /* Index */ memcpy(sbExport,GetFarSb(ahte->cch),B2W(ahte->cch[0]) + 1); /* Save the name */ apropnam = (APROPNAMEPTR ) FETCHSYM(rprop,FALSE); /* Fetch alias record */ #if EXE386 fprintf(bsLst," %04X:%08lX ", #else fprintf(bsLst," %04X:%04X ", #endif mpsegsa[mpgsnseg[apropnam->an_gsn]],apropnam->an_ra); /* Print the address */ OutSb(bsLst,sbExport); /* Print the exported name */ for(i = 22 - B2W(sbExport[0]); i > 0; --i) fputc(' ',bsLst); /* Fill with spaces */ fputs(" ",bsLst); /* Skip two spaces */ ahte = GetHte(apropnam->an_next); /* Get the alias name */ OutSb(bsLst,GetFarSb(ahte->cch)); /* Output export name */ NEWLINE(bsLst); ChkMapErr(); } LOCAL void NEAR PrintExps(WORD irbMac, ATTRTYPE attr) { AHTEPTR ahte; /* Pointer to hash table entry */ APROPEXPPTR apropexp; /* Pointer to property cell */ RBTYPE rprop; /* Alias record address */ WORD i; /* Index */ RBTYPE CurrSym; for(i = irbMac; i > 0; i--) /* Loop through sorted symbols */ { CurrSym = ExtractMin(i); ahte = (AHTEPTR ) FETCHSYM(CurrSym,FALSE); /* Fetch hash table entry */ apropexp = (APROPEXPPTR ) FETCHSYM(ahte->rprop,FALSE); /* Fetch property cell */ while(apropexp->ax_attr != attr) { /* Loop to find property cell */ apropexp = (APROPEXPPTR ) FETCHSYM(apropexp->ax_next,FALSE); /* Fetch the next cell in the chain */ } if((rprop = apropexp->ax_symdef) == RHTENIL) continue; ShowExp((AHTEPTR) FETCHSYM(CurrSym,FALSE),rprop); /* Print the export */ /* Save address of alias */ } } #endif /* OSEGEXE */ LOCAL void NEAR PutSpaces(int HowMany) { for (; HowMany > 0; HowMany--) putc(' ', bsLst); ChkMapErr(); } LOCAL void NEAR HdrName(attr) ATTRTYPE attr; /* Symbol attribute type */ { fputs(GetMsg(MAP_hdraddr), bsLst); PutSpaces(9); fputs(GetMsg((MSGTYPE)((attr == ATTRPNM) ? MAP_hdrpubnam : MAP_hdrlocnam)), bsLst); /* Header (MAPSYM keys on "Value") */ ChkMapErr(); } LOCAL void NEAR HdrValue(attr) ATTRTYPE attr; /* Symbol attribute type */ { fputs(GetMsg(MAP_hdraddr), bsLst); PutSpaces(9); fputs(GetMsg((MSGTYPE)((attr == ATTRPNM) ? MAP_hdrpubval : MAP_hdrlocval)), bsLst); /* Header (MAPSYM keys on "Value") */ ChkMapErr(); } /**************************************************************** * * * SortSyms: * * * * List symbols, sorted. * * * ****************************************************************/ void NEAR SortSyms(ATTRTYPE attr, /* Symbol attribute type */ void (*savf)(APROPNAMEPTR prop, RBTYPE rhte, RBTYPE rprop, WORD fNewHte), /* Function to save symbols */ int (cdecl *scmpf)(const RBTYPE *sb1, const RBTYPE *sb2), /* Function to compare symbols */ void (NEAR *hdrf)(ATTRTYPE attr), /* Function to print header */ void (NEAR *lstf)(WORD irbMac, ATTRTYPE attr)) /* Function to list symbols */ { symMac = 0; /* Initialize counter to zero */ cmpf = scmpf; /* Set comparison function */ EnSyms(savf,attr); /* Apply function to symbols */ (*hdrf)(attr); /* Print a header */ (*lstf)(symMac,attr); /* Print them */ } /*** AddContributor - add current file to list * * Purpose: * Add current .OBJ file that contribiute to definition of given * segment. The list of .OBJ files is kept in virtual memory. * Each segment description record has Head and Tail pointers to * its contributor list. * * Input: * gsn - global segment number - linker internal way of * recognizing segments * raComdat - if contribution is comming from a COMDAT symbol * this is its initial offset in the segment * size - contribution size * vrpropFile - pointer to current .OBJ file description - global variable * * Output: * No explicit return value. Updated list of contributors for segment. * * Exceptions: * None. * *************************************************************************/ void AddContributor(SNTYPE gsn, DWORD raComdat, DWORD size) { APROPSNPTR apropSn; /* Pointer to seg. record */ CONTRIBUTOR FAR *NewObj; /* New .OBJ file that contrbiuts to seg */ apropSn = (APROPSNPTR ) FETCHSYM(mpgsnrprop[gsn],FALSE); NewObj = (CONTRIBUTOR FAR *) GetMem(sizeof(CONTRIBUTOR)); /* Build new list element */ NewObj->next = 0L; /* End of list */ NewObj->file = vrpropFile; /* Save global file description pointer */ NewObj->len = size; /* Size of contribution */ if (raComdat != -1L) NewObj->offset = raComdat; else NewObj->offset = mpgsndra[gsn]; /* Attach new record at the list end */ if (apropSn->as_CHead) apropSn->as_CTail->next = NewObj; else apropSn->as_CHead = NewObj; apropSn->as_CTail = NewObj; } /*** PrintContributors - print out list of files * * Purpose: * Print list of .OBJ files that contribute to form given segment. * For each file print number of bytes that it contribute. * * Input: * gsn - global segment number - linker internal way of * recognizing segments * * Output: * No explicit return value. * * Exceptions: * None. * *************************************************************************/ LOCAL void NEAR PrintContributors(SNTYPE gsn) { APROPFILEPTR apropFile; /* Pointer to file property cell */ APROPSNPTR apropSn; /* Pointer to seg. record */ CONTRIBUTOR FAR *pElem; /* Real pointer to list element */ AHTEPTR ahte; /* Pointer symbol name */ SBTYPE sb, sb1; /* String buffers */ int n; /* String length counter */ apropSn = (APROPSNPTR ) FETCHSYM(mpgsnrprop[gsn],FALSE); if (apropSn->as_CHead == NULL) return; /* Print list */ fprintf(bsLst,"\r\n"); pElem = apropSn->as_CHead; do { if(fNewExe || OIAPX286) { #if EXE386 if (f386) fprintf(bsLst," at offset %08lXH %05lXH bytes from", pElem->offset, pElem->len); else #endif fprintf(bsLst," at offset %05lXH %05lXH bytes from", pElem->offset, pElem->len); } else fprintf(bsLst," at offset %05lXH %05lXH bytes from", pElem->offset, pElem->len); apropFile = (APROPFILEPTR ) FETCHSYM(pElem->file,FALSE); ahte = GetHte(pElem->file); for(n = B2W(ahte->cch[0]), sb[n+1] = 0; n >= 0; sb[n] = ahte->cch[n], --n); if (apropFile->af_rMod) { ahte = (AHTEPTR ) FETCHSYM(apropFile->af_rMod,FALSE); while(ahte->attr != ATTRNIL) ahte = (AHTEPTR ) FETCHSYM(ahte->rhteNext,FALSE); for (n = B2W(ahte->cch[0]); n >= 0; --n) sb1[n] = ahte->cch[n]; sb1[1 + B2W(sb1[0])] = '\0'; /* Null-terminate */ fprintf(bsLst, " %s (%s)\r\n", 1 + sb, 1 + sb1); } else fprintf(bsLst," %s\r\n", 1 + sb); ChkMapErr(); pElem = pElem->next; } while (pElem != NULL); } /**************************************************************** * * * PrintMap: * * * ****************************************************************/ void PrintMap(void) { SEGTYPE seg; WORD cch; APROPSNPTR papropSn; AHTEPTR pahte; SNTYPE gsn; RBTYPE rhteClass; /* Virt. addr. of class name */ long addrStart; long addr; #if OVERLAYS IOVTYPE iov; #endif #if OSMSDOS int oldbsize; /* Old file buffer size */ char *oldbase; /* Old file buffer */ #endif WORD flags; #if OSMSDOS #if OWNSTDIO oldbsize = bsLst->_bsize; #else oldbsize = 512; #endif oldbase = bsLst->_base; setvbuf(bsLst,bigbuf,_IOFBF,sizeof(bigbuf)); #endif #if OSEGEXE if(fNewExe && rhteModule != RHTENIL)/* If there is a module name */ { pahte = (AHTEPTR ) FETCHSYM(rhteModule,FALSE); /* Fetch the hash table entry */ fputs("\r\n ",bsLst); /* Indent one space */ OutSb(bsLst,GetFarSb(pahte->cch));/* Print the module name */ NEWLINE(bsLst); ChkMapErr(); } #endif if(fNewExe || OIAPX286) { fputs(GetMsg(MAP_hdrstart), bsLst); #if EXE386 PutSpaces(9); #else if (f386) PutSpaces(9); else PutSpaces(5); #endif fputs(GetMsg(MAP_hdrlen), bsLst); PutSpaces(5); fputs(GetMsg(MAP_hdrname), bsLst); PutSpaces(19); fputs(GetMsg(MAP_hdrclass), bsLst); } else { fputs(GetMsg(MAP_hdrseg86), bsLst); PutSpaces(19); fputs(GetMsg(MAP_hdrclass), bsLst); } ChkMapErr(); #if OVERLAYS for(iov = 0; iov < (IOVTYPE) iovMac; ++iov) { if(fOverlays) { if (iov == IOVROOT) fputs(GetMsg(MAP_resident), bsLst); else fprintf(bsLst, GetMsg(MAP_overlay), iov); ChkMapErr(); } #endif for(seg = 1; seg <= segLast; ++seg) /* Look at all segments */ { #if OVERLAYS if(!fOverlays || mpsegiov[seg] == iov) { #endif if(fNewExe || OIAPX286) { #if EXE386 fprintf(bsLst," %04X:%08lX", mpsegsa[seg],mpsegraFirst[seg]); #else if (f386) fprintf(bsLst," %04X:%08lX", mpsegsa[seg],mpsegraFirst[seg]); else fprintf(bsLst," %04X:%04X",mpsegsa[seg],(int)mpsegraFirst[seg]); #endif ChkMapErr(); } else addrStart = (long) mpsegsa[seg] << 4; for(gsn = 1; gsn < gsnMac; ++gsn) { if(mpgsnseg[gsn] == seg) { papropSn = (APROPSNPTR ) FETCHSYM(mpgsnrprop[gsn],FALSE); rhteClass = papropSn->as_rCla; /* Save key to class name */ #if NOT EXE386 flags = papropSn->as_flags; #endif if(fNewExe || OIAPX286) #if EXE386 fprintf(bsLst," %09lXH ",papropSn->as_cbMx); #else fprintf(bsLst," %05lXH ",papropSn->as_cbMx); #endif else { addr = addrStart + (long) mpsegraFirst[seg]; fprintf(bsLst," %05lXH",addr); if(papropSn->as_cbMx) addr += papropSn->as_cbMx - 1; fprintf(bsLst," %05lXH",addr); fprintf(bsLst," %05lXH ",papropSn->as_cbMx); } pahte = GetHte(papropSn->as_next); /* Get the segment name */ OutSb(bsLst,GetFarSb(pahte->cch)); /* Write segment name */ if(B2W(pahte->cch[0]) > 22) cch = 1; else cch = 23 - B2W(pahte->cch[0]); /* Get number of spaces to emit */ while(cch--) OutByte(bsLst,' '); /* Emit spaces */ pahte = (AHTEPTR ) FETCHSYM(rhteClass,FALSE); /* Fetch class names from VM */ OutSb(bsLst,GetFarSb(pahte->cch)); /* Output class name */ if (fFullMap) { #if EXE386 fprintf(bsLst, " 32-bit"); #else if (Is32BIT(flags)) fprintf(bsLst, " 32-bit"); else fprintf(bsLst, " 16-bit"); #endif PrintContributors(gsn); } NEWLINE(bsLst); ChkMapErr(); break; /* Exit loop */ } } #if OVERLAYS } #endif } #if OVERLAYS } #endif fGrps = FALSE; /* Assume no groups */ EnSyms(PrintGroupOrigins,ATTRGRP); /* Apply function to symbols */ #if OSEGEXE if(vfMap || expMac) #else if(vfMap) #endif { AllocSortBuffer(pubMac > expMac ? pubMac : expMac, TRUE); } #if OSEGEXE if(expMac) { /* Sort or list exported names */ SortSyms(ATTREXP,SaveHteSym,FGtName,HdrExport, PrintExps); } #endif if(vfMap) /* If publics requested */ { if(!fListAddrOnly) SortSyms(ATTRPNM,SaveHteSym,FGtName,HdrName, PrintSyms); /* Sort public symbols by name */ SortSyms(ATTRPNM,SavePropSym,FGtAddr,HdrValue, PrintSyms); /* Sort public symbols by value */ } #if LOCALSYMS if(fLocals) /* If locals requested */ { SortSyms(ATTRLNM,SaveHteSym,FGtName,HdrName, PrintSyms); /* Sort local symbols by name */ SortSyms(ATTRLNM,SavePropSym,FGtAddr,HdrValue, PrintSyms); /* Sort local symbols by value */ } #endif ChkMapErr(); FreeSortBuffer(); #if OSMSDOS setvbuf(bsLst,oldbase,_IOFBF,oldbsize); #endif }