PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 1/22 TITLE : Understanding MAP files generated by the Linker. Understanding MAP files ======================= MAP files are files produced during the Linking phase of program development that show the location of all the different parts of an application including memory segments, variables, program code, the program stack, etc. Borland Linkers are capable of producing four different kinds of .map files: Segments, Publics, Detailed and Dump. The different outputs are controlled by Linker Settings: from the menu in the integrated development environment, and by Command lime parameters for the cmmand line Compilers and the stand alone Linker. The best way to understand map files is to produce minimal map files, examine them, add to them and see the changes brought about by additions. The Segment Map File ==================== The Segment Map File shows the program's various Segments, their locations, their sizes, and their classes for programs linked by the Borland integrated compilers and the stand alone linker. The following two line program can be used to produce a minimal map file. void main(void) { } In the integrated development environment by choose Menu- Options-Linker-Settings-Map File-Segments; from the command line compiler use the -M option option. If the TLINK is called explicitly, the default settings produces a Segment map file. Note that the /x option causes TLINK to not produce any map files. The following is a sample Segment Map file produced by the preceding minimal two line program. ================================================================== PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 2/22 TITLE : Understanding MAP files generated by the Linker. Start Stop Length Name Class 00000H 00C0CH 00C0DH _TEXT CODE 00C10H 00C10H 00000H _FARDATA FAR_DATA 00C10H 00C10H 00000H _FARBSS FAR_BSS 00C10H 00C10H 00000H _OVERLAY_ OVRINFO 00C10H 00C10H 00000H _1STUB_ STUBSEG 00C10H 00E95H 00286H _DATA DATA 00E96H 00E96H 00000H _CVTSEG DATA 00E96H 00E96H 00000H _SCNSEG DATA 00E96H 00E96H 00000H _CONST CONST 00E96H 00E9BH 00006H _INIT_ INITDATA 00E9CH 00E9CH 00000H _INITEND_ INITDATA 00E9CH 00E9CH 00000H _EXIT_ EXITDATA 00E9CH 00E9CH 00000H _EXITEND_ EXITDATA 00E9CH 00EDBH 00040H _BSS BSS 00EDCH 00EDCH 00000H _BSSEND BSSEND 00EE0H 00F5FH 00080H _STACK STACK Program entry point at 0000:0000 ================================================================== As you can see a lot of segments were created for a two line program. Actually, only three segments were created for the program itself: _TEXT, _DATA and _BSS. The rest were created by the start up code C0x where x is the memory model. In fact if you link the two line program without the start-up library via TLINK myprog,myprog,myprog, a map file with only the following three segments will be produced: _TEXT, _DATA, and _BSS. _TEXT will be the only segment with anything in it, _DATA and _BSS will be empty. The map file reproduced above is basically a table with five fields: Start,Stop, Length, Name and Class. Let us examine each field in detail. The 'Start' field refers to the spot in memory where memory segment would reside in, if the program was loaded at the absolute location 00000H. No DOS application is really loaded into position 00000H of memory because in the IBM PC family of computers position 00000H, or zero page, is used for the interrupt vector table. Loading a program onto the zero page would most likely cause the computer to crash. Instead a program is loaded higher into memory. In order to relate the start and PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 3/22 TITLE : Understanding MAP files generated by the Linker. stop memory locations of a map file for a DOS program to the actual memory locations that the segments reside in, use the stand alone Turbo-Debugger to find the start address ( also known as PSP, Program Segment Prefix ) of the program. The program load position can be found in the stand alone debugger by Menu- View-CPU and looking at the CS register. For the example above ( assuming the small memory model ) the CS register contains the location of the Code Segment in memory, which corresponds to the _TEXT of the Segment Map file. For DOS applications compiled in the Medium, Large or Huge memory model, the variable _psp can be used to determined the PSP of the application. ( NOTE: _psp can also be used in the tiny, small or compact models too ). All Start and Stop Fields of the Segment map should be incremented by the value of the _psp to obtain their actual locations in memory. NOTE: Relating a map file to the true memory locations in a Windows program is a little bit more complex than for a DOS application because Windows uses a descriptor table and selectors which creates an extra level of indirection. Hence the map files of Windows applications contain a logical number for the 'Start' field and does not contain any 'Stop' fields. The 'Stop' field refers to the position in memory that the segment would stop at if the program was loaded into position 00000H of memory. The 'Length' field refers to the length of the segment. Sometimes the 'Length' field is larger then the actual amount of data/code declared for the segment because it is padded to allow it to end on a boundary, for example a WORD boundary. The 'Name' field is used to give a unique identifier to each segment while the 'Class' field is normally used to identify what kind of information is contained in the segment. ( NOTE: The 'Class' of a segment is usually assigned based on the contents/function of the segment. However, the 'Class' field is also intimately related to ordering of segments ). Since the order of segments is very important in an Executable, and 'Class' names dictate the placement of segments, the Borland Startup Code defines all the pertinent segment classes in the order expected so that they may serve as placeholders. This is why it is very important that the Linker always *sees* the Borland StartupCode ( c0x.obj, c0wx.obj or c0dx.obj for DOS, Windows .EXEs and Windows DLLs respectively ) PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 4/22 TITLE : Understanding MAP files generated by the Linker. prior to reading any other .OBJs or .LIB files. Several of the segments/classes defined by the Borland StartupCode are actually included for compatibility with OBJs and LIBs produced by other programming tools. NOTE: Do not remove or insert segment definitions in the Borland Startupcode unless you're familiar with both the stack resizing performed by the StartupCode and the internals of the memory allocation helper functions of the Borland RunTime Library. The following table lists the various classes defined by the Borland startup code along with a description of the segment's main usage: CODE The CODE class is where the programs CODE resides. It is created from Assembler via the CODESEG directive. From C and C++ the actual program code will be put into CODE class segments. For example, adding the following line between the curly brackets of our two line minimal program will increase the size of the CODE segment class in the map file: int a = 12 + 15; _TEXT is the name for the primary Code Segment. Multiple module programs in a far code memory model will contain _TEXT for the primary code segment and a Code Segment for each Module, named the ModuleName_TEXT; for example, a module name MYPROG.CPP will generate a code segment by the name of MYPROG_TEXT. For a good example of a multiple module program generate a map file of TVDEMO from the C:\BORLANDC\TVISION\DEMOS directory. FAR_DATA The FAR_DATA segment class is defined by the Assembler directive 'FARDATA'. Typically FAR_DATA classes contains initialized far data. The Borland C and C++ compilers store initialized far data in FAR_DATA class segments. In a C or C++ program the far keyword can be used to force data into a FAR_DATA segment class. For example add the following line to the minimal program *before* the main function (i.e. make a global variable): PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 5/22 TITLE : Understanding MAP files generated by the Linker. char far szTestStr[80] = "Hi There"; It will create a new segment of class FAR_DATA to contain the initialized variable szTestStr. Another way to force data into a FAR_DATA segment is by activating automatic far data and setting the threshold low enough so that the data is forced far. In order for automatic far data to work correctly, the compiler must be in a memory model that supports far data, such as the Large memory model. In the IDE Automatic Far data is activated by Menu-Options-Compiler-Advanced CodeGeneration. Once in the correct Menu dialog box click the Automatic Far Data check box to on and edit the Far Data Threshold field down to 60. Change the data declaration to: char szTestStr[80] = "Hi There"; The map file will show the data going into a far segment. The command line compilers can activate the same automatic far data threshold with the command line options '-Ff=60 -ml'. FAR_BSS The FAR_BSS segment class is defined by the Assembler directive of UFARDATA. FAR_BSS classes typically contain uninitialized Far data. Some Assemblers and Compilers put data into FAR_BSS. The Borland C++ Compilers puts uninitialized far data into FAR_DATA class segments along with the initialized far data. OVRINFO The OVERINFO segment class is used for information pertaining overlay support. The Borland C++ uses this segment for applications using VROOMM. STUBSEG The STUBSEG segment class contains thunks used for overlay support. For every module overlayed in VROOMM, there is a STUBSEG segment which contains the thunks for the various entry points to the module. BEGDATA The BEGDATA segment class is the first segment of DGROUP ( DGROUP is a collection of segments containing the near data of an application and a near heap, if PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 6/22 TITLE : Understanding MAP files generated by the Linker. applicable - In Windows applications, DGROUP also contains the application's stack ). DATA The DATA segment class is defined in Assembler by the segment directive DATASEG. It contains initialized near data from all object modules and libraries. In C and C++, data can be put into DATA class segment through a global/static variable declaration. For example, the following line added to our minimal example program prior to the main procedure will increase the size of a DATA class segment. char szMyLine[80] = "Hi There"; Automatic far data should be turned off or the threshold set higher than 80 for the preceding declaration to put the data into a DATA class segment. CONST The CONST segment class is defined in Assembler by the segment directive CONST. It is used by some Assemblers and Compilers to designate a segment to house constant data ( i.e. readonly data ). This is another placeholder as the Borland C and C++ compilers do not store constants in this segment class. INITDATA The INITDATA segment class contains two named segment identifiers: _INIT_ and _INITEND_. The _INIT_ segment contains a table that the start-up code uses for initializations prior to executing the main() or WinMain() functions provided by the programmer. To add data to this segment declare a global or static instance of a class containing a constructor. The compiler will add an entry to the _INIT_ segment which will ensure that the class initialization takes place prior to the execution of main() or WinMain(). To see an example of the above, declare a global instance of a 'TodoWindow' to the TODOLIST.CPP file. For example: TodoWindow AnotherTodo; TODOLIST.CPP is part of the TODO.PRJ, located in C:\BORLANDC\EXAMPLES\WIN30. Also contained in the _INIT_ segment are entries for functions used in a PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 7/22 TITLE : Understanding MAP files generated by the Linker. '#pragma startup' statement. Similarly the compiler inserts an entry in the segment so that the specified function is called before the execution of main()/WinMain(). The _INITEND_ segment is a placeholder to mark the end of _INIT_. EXITDATA The EXITDATA segment class also contains two named segments _EXIT_ and _EXITEND_. It contains a table of functions that the start-up code calls after the execution of main()/WinMain() but prior to program termination. Being the conterpart of _INIT_, _EXIT_ contains entries for global/static objects' destructors and functions specified in a '#pragma exit' function. The _EXITEND_ segment is a placeholder for the end of the _EXIT_ segment ( aka Exit Table ). NOTE: If either the _INIT_ or _EXIT_ table is corrupted or if a constructor or 'pragma startup/exit' function misbehaves, an application may terminately prematurely ( i.e. prior to reaching main()/WinMain() ) or may exhibit unexpected behaviours after the program returns from main()/WinMain(). Furthermore, loading a application with a offending constructor or '#pragma startup' function, may cause the latter to terminate even before main()/WinMain() is reached ( Use the -l option with the Borland Debuggers to investigate cases where your application is terminating prior to executing main()/WinMain() ). BSS The BSS segment class is defined in Assembler by the UDATASEG directive. Segments of the BSS class contain uninitialized near data. In C and C++ uninitialized near data can be put into a BSS segment class by declaring global data. For example adding the following line to the minimum example prior to main will add to a BSS segment class. char myLine[80]; BSSEND The BSSEND segment class is a placeholder for the end of the BSS segment area. ( NOTE: It is very important that BSSEND *follows* BSSEND since it is used as a marker of the initialization of uninitialized data to NULL at startup time ). PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 8/22 TITLE : Understanding MAP files generated by the Linker. STACK The STACK segment class is defined in Assembler by the STACK directive. It defines the area that the stack will occupy. In the Borland C and C++ DOS compilers this area is defined as 80H in size. Even if the stack is set larger with the _stklen global variable. The stack size will still show up in the map files as 80H. This is because 80H is the size it starts out as and is increased to the value in _sklen later by the start-up code. Windows programs map files do not contain a segment of class STACK since the stack of a Windows Executable is built at runtime ( see. the Windows API INITTASK for more information ). The last thing that the Segment map will contain is the program entry point if the program were loaded at 0000:0000. This is where the start-up code starts and is typically 0000:0000. As with the start and stop fields this location should by incremented by the value in CS for DOS application to find the real entry point for a program in memory. The Publics Map File ==================== The second type of Map file that the Borland Compilers and Linker can produce is the Publics Map File. To produce a Publics Map file from the integrated development environment set Menu-Options-Linker-Settings-Map File to Publics. From the Command Line compiler use the -M qualifier. With the Stand Alone Linker use the /m qualifier. Our minimal example program produces the following Publics Map file. ======================================================================= Start Stop Length Name Class 00000H 01096H 01097H _TEXT CODE 01097H 0109BH 00005H DOSMNMAP_TEXT CODE 010A0H 010A0H 00000H _FARDATA FAR_DATA 010A0H 010A0H 00000H _FARBSS FAR_BSS 010A0H 010A0H 00000H _OVERLAY_ OVRINFO 010A0H 010A0H 00000H _1STUB_ STUBSEG 010A0H 0135FH 002C0H _DATA DATA PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 9/22 TITLE : Understanding MAP files generated by the Linker. 01360H 01360H 00000H _CVTSEG DATA 01360H 01360H 00000H _SCNSEG DATA 01360H 01360H 00000H _CONST CONST 01360H 01365H 00006H _INIT_ INITDATA 01366H 01366H 00000H _INITEND_ INITDATA 01366H 01366H 00000H _EXIT_ EXITDATA 01366H 01366H 00000H _EXITEND_ EXITDATA 01366H 013E5H 00080H _BSS BSS 013E6H 013E6H 00000H _BSSEND BSSEND 013F0H 0146FH 00080H _STACK STACK Address Publics by Name 010A:0000 DATASEG@ 0000:0291 DGROUP@ 0000:0358 F_LXLSH@ 0000:0379 F_PADD@ 0000:03A8 F_PSUB@ 0000:0358 LXLSH@ 0000:0355 N_LXLSH@ 0000:0376 N_PADD@ 0000:045B N_PCMP@ 0000:03A5 N_PSUB@ 0000:0379 PADD@ 0000:03A8 PSUB@ 0000:027A _abort 0000:0295 _atexit 010A:007F _errno 0000:031A _exit 0000:0676 _farfree 0000:078A _farmalloc 0000:08EE _farrealloc 0000:0AC4 _fflush 0000:0B91 _flushall 0000:0676 _free 0000:0C55 _fseek 0000:0CD5 _ftell 0000:0421 _isatty 0000:0432 _lseek 0109:0007 _main 0000:0780 _malloc 0000:08E7 _realloc 0000:0AA8 _setblock PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 10/22 TITLE : Understanding MAP files generated by the Linker. 0000:0DB5 _setvbuf 0000:1000 Abs __AHINCR 0000:000C Abs __AHSHIFT 010A:0094 __atexitcnt 010A:02C6 __atexittbl 0000:09DE __brk 010A:008B __brklvl 010A:006B __C0argc 010A:006D __C0argv 010A:0071 __C0environ 0000:033B __cexit 0000:016A __checknull 0000:0157 __cleanup 0000:0349 __c_exit 010A:025C __doserrno 0000:040F __DOSERROR 010A:025E __dosErrorToSV 010A:0075 __envLng 010A:0077 __envseg 010A:0079 __envSize 0000:0329 __exit 010A:0096 __exitbuf 010A:009A __exitfopen 010A:009E __exitopen 010A:0087 __heapbase 010A:008F __heaptop 010A:005B __Int0Vector 010A:005F __Int4Vector 010A:0063 __Int5Vector 010A:0067 __Int6Vector 0000:03D6 __IOERROR 0000:0293 __MMODEL 010A:0232 __nfile 010A:0234 __openfd 010A:007D __osmajor 010A:007E __osminor 010A:007D __osversion 010A:007B __psp 010A:02C0 __RealCvtVector 0000:01C0 __restorezero 0000:0A1D __sbrk 010A:02C0 __ScanTodVector 0000:047C __setupio PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 11/22 TITLE : Understanding MAP files generated by the Linker. 010A:0081 __StartTime 010A:02B8 __stklen 010A:00A2 __streams 0000:016B __terminate 010A:007D __version 0000:1023 __write 0000:105F __xfflush 010A:0085 ___brklvl 0000:0536 ___first 0000:0538 ___last 0000:053A ___rover 0000:0ED2 ___write Address Publics by Value 0000:000C Abs __AHSHIFT 0000:0157 __cleanup 0000:016A __checknull 0000:016B __terminate 0000:01C0 __restorezero 0000:027A _abort 0000:0291 DGROUP@ 0000:0293 __MMODEL 0000:0295 _atexit 0000:031A _exit 0000:0329 __exit 0000:033B __cexit 0000:0349 __c_exit 0000:0355 N_LXLSH@ 0000:0358 F_LXLSH@ 0000:0358 LXLSH@ 0000:0376 N_PADD@ 0000:0379 F_PADD@ 0000:0379 PADD@ 0000:03A5 N_PSUB@ 0000:03A8 F_PSUB@ 0000:03A8 PSUB@ 0000:03D6 __IOERROR 0000:040F __DOSERROR 0000:0421 _isatty 0000:0432 _lseek 0000:045B N_PCMP@ 0000:047C __setupio PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 12/22 TITLE : Understanding MAP files generated by the Linker. 0000:0536 ___first 0000:0538 ___last 0000:053A ___rover 0000:0676 _free 0000:0676 _farfree 0000:0780 _malloc 0000:078A _farmalloc 0000:08E7 _realloc 0000:08EE _farrealloc 0000:09DE __brk 0000:0A1D __sbrk 0000:0AA8 _setblock 0000:0AC4 _fflush 0000:0B91 _flushall 0000:0C55 _fseek 0000:0CD5 _ftell 0000:0DB5 _setvbuf 0000:0ED2 ___write 0000:1000 Abs __AHINCR 0000:1023 __write 0000:105F __xfflush 0109:0007 _main 010A:0000 DATASEG@ 010A:005B __Int0Vector 010A:005F __Int4Vector 010A:0063 __Int5Vector 010A:0067 __Int6Vector 010A:006B __C0argc 010A:006D __C0argv 010A:0071 __C0environ 010A:0075 __envLng 010A:0077 __envseg 010A:0079 __envSize 010A:007B __psp 010A:007D __osversion 010A:007D __osmajor 010A:007D __version 010A:007E __osminor 010A:007F _errno 010A:0081 __StartTime 010A:0085 ___brklvl 010A:0087 __heapbase 010A:008B __brklvl PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 13/22 TITLE : Understanding MAP files generated by the Linker. 010A:008F __heaptop 010A:0094 __atexitcnt 010A:0096 __exitbuf 010A:009A __exitfopen 010A:009E __exitopen 010A:00A2 __streams 010A:0232 __nfile 010A:0234 __openfd 010A:025C __doserrno 010A:025E __dosErrorToSV 010A:02B8 __stklen 010A:02C0 __ScanTodVector 010A:02C0 __RealCvtVector 010A:02C6 __atexittbl Program entry point at 0000:0000 ========================================================================= A Publics Map File contains the same Segment Map as the Segment Map File plus two tables containing the Public symbols in the program. The first Public name table is called 'Publics by Name' and contains the public symbols in Alphabetic order. The second Public Name table is called 'Publics by Value' and contains the same symbols in memory location order. The records in both tables contain three fields: Memory Location, Qualifier and Symbol Name. The 'memory location' is the location that the variable would reside at if the program was loaded into memory location 0000:0000. As DOS applications are not loaded into the zero page, to get the real memory location to use with the debugger add the PSP ( available from the _psp variable ) to the values in the memory location field. The qualifier field contains extra data about the symbols. Abs :means that the symbol is at an absolute offset address. idle :means that the symbol is not used by the application or is only used locally within the module where it is defined. The linker is basically indicating that the symbol was not required for any fixupps. Note that 'Idle' doesn't necessarily mean that the symbol isn't used at all. It just means that it isn't used outside PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 14/22 TITLE : Understanding MAP files generated by the Linker. of the module where it is defined. Programmers, in an attempt to make an application slimer, may mistakenly remove functions which although flagged as 'idle' by the linker, are required to compile a particular module/library/application. To find out functions that are truely used or unused, the OBJXREF.EXE and TCREF.EXE utilities should be used to generate a 'call tree'. See the utilities documentation ( UTILS.DOC as of this writing ) for more information about OBJXREF and TCREF. The name field contains the names for all public symbols from all modules, start-up code, and libraries used for the link. If some of the experiments that were performed to see the segments change are repeated with the Public Symbol Map file activated, the memory locations of the various global variables we added will be shown. By comparing the memory locations of the symbols with the memory ranges of the segments, the segment location of different symbols can be verified. The Detailed Map File ===================== The third type of map file that the Borland Compilers and Linker can produce is the Detailed Map File. To produce a Detailed Map file from the integrated development environment set Menu-Options-Linker-Settings-Map File to Detailed. From the Command Line compiler use the -ls qualifier. With the Stand Alone Linker use the /s qualifier. For our minimal example program the following detailed Map file is produced. ========================================================================= Start Stop Length Name Class 00000H 01096H 01097H _TEXT CODE 01097H 0109BH 00005H DOSMNMAP_TEXT CODE 010A0H 010A0H 00000H _FARDATA FAR_DATA 010A0H 010A0H 00000H _FARBSS FAR_BSS 010A0H 010A0H 00000H _OVERLAY_ OVRINFO 010A0H 010A0H 00000H _1STUB_ STUBSEG 010A0H 0135FH 002C0H _DATA DATA PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 15/22 TITLE : Understanding MAP files generated by the Linker. 01360H 01360H 00000H _CVTSEG DATA 01360H 01360H 00000H _SCNSEG DATA 01360H 01360H 00000H _CONST CONST 01360H 01365H 00006H _INIT_ INITDATA 01366H 01366H 00000H _INITEND_ INITDATA 01366H 01366H 00000H _EXIT_ EXITDATA 01366H 01366H 00000H _EXITEND_ EXITDATA 01366H 013E5H 00080H _BSS BSS 013E6H 013E6H 00000H _BSSEND BSSEND 013F0H 0146FH 00080H _STACK STACK Detailed map of segments 0000:0000 0295 C=CODE S=_TEXT G=(none) M=c0.ASM ACBP=28 0000:0295 002D C=CODE S=_TEXT G=(none) M=ATEXIT ACBP=28 0000:02C2 0093 C=CODE S=_TEXT G=(none) M=EXIT ACBP=28 0000:0355 0000 C=CODE S=_TEXT G=(none) M=FILES ACBP=28 0000:0355 0000 C=CODE S=_TEXT G=(none) M=FILES2 ACBP=28 0000:0355 0021 C=CODE S=_TEXT G=(none) M=H_LLSH ACBP=28 0000:0376 0060 C=CODE S=_TEXT G=(none) M=H_PADD ACBP=28 0000:03D6 004B C=CODE S=_TEXT G=(none) M=IOERROR ACBP=28 0000:0421 0011 C=CODE S=_TEXT G=(none) M=ISATTY ACBP=28 0000:0432 0029 C=CODE S=_TEXT G=(none) M=LSEEK ACBP=28 0000:045B 0021 C=CODE S=_TEXT G=(none) M=N_PCMP ACBP=28 0000:047C 00BA C=CODE S=_TEXT G=(none) M=SETUPIO ACBP=28 0000:0536 0000 C=CODE S=_TEXT G=(none) M=STKLEN ACBP=28 0000:0536 0432 C=CODE S=_TEXT G=(none) M=FARHEAP ACBP=28 0000:0968 0140 C=CODE S=_TEXT G=(none) M=FBRK ACBP=28 0000:0AA8 001C C=CODE S=_TEXT G=(none) M=SETBLOCK ACBP=28 0000:0AC4 00CD C=CODE S=_TEXT G=(none) M=FFLUSH ACBP=28 0000:0B91 0042 C=CODE S=_TEXT G=(none) M=FLUSHALL ACBP=28 0000:0BD3 01E2 C=CODE S=_TEXT G=(none) M=FSEEK ACBP=28 0000:0DB5 011D C=CODE S=_TEXT G=(none) M=SETVBUF ACBP=28 0000:0ED2 0151 C=CODE S=_TEXT G=(none) M=WRITE ACBP=28 0000:1023 003C C=CODE S=_TEXT G=(none) M=WRITEA ACBP=28 0000:105F 0038 C=CODE S=_TEXT G=(none) M=XFFLUSH ACBP=28 0109:0007 0005 C=CODE S=DOSMNMAP_TEXT G=(none) M=DOSMNMAP.CPP ACBP=28 010A:0000 0000 C=FAR_DATA S=_FARDATA G=(none) M=c0.ASM ACBP=68 010A:0000 0000 C=FAR_BSS S=_FARBSS G=(none) M=c0.ASM ACBP=68 010A:0000 0000 C=OVRINFO S=_OVERLAY_ G=(none) M=c0.ASM ACBP=68 010A:0000 0000 C=STUBSEG S=_1STUB_ G=(none) M=c0.ASM ACBP=68 010A:0000 0093 C=DATA S=_DATA G=DGROUP M=c0.ASM ACBP=68 PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 16/22 TITLE : Understanding MAP files generated by the Linker. 010A:0094 0000 C=DATA S=_DATA G=DGROUP M=DOSMNMAP.CPP ACBP=48 010A:0094 0002 C=DATA S=_DATA G=DGROUP M=ATEXIT ACBP=48 010A:0096 000C C=DATA S=_DATA G=DGROUP M=EXIT ACBP=48 010A:00A2 0190 C=DATA S=_DATA G=DGROUP M=FILES ACBP=48 010A:0232 002A C=DATA S=_DATA G=DGROUP M=FILES2 ACBP=48 010A:025C 0000 C=DATA S=_DATA G=DGROUP M=H_LLSH ACBP=48 010A:025C 0000 C=DATA S=_DATA G=DGROUP M=H_PADD ACBP=48 010A:025C 005B C=DATA S=_DATA G=DGROUP M=IOERROR ACBP=48 010A:02B8 0000 C=DATA S=_DATA G=DGROUP M=ISATTY ACBP=48 010A:02B8 0000 C=DATA S=_DATA G=DGROUP M=LSEEK ACBP=48 010A:02B8 0000 C=DATA S=_DATA G=DGROUP M=N_PCMP ACBP=48 010A:02B8 0000 C=DATA S=_DATA G=DGROUP M=SETUPIO ACBP=48 010A:02B8 0002 C=DATA S=_DATA G=DGROUP M=STKLEN ACBP=48 010A:02BA 0000 C=DATA S=_DATA G=DGROUP M=FARHEAP ACBP=48 010A:02BA 0002 C=DATA S=_DATA G=DGROUP M=FBRK ACBP=48 010A:02BC 0000 C=DATA S=_DATA G=DGROUP M=SETBLOCK ACBP=48 010A:02BC 0000 C=DATA S=_DATA G=DGROUP M=FFLUSH ACBP=48 010A:02BC 0000 C=DATA S=_DATA G=DGROUP M=FLUSHALL ACBP=48 010A:02BC 0000 C=DATA S=_DATA G=DGROUP M=FSEEK ACBP=48 010A:02BC 0004 C=DATA S=_DATA G=DGROUP M=SETVBUF ACBP=48 010A:02C0 0000 C=DATA S=_DATA G=DGROUP M=WRITE ACBP=48 010A:02C0 0000 C=DATA S=_DATA G=DGROUP M=WRITEA ACBP=48 010A:02C0 0000 C=DATA S=_DATA G=DGROUP M=XFFLUSH ACBP=48 010A:02C0 0000 C=DATA S=_CVTSEG G=DGROUP M=c0.ASM ACBP=48 010A:02C0 0000 C=DATA S=_SCNSEG G=DGROUP M=c0.ASM ACBP=48 010A:02C0 0000 C=CONST S=_CONST G=DGROUP M=c0.ASM ACBP=48 010A:02C0 0000 C=INITDATA S=_INIT_ G=DGROUP M=c0.ASM ACBP=48 010A:02C0 0006 C=INITDATA S=_INIT_ G=DGROUP M=SETUPIO ACBP=48 010A:02C6 0000 C=INITDATA S=_INITEND_ G=DGROUP M=c0.ASM ACBP=28 010A:02C6 0000 C=EXITDATA S=_EXIT_ G=DGROUP M=c0.ASM ACBP=48 010A:02C6 0000 C=EXITDATA S=_EXITEND_ G=DGROUP M=c0.ASM ACBP=28 010A:02C6 0000 C=BSS S=_BSS G=DGROUP M=c0.ASM ACBP=48 010A:02C6 0000 C=BSS S=_BSS G=DGROUP M=DOSMNMAP.CPP ACBP=48 010A:02C6 0080 C=BSS S=_BSS G=DGROUP M=ATEXIT ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=IOERROR ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=ISATTY ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=LSEEK ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=SETUPIO ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=SETBLOCK ACBP=48 010A:0346 0000 C=BSS S=_BSS G=DGROUP M=WRITEA ACBP=48 010A:0346 0000 C=BSSEND S=_BSSEND G=DGROUP M=c0.ASM ACBP=28 013F:0000 0080 C=STACK S=_STACK G=(none) M=c0.ASM ACBP=74 PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 17/22 TITLE : Understanding MAP files generated by the Linker. Address Publics by Name 010A:0000 idle DATASEG@ 0000:0291 idle DGROUP@ 0000:0358 idle F_LXLSH@ 0000:0379 idle F_PADD@ 0000:03A8 idle F_PSUB@ 0000:0358 idle LXLSH@ 0000:0355 N_LXLSH@ 0000:0376 N_PADD@ 0000:045B N_PCMP@ 0000:03A5 idle N_PSUB@ 0000:0379 idle PADD@ 0000:03A8 idle PSUB@ 0000:027A idle _abort 0000:0295 idle _atexit 010A:007F _errno 0000:031A _exit 0000:0676 idle _farfree 0000:078A idle _farmalloc 0000:08EE idle _farrealloc 0000:0AC4 _fflush 0000:0B91 _flushall 0000:0676 _free 0000:0C55 _fseek 0000:0CD5 idle _ftell 0000:0421 _isatty 0000:0432 _lseek 0109:0007 _main 0000:0780 _malloc 0000:08E7 idle _realloc 0000:0AA8 _setblock 0000:0DB5 _setvbuf 0000:1000 idle __AHINCR 0000:000C idle __AHSHIFT 010A:0094 __atexitcnt 010A:02C6 __atexittbl 0000:09DE __brk 010A:008B __brklvl 010A:006B idle __C0argc 010A:006D idle __C0argv 010A:0071 idle __C0environ 0000:033B idle __cexit PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 18/22 TITLE : Understanding MAP files generated by the Linker. 0000:016A __checknull 0000:0157 __cleanup 0000:0349 idle __c_exit 010A:025C idle __doserrno 0000:040F idle __DOSERROR 010A:025E idle __dosErrorToSV 010A:0075 idle __envLng 010A:0077 idle __envseg 010A:0079 idle __envSize 0000:0329 __exit 010A:0096 __exitbuf 010A:009A idle __exitfopen 010A:009E idle __exitopen 010A:0087 __heapbase 010A:008F __heaptop 010A:005B idle __Int0Vector 010A:005F idle __Int4Vector 010A:0063 idle __Int5Vector 010A:0067 idle __Int6Vector 0000:03D6 __IOERROR 0000:0293 idle __MMODEL 010A:0232 __nfile 010A:0234 __openfd 010A:007D idle __osmajor 010A:007E idle __osminor 010A:007D idle __osversion 010A:007B __psp 010A:02C0 idle __RealCvtVector 0000:01C0 __restorezero 0000:0A1D __sbrk 010A:02C0 idle __ScanTodVector 0000:047C __setupio 010A:0081 idle __StartTime 010A:02B8 __stklen 010A:00A2 __streams 0000:016B __terminate 010A:007D idle __version 0000:1023 __write 0000:105F __xfflush 010A:0085 idle ___brklvl 0000:0536 idle ___first 0000:0538 idle ___last 0000:053A idle ___rover PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 19/22 TITLE : Understanding MAP files generated by the Linker. 0000:0ED2 ___write Address Publics by Value 0000:000C idle __AHSHIFT 0000:0157 __cleanup 0000:016A __checknull 0000:016B __terminate 0000:01C0 __restorezero 0000:027A idle _abort 0000:0291 idle DGROUP@ 0000:0293 idle __MMODEL 0000:0295 idle _atexit 0000:031A _exit 0000:0329 __exit 0000:033B idle __cexit 0000:0349 idle __c_exit 0000:0355 N_LXLSH@ 0000:0358 idle F_LXLSH@ 0000:0358 idle LXLSH@ 0000:0376 N_PADD@ 0000:0379 idle F_PADD@ 0000:0379 idle PADD@ 0000:03A5 idle N_PSUB@ 0000:03A8 idle F_PSUB@ 0000:03A8 idle PSUB@ 0000:03D6 __IOERROR 0000:040F idle __DOSERROR 0000:0421 _isatty 0000:0432 _lseek 0000:045B N_PCMP@ 0000:047C __setupio 0000:0536 idle ___first 0000:0538 idle ___last 0000:053A idle ___rover 0000:0676 _free 0000:0676 idle _farfree 0000:0780 _malloc 0000:078A idle _farmalloc 0000:08E7 idle _realloc 0000:08EE idle _farrealloc 0000:09DE __brk 0000:0A1D __sbrk PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 20/22 TITLE : Understanding MAP files generated by the Linker. 0000:0AA8 _setblock 0000:0AC4 _fflush 0000:0B91 _flushall 0000:0C55 _fseek 0000:0CD5 idle _ftell 0000:0DB5 _setvbuf 0000:0ED2 ___write 0000:1000 idle __AHINCR 0000:1023 __write 0000:105F __xfflush 0109:0007 _main 010A:0000 idle DATASEG@ 010A:005B idle __Int0Vector 010A:005F idle __Int4Vector 010A:0063 idle __Int5Vector 010A:0067 idle __Int6Vector 010A:006B idle __C0argc 010A:006D idle __C0argv 010A:0071 idle __C0environ 010A:0075 idle __envLng 010A:0077 idle __envseg 010A:0079 idle __envSize 010A:007B __psp 010A:007D idle __osversion 010A:007D idle __osmajor 010A:007D idle __version 010A:007E idle __osminor 010A:007F _errno 010A:0081 idle __StartTime 010A:0085 idle ___brklvl 010A:0087 __heapbase 010A:008B __brklvl 010A:008F __heaptop 010A:0094 __atexitcnt 010A:0096 __exitbuf 010A:009A idle __exitfopen 010A:009E idle __exitopen 010A:00A2 __streams 010A:0232 __nfile 010A:0234 __openfd 010A:025C idle __doserrno 010A:025E idle __dosErrorToSV 010A:02B8 __stklen PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 21/22 TITLE : Understanding MAP files generated by the Linker. 010A:02C0 idle __ScanTodVector 010A:02C0 idle __RealCvtVector 010A:02C6 __atexittbl Program entry point at 0000:0000 ======================================================================== A Detailed Map contains all the information from both the Segment Map and the Public Map files. It also contains a table with a more detailed breakdown of the Segments in memory. The detailed segment table contains seven fields: Memory location, Size in Bytes, Segment Class, Segment Name, Group, Module, and Alignment/Combining. As with the other Tables the Memory location assumes the program ( DOS Applications ) is loaded into the zero page. To get the real locations, the Addresses in field one will have to be added to the PSP of the application after the latter is loaded into memory. The size field shows how large the partial segment is. The Class field shows the segment class that the partial segment belongs to. The Class field types are the same as defined in the segment map section. The Name field show the segment name that the partial segment belongs to. The group field shows the Group that the partial segment belongs to. This field can be instrumental in resolving "DGROUP exceeds 64K" error messages. DGROUP segments will be defined by G=DGROUP. By finding the detailed Segments that contribute to DGROUP and cross referencing to the Public Symbols, likely candidates for movement to far data via the far keyword can be located and moved. The module name is the file name of the translation unit/source code that contains the sub segments. This actually allows the programmer to spot the actual source module that contributed too much to DGROUP if an overflow of the latter is reported by the linker. The Alignment/Combination, or ACBP field contains bit coded information for A (alignment), C (Combination), and B (Big Field) data. The P field, defined by Intel, is not used by the Borland Compilers nor the Borland Linker. The bit definitions follow: Segment size (Big Field) 0000 0000 = 0 = Segment less then 64k 0000 0010 = 2 = Segment > 64k Segment Combination 0000 0000 = 0 = May not be combined 0000 1000 = 8 = public combined segment PRODUCT : Borland C++ NUMBER : 1320 VERSION : 3.1 OS : ALL DATE : October 25, 1993 PAGE : 22/22 TITLE : Understanding MAP files generated by the Linker. Segment Alignment 0000 0000 = 00 = Absolute segment 0010 0000 = 20 = byte alignment 0100 0000 = 40 = word alignment 0110 0000 = 60 = paragraph alignment 1000 0000 = 80 = page alignment 1010 0000 = A0 = Unnamed Absolute storage The Dump Map File ================= The Dump Map file is produced by the Borland Linker when the menu choices or command line parameters are set to produce a detailed map file and linker encounters some error conditions such as exceeding a table limit. The map file produced in those cases will actually contain a hex dump. The map file should be forwarded to Borland's C++ Technical Support Team for further analysis of the problem encountered. DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.