Borland Online And The Cobb Group Present:


July, 1995 - Vol. 2 No. 7

How the -Ox TLINK options reduce EXE size

In the article, Shrinking Windows EXEs and DLLs we describe four new optimizations­­Oc, Oi, Oa, and Or­­that you can use to eliminate unnecessary information from these files. The four optimizations affect fixup chaining, iterating data, minimizing the segment-alignment value, and minimizing the resource-alignment value.

Fixup chaining

In a Windows application, code segments don't usually load at the same memory address each time you run the application. As a result, when a function in one segment (funcA()) needs to call a function in another segment (funcB()), Windows needs to provide a facility for computing the correct address for funcB() when it loads the application at run-time. (Until run-time, funcA() will contain a placeholder or "dummy" address for funcB(), since there's no way for the compiler or linker to know what the real address will be when the application runs.)

To compute the addresses of relocatable functions, each Windows application must have a table of pointers that specifies the locations of the functions in each segment. Using this relocation table, or fixup table, Windows can then insert the correct address of funcB() into the appropriate locations within the body of funcA(). This process, also known as "fixing up" function addresses, is illustrated in Figure A.


Figure A - Windows uses information in the fixup table to locate function addresses from other segments.

Unfortunately, if you call the same function numerous times­­and if that function is in a different segment from the function that called it­­the linker will, by default, create a new fixup table entry for each function call. This is true even though much of the information in the subsequent fixup entries is redundant.

Instead, you can apply fixup chaining to the redundant fixup entries. Fixup chaining replaces the redundant entries in the fixup table with a single entry. Then, it substitutes a series of linked offsets in place of the dummy addresses the linker would normally insert for an inter-segment function call, as shown in Figure B.


Figure B - Fixup chaining eliminates the redundant fixup table entries and utilizes previously unused space.

To apply fixup chaining to your Windows EXEs or DLLs, you'll need to link them using the ­Oc option with TLINK 7.0, the command-line linker. (None of the ­Ox optimizations are directly available using the Integrated Development Environment's [IDE's] built-in linker.)

Iterate data

If you're familiar with the compression techniques found in various disk compression utilities, you'll understand how iterating data reduces the size of an EXE or DLL. If the linker detects any significant pattern of bytes within a data segment, the linker will replace that block of data with a description of the data.

For example, if the linker detects the pattern

FF FE FF FE FF FE FF FE

it will recognize that the sequence FF FE repeats four times. If it can create a description of the pattern that takes up less space than the pattern of data itself, the linker will do so when you use the ­Oi option.

Minimize segment-alignment value

When the linker assigns various blocks of code to segments (groups of functions or data that Windows will load together in a single chunk), it must decide how to arrange those segments within the EXE or DLL disk file. By default, the linker will write a segment to the disk file on 512-byte boundaries or, in other words, in 512-byte sectors. (For the remainder of this article, we'll use the term sector to identify these 512-byte segment-alignment intervals in the EXE file, not to describe anything related to file sectors on a disk.)

Unfortunately, if a given segment doesn't end at one of these 512-byte intervals, the linker will skip ahead to the beginning of the next sector before writing the next segment. For example, when you're using the default 512-byte sectors, if a given segment is 1026 bytes long (two 512-byte sectors plus two extra bytes), that segment will actually occupy 1536 bytes within the file. The 510 remaining bytes in the third sector are completely wasted, as shown in Figure C.

Figure C - The default 512-byte segment-alignment (or sector) size will frequently waste space in your EXE and DLL files.

The ­Oa option tells the linker to create the smallest possible sector value that's also a power of 2, assuming that such a sector size is appropriate for the EXE file size. For example, to completely eliminate wasted space for a 1026-byte segment, the linker could use a sector size of 2 (since 1026 is evenly divisible by 2 but not by 4, 8, 16, 32, 64, 128, 256, 512, or 1024).

However, if the size of the EXE file that contains this 1026-byte segment is greater than 131,072 bytes, the linker will need to use larger sectors and therefore tolerate some wasted space. (The size limitation occurs because the EXE file stores the starting point of each segment as a two-byte sector index that can identify up to 65536 sectors. Obviously, the linker can only use a sector value of 2 on files up to 65536 x 2 bytes in size.)

You don't need to worry about the size of the EXE file, though, because the ­Oa option calculates the optimum value for you. The linker will use the smallest possible sectors, but no smaller than a value that it can use to specify a position anywhere within the EXE file.

Minimize resource-alignment value

The -Or option tells the linker to use the same technique for resource information (bitmaps, string lists, icons, and so on) that the -Oa option applies to code information. Depending on how many resources your application uses, applying this option can yield significant savings.

Return to the Borland C++ Developer's Journal index

Subscribe to the Borland C++ Developer's Journal


Copyright (c) 1996 The Cobb Group, a division of Ziff-Davis Publishing Company. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Ziff-Davis Publishing Company is prohibited. The Cobb Group and The Cobb Group logo are trademarks of Ziff-Davis Publishing Company.