C H A P T E R  4

Incremental Link Editor (ild)

This chapter describes ild, ild-specific features, example messages, and ild options.


4.1 Introduction

ild is an incremental version of the Link Editor ld, and replaces ld for linking programs. Use ild to complete the edit, compile, link, and debug loop efficiently and more quickly. You can avoid relinking entirely by using the fix and continue feature of dbx which allows you to work without relinking. However, if you need to relink, the process can be faster if you use ild. For more information on fix and continue, see Chapter 11 in Debugging a Program With dbx.

ild links incrementally so you can insert modified object code into an executable file that you created earlier, without relinking unmodified object files. The time required to relink depends upon the amount of code modified. Linking your application on every build does not require the same amount of time; small changes in code can be relinked very quickly.

On the initial link, ild requires about the same amount of time that ld requires, but subsequent ild links can be much faster than an ld link. The cost of the reduced link time is an increase in the size of the executable.


4.2 Overview of Incremental Linking

When you use ild in place of ld, the initial link causes the various text, data, bss, exception table sections, etc., to be padded with additional space for future expansion (see FIGURE 4-1). Additionally, all relocation records and the global symbol table are saved into a new persistent state region in the executable file. On subsequent incremental links, ild uses timestamps to determine which object files have changed and patches the changed object code into a previously built executable. That is, previous versions of the object files are invalidated and the new object files are loaded into the space vacated, or into the pad sections of the executable when needed. All references to symbols in invalidated object files are patched to point to the correct new object files.

ild does not support all ld command options. If ild is passed a command option that it does not support, ild directly invokes /usr/ccs/bin/ld to perform the link. See Section 4.9, ld Options not Supported by ild for more information on commands that are not supported by the Incremental Linker.


4.3 How to Use ild

ild is invoked automatically by the compilation system in place of ld under certain conditions. When you invoke a compilation system, you are invoking a compiler driver. When you pass certain options to the driver, the driver uses ild. The compiler driver reads the options from the command line and executes various programs in the correct order and adds files from the list of arguments that are passed.

For example, cc first runs acomp (the front-end of the compiler), then acomp runs the optimizing code generator, then cc does the same thing for the other source files listed on the command line. The driver can then generate a call to either ild or ld, depending on the options, passing it all of the files just compiled, plus other files and libraries needed to make the program complete.

The following figure shows an example of incremental linking.

 FIGURE 4-1 An Example of Incremental Linking

Graphic showing the difference between what kind of executable is produced by the linker versus the incremental linker.

The following compilation system options control whether a link step is performed by ild or ld:



Note - If -xildon and -xildoff are both present, the last command listed is used by the driver to select the linker.



When you use the -g option to invoke debugging, and you have the default Makefile structure (which includes compile-time options such as -g on the link command line), you use ild automatically when doing development.


4.4 How ild Works

On an initial link, ild saves information about:

Initial ild links take about as much time as an ld link.

On incremental links, ild:

Incremental ild links are much faster than ld links.

In general, you do one initial link and all subsequent links are incremental.

For example, ild saves a list of all places where symbol foo is referenced in your code. If you do an incremental link that changes the value of foo, ild must change the value of all references to foo.

ild spreads out the components of the program and each section of the executable has padding added to it. Padding makes the executable modules larger than when they were linked by ld. As object files increase in size during successive incremental links, the padding can become exhausted. If this occurs, ild displays a message and does a complete full relink of the executable.

For example, as FIGURE 4-1 shows, each of the three columns shows the sequence of text and data in a linked executable program. The left column shows text and data in an executable linked by ld. The center column shows the addition of text and data padding in an executable linked by ild. Assume that a change is made to the source file for Text 1 that causes the Text section to grow without affecting the size of the other sections. The right column shows that the original location of Text 1 has been replaced by Text padding (Text 1 has been invalidated). Text 1 has been moved to occupy a portion of the Text padding space.

To produce a smaller nonincremental executable, run the compiler driver (for example, cc or CC) with the -xildoff option, and ld is invoked to produce a more compact executable.

The resulting executable from ild can be debugged by dbx because dbx/Debugger understands the padding that ild inserts between programs.

For any command-line option that ild does not understand, ild invokes ld. ild is compatible with ld (in /usr/ccs/bin/ld). See Section 4.7, ild Options, for details.

There are no special or extra files used by ild.


4.5 What ild Cannot Do

When ild is invoked to create shared objects, ild invokes ld to create the link.

Performance of ild may suffer greatly if you change a high percentage of object files. ild automatically does a full relink when it detects that a high percentage of files have been changed.

Do not use ild to produce the final production code for shipment. ild makes the file larger because parts of the program have been spread out due to padding. Because of the padding and additional time required to link, it is recommended that you do not use the -xildon option for production code. (Use -xildoff on the link line if -g is present.)

ild may not link small programs much faster, and the increase in size of the executable is greater than that for larger programs.

Third-party tools that work on executables may have unexpected results on ild-produced binaries.

Any program that modifies an executable, for example strip or mcs, might affect the ability of ild to perform an incremental link. When this happens, ild issues a message and performs a full relink. For more information on a full relink, see Section 4.6, Reasons for Full Relinks.


4.6 Reasons for Full Relinks

The following section explains under which circumstances ild calls ld to complete a link.

4.6.1 ild Deferred-Link Messages

The message `ild: calling ld to finish link'... means that ild cannot complete the link, and is deferring the link request to ld for completion. By default, these messages are displayed as needed. You can suppress these messages by using the -z i_quiet option.

The following message is suppressed if ild is implicitly requested (-g), but is displayed if -xildon is on the command line. This message is displayed in all cases if you use the -z i_verbose option, and never displayed if you use the -z i_quiet option.

ild: calling ld to finish link -- cannot handle shared libraries in archive library name

Here are further examples of -z i_verbose messages:

ild: calling ld to finish link -- cannot handle keyword Keyword

ild: calling ld to finish link -- cannot handle keyword -d

ild: calling ld to finish link -- cannot handle -z keyword

ild: calling ld to finish link -- cannot handle argument keyword

4.6.2 ild Relink Messages

The message `ild: (Performing full relink)' ... means that for some reason ild cannot do an incremental link and must do a full relink. This is not an error. It is to inform you that this link will take longer than an incremental link (see Section 4.4, How ild Works, for more details). ild messages can be controlled by ild options -z i_quiet and -z i_verbose. Some messages have a verbose mode with more descriptive text.

You can suppress all of these messages by using the ild option -z i_quiet. If the default message has a verbose mode, the message ends with an ellipsis ([...]) indicating more information is available. You can view the additional information by using the -z i_verbose option. Example messages are shown with the -z i_verbose option selected.

4.6.3 Example 1: Internal Free Space Exhausted

The most common of the full relink messages is the internal free space exhausted message:

    
$ cat test1.c 
    
int main() { return 0; }
    
$ rm a.out
# This creates test1.o
$ cc -xildon -c -g test1.c
# This creates a.out with minimal debugging information.
$ cc -xildon -z i_verbose -g test1.o
# A one-line compile and link puts all debugging information into a.out.
$ cc -xildon -z i_verbose -g test1.c
    
ild: (Performing full relink) internal free space in output file exhausted (sections)
    
$

These commands show that going from a one-line compile to a two-line compile causes debugging information to grow in the executable. This growth causes ild to run out of space and do an full relink.

4.6.4 Example 2: Running strip

Another problem arises when you run strip. Continuing from Example 1:

# Strip a.out
$ strip a.out
# Try to do an incremental link
$ cc -xildon -z i_verbose -g test1.c
    
ild: (Performing full relink) a.out has been altered since the last incremental link -- maybe you ran strip or mcs on it?
    
$

4.6.5 Example 3: ild Version

When a new version of ild is run on an executable created by an older version of ild, you see the following error message:

# Assume old_executable was created by an earlier version of ild
$ cc -xildon -z i_verbose foo.o -o old_executable
    
ild: (Performing full relink) an updated ild has been installed since a.out was last linked (2/16)



Note - The numbers (2/16) are used only for internal reporting.



4.6.6 Example 4: Too Many Files Changed

Sometimes ild determines that it will be faster to do a full relink than an incremental link. For example:

$ rm a.out
$ cc -xildon -z i_verbose \
     x0.o x1.o x2.o x3.o x4.o x5.o x6.o x7.o x8.o test2.o
$ touch x0.o x1.o x2.o x3.o x4.o x5.o x6.o x7.o x8.o
$ cc -xildon -z i_verbose \
     x0.o x1.o x2.o x3.o x4.o x5.o x6.o x7.o x8.o test2.o
ild: (Performing full relink) too many files changed

Here, use of the touch command causes ild to determine that files x0.o through x8.o have changed and that a full relink will be faster than incrementally relinking all nine object files.

4.6.7 Example 5: Full Relink

There are certain conditions that can cause a full relink on the next link, as compared to the previous examples that cause a full relink on this link.

The next time you try to link that program, you see the message:

# ild detects previous error and does a full relink
$ cc -xildon -z i_verbose  broken.o
ild: (Performing full relink) cannot do incremental relink due to problems in the previous link

A full relink occurs.

4.6.8 Example 6: New Working Directory

    
% cd /tmp
    
% cat y.c
    
    int main(){ return 0;}
    
% cc -c y.c
    
% rm -f a.out
# initial link with cwd equal to /tmp
% cc -xildon -z i_verbose y.o -o a.out
    
% mkdir junk
    
% mv y.o y.c a.out junk
    
% cd junk
# incremental link, cwd is now /tmp/junk
% cc -xildon -z i_verbose y.o -o a.out
    
ild: (Performing full relink) current directory has changed from `/tmp' to `/tmp/junk'
    
%


4.7 ild Options

This section describes the linker control options directly accepted by the compilation system and linker options that may be passed through the compilation system to ild.

4.7.1 -a

In static mode only, produce an executable object file; give errors for undefined references. This is the default behavior for static mode.

4.7.2 -B dynamic | static

Options governing library inclusion. Option -Bdynamic is valid in dynamic mode only. These options can be specified any number of times on the command line as toggles: if the -Bstatic option is given, no shared objects are accepted until -Bdynamic is seen. See option Section 4.7.9, -lx.

4.7.3 -d y|n

When -dy (the default) is specified, ild uses dynamic linking; when -dn is specified, ild uses static linking. See option Section 4.7.2, -B dynamic | static.

4.7.4 -e epsym

Set the entry point address for the output file to be that of the symbol epsym.

4.7.5 -g

The compilation systems invoke ild in place of ld when the -g option (output debugging information) is given, unless any of the following are true:

  • The -G option (produce a shared library) is given
  • The -xildoff option is present
  • Any source files are named on the command line

4.7.6 -I name

When building an executable, use name as the path name of the interpreter to be written into the program header. The default in static mode is no interpreter; in dynamic mode, the default is the name of the runtime linker, /usr/lib/ld.so.1. Either case may be overridden by -Iname. exec only loads this interpreter when it loads a.out and will pass control to the interpreter rather than to a.out directly.

4.7.7 -i

Ignores LD_LIBRARY_PATH setting. This option is useful when an LD_LIBRARY_PATH setting is in effect to influence the runtime library search, which would interfere with the link editing being performed. (This also applies to the setting of LD_LIBRARY_PATH_64).

4.7.8 -Lpath

Adds path to the library search directories. ild searches for libraries first in any directories specified by the -L options, and then in the standard directories. This option is useful only if it precedes the -l options to which it applies on the command line. You can use the environment variable LD_LIBRARY_PATH and LD_LIBRARY_PATH_64 to supplement the library search path (see LD_LIBRARY_PATH).

4.7.9 -lx

Searches a library libx.so or libx.a, the conventional names for shared objects and archive libraries, respectively. In dynamic mode, unless the -Bstatic option is in effect, ild searches each directory specified in the library search path for a file libx.so or libx.a. The directory search stops at the first directory containing either. ild chooses the file ending in .so if -l expands to two files whose names are of the form libx.so and libx.a. If no libx.so is found, then ild accepts libx.a. In static mode, or when the -Bstatic option is in effect, ild selects only the file ending in .a. A library is searched when its name is encountered, so the placement of -l is significant.

4.7.10 -m

Produce a memory map or listing of the input/output sections on the standard output.

4.7.11 -o outfile

Produces an output object file named outfile. The name of the default object file is a.out.

4.7.12 -Q y|n

Under -Qy, an ident string is added to the .comment section of the output file to identify the version of the link editor used to create the file. This results in multiple ld idents when there have been multiple linking steps, such as when using ld -r. This is identical with the default action of the cc command. Option -Qn suppresses version identification.

4.7.13 -Rpath

This option gives a colon-separated list of directories that specifies library search directories to the runtime linker. If present and not null, path is recorded in the output object file and passed to the runtime linker. Multiple instances of this option are concatenated and separated by a colon.

4.7.14 -s

Strips symbolic information from the output file. Any debugging information and associated relocation entries are removed. Except for relocatable files or shared objects, the symbol table and string table sections are also removed from the output object file.

4.7.15 -t

Turn off the warning about multiply defined symbols that are not the same size.

4.7.16 -u symname

Enter symname as an undefined symbol in the symbol table. This is useful for loading entirely from an archive library, since initially the symbol table is empty and an unresolved reference is needed to force the loading of the first routine. The placement of this option on the command line is significant; it must be placed before the library that defines the symbol.

4.7.17 -V

Output a message about the version of ild being used.

4.7.18 -xildoff

Incremental linker off. Force the use of bundled ld. This is the default if -g is not being used, or -G is being used. You can override this default with -xildon.

4.7.19 -xildon

Incremental linker. Force the use of ild in incremental mode. This is the default if -g is being used. You can override this default with -xildoff.

4.7.20 -YP,dirlist

(cc only) Changes the default directories used for finding libraries. Option dirlist is a colon-separated path list.



Note - ild uses the "-z name" form for special options. The i_ prefix to the -z options identifies those options peculiar to ild.



4.7.21 -z allextract|defaultextract| weakextract

Alter the extraction criteria of objects from any archives that follow. By default archive members are extracted to satisfy undefined references and to promote tentative definitions with data definitions. Weak symbol references do not trigger extraction. Under -z allextract, all archive members are extracted from the archive. Under -z weakextract, weak references trigger archive extraction. -z defaultextract provides a means of returning to the default following use of the former extract options.

4.7.22 -z defs

Forces a fatal error if any undefined symbols remain at the end of the link. This is the default when building an executable. It is also useful when building a shared object to assure that the object is self-contained, that is, that all its symbolic references are resolved internally.

4.7.23 -z i_dryrun

(ild only.) Prints the list of files that would be linked by ild and exits.

4.7.24 -z i_full

(ild only.) Does a complete relink in incremental mode.

4.7.25 -z i_noincr

(ild only.) Runs ild in nonincremental mode (not recommended for customer use -- used for testing only).

4.7.26 -z i_quiet

(ild only) Turns off all ild relink messages.

4.7.27 -z i_verbose

(ild only) Expands on default information on some ild relink messages.

4.7.28 -z nodefs

Allows undefined symbols. This is the default when building a shared object. When used with executables, the behavior of references to such "undefined symbols" is unspecified.


4.8 Options Passed to ild From the Compilation System

The following options are accepted by ild, but you must use the form:

-Wl,arg,arg (for cc), to pass them to ild through the compilation system.

4.8.1 -a

In static mode only, produces an executable object file; gives errors for undefined references. This is the default behavior for static mode. Option -a cannot be used with the -r option.

4.8.2 -e epsym

Sets the entry point address for the output file to be that of the symbol epsym.

4.8.3 -I name

When building an executable, uses name as the path name of the interpreter to be written into the program header. The default in static mode is no interpreter; in dynamic mode, the default is the name of the runtime linker, /usr/lib/ld.so.1. Either case can be overridden by -I name. The exec system call loads this interpreter when it loads the a.out and passes control to the interpreter rather than to the a.out directly.

4.8.4 -m

Produces a memory map or listing of the input/output sections on the standard output.

4.8.5 -t

Turn off the warning about symbols that are defined more than once and that are not the same size.

4.8.6 -u symname

Enters symname as an undefined symbol in the symbol table. This is useful for loading entirely from an archive library because, initially, the symbol table is empty and an unresolved reference is needed to force the loading of the first routine. The placement of this option on the command line is significant; it must be placed before the library that defines the symbol.

4.8.7 Environment

LD_LIBRARY_PATH

A list of directories which is searched for the libraries that are specified with the -l option. Multiple directories are separated by a colon. In the most general case, it contains two directory lists separated by a semicolon:

dirlist1; dirlist2

If ild is called with any number of occurrences of -L, as in:

ild ...-Lpath1 ...  -Lpathn ...

then the search path ordering is:

dirlist1 path1 ...  pathn dirlist2  LIBPATH

When the list of directories does not contain a semicolon, it is interpreted as follows:

dirlist2

LD_LIBRARY_PATH is also used to specify library search directories to the runtime linker. That is, if LD_LIBRARY_PATH exists in the environment, the runtime linker searches the directories named in it, before its default directory, for shared objects to be linked with the program at execution.



Note - When running a set-user-ID or set-group-ID program, the runtime linker searches only for libraries in /usr/lib. It also searches for any full pathname specified within the executable. A full pathname is the result of a runpath being specified when the executable was constructed. Any library dependencies specified as relative pathnames are silently ignored.



LD_LIBRARY_PATH_64

On Solaris 7 and Solaris 8, this environment variable is similar to LD_LIBRARY_PATH but overrides it when searching for 64-bit dependencies.

When you run Solaris 7 or Solaris 8 on a SPARC processor and link in 32-bit mode, LD_LIBRARY_PATH_64 is ignored. If only LD_LIBRARY_PATH is defined, it is used for both 32-bit and 64-bit linking. If both LD_LIBRARY_PATH and LD_LIBRARY_PATH_64 are defined, the 32-bit linking will be done using LD_LIBRARY_PATH and the 64-bit linking will be done using LD_LIBRARY_PATH_64.

LD_OPTIONS

A default set of options to ild. LD_OPTIONS is interpreted by ild as though its value had been placed on the command line immediately following the name used to invoke ild, as in:

ild $LD_OPTIONS   ...  other-arguments ...

LD_PRELOAD

A list of shared objects that are to be interpreted by the runtime linker. The specified shared objects are linked in after the program being executed and before any other shared objects that the program references.



Note - When running a set-user-ID or set-group-ID program, this option is silently ignored.



LD_RUN_PATH

An alternative mechanism for specifying a runpath to the link editor (see the -R option). If both LD_RUN_PATH and the -R option are specified, the -R is used.

LD_DEBUG

(not supported by ild) Provide a list of tokens that cause the runtime linker to print debugging information to the standard error. The special token help indicates the full list of tokens available.



Note - Environment variable names beginning with the characters `LD_ `are reserved for possible future enhancements to ld. Environment variable-names beginning with the characters `ILD_ ` are reserved for possible future enhancements to ild.




4.9 ld Options not Supported by ild

If ild determines that a command line option is not implemented, ild directly invokes /usr/css/bin/ld to perform the link.

The following options, which may be given to the compilation system, are not supported by ild.

4.9.1 -B symbolic

In dynamic mode only, when building a shared object, bind references to global symbols to their definitions within the object, if definitions are available. Normally, references to global symbols within shared objects are not bound until runtime, even if definitions are available, so that definitions of the same symbol in an executable or other shared objects can override the object's own definition. ld issues warnings for undefined symbols unless -z defs overrides.

4.9.2 -b

In dynamic mode only, when creating an executable, does not do special processing for relocations that reference symbols in shared objects. Without the -b option, the link editor creates special position-independent relocations for references to functions defined in shared objects and arranges for data objects defined in shared objects to be copied into the memory image of the executable by the runtime linker. With the -b option, the output code can be more efficient, but it is less sharable.

4.9.3 -G

In dynamic mode only, produces a shared object. Undefined symbols are allowed.

4.9.4 -h name

In dynamic mode only, when building a shared object, records name in the object's dynamic section. Option name is recorded in executables that are linked with this object rather than the object's UNIX System file name. Accordingly, name is used by the runtime linker as the name of the shared object to search for at runtime.

4.9.5 -z muldefs

Allows multiple symbol definitions. By default, multiple symbol definitions occurring between relocatable objects result in a fatal error condition. This option suppresses the error condition, and allows the first symbol definition to be taken.

4.9.6 -z text

In dynamic mode only, forces a fatal error if any relocations against non-writable, allocatable sections remain.


4.10 Additional Unsupported Commands

In addition, the following options that may be passed directly to ld, are not supported by ild:

4.10.1 -D token,token, ...

Prints debugging information as specified by each token, to the standard error. The special token help indicates the full list of tokens available.

4.10.2 -F name

Useful only when building a shared object. Specifies that the symbol table of the shared object is used as a "filter" on the symbol table of the shared object specified by name.

4.10.3 -M mapfile

Reads mapfile as a text file of directives to ld. See SunOS 5.3 Linker and Libraries Manual for a description of mapfiles.

4.10.4 -r

Combines relocatable object files to produce one relocatable object file. ld does not complain about unresolved references. This option cannot be used in dynamic mode or with -a.


4.11 Files That ild Uses

  • libx.a libraries
  • a.out output file