4.4. Linker The GNU Linker (ld) is a major part of the GNU binutils (http://sourceware.org/binutils/), the facility to compile and link programs in Linux. The latest version of the GNU Linker is 2.15. Binutils have been ported to many UNIX variants as well as Windows. Both the Solaris and Linux linkers work with files that conform to the executable and linking format (ELF). Table 4-6 compares Solaris and GNU ld linker options. Table 4-6. Linker Options ComparisonSolaris ld option | GNU ld[13] | Description[14] |
---|
-64 | N/A | Creates a 64-bit object. | -a | -static | Produces an executable object file in static mode only. | -b | N/A (see comment) | With this option, the linker does no (see comment) special processing for relocations that reference symbols in shared objects. There is no exact match in GNU ld, but it can be achieved by not using -fPIC/-fpic compiler options. | -B direct | N/A | Establishes direct binding information by recording the relationship between each symbol reference and the dependency that provides the definition. | -B dynamic|static | -Bdynamic, -Bstatic | Governs library inclusion. | -B eliminate | N/A | Causes any global symbols not assigned to a version definition to be eliminated from the symbol table. | -B group | -Bgroup | Establishes a shared object and its dependencies as a group. | -B local | N/A (see comment) | Causes any global symbols not assigned to a version definition to be reduced local. In GNU ld, this can only be achieved using the wildcard matching in a version definition file. | -B reduce | N/A | When generating a relocatable object, causes the reduction of symbolic information defined by any version definitions. | -B symbolic | -Bsymbolic | In dynamic mode, when building a shared object, binds references to global symbols to their definitions, if available, within object. | -c name | -c | Records the configuration file name for use at runtime. | -C | --demangle[=style] | Demangles C++ symbol names displayed in diagnostic messages. | -d y|n | -dy, -dn | Uses dynamic|static linking. | -D token, . . . | N/A | Prints debugging information, as specified by each token, to the standard error. | -e epsym | -e enTRy, --enTRy=entry | Sets the entry point address for the output file to be the symbol epsym. | -f name | -f name, --auxiliary name | Specifies that the symbol table of the shared object is used as an auxiliary filter on the symbol table of the shared object specified by name. | -F name | -F name, --filter name | 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. | -G | -shared | Produces a shared object. Undefined symbols are allowed. | -h name | -soname name | Records name in the object's dynamic section. name is recorded in any dynamic objects that are linked with this object rather than the object's file system name. | -i | N/A | Ignores LD_LIBRARY_PATH. | -l name | --dynamic-linker name | When building an executable, uses name as the path name of the interpreter to be written into the program header. | -l x | -lx | Searches a library libx.so or libx.a. | -L path | -Lpath | Adds path to the library search directories. | -m | -M (see comment) | Produces a memory map or listing of the input/output sections, together with any nonfatal multiply-defined symbols, on the standard output. GNU ld -M option outputs similar information but in a different format. | -M mapfile | --version-script file | Reads mapfile as a text file of directives to ld. | -N string | N/A (see comment) | This option causes a DT_NEEDED enTRy to be added to the .dynamic section of the object being built. The value of the DT_NEEDED string is the string that is specified on the command line. There is no exact match in GNU ld. You will have to link against a shared object with this string as the name. | -o outfile | -o output | Produces an output object file that is named outfile. | -p auditlib | N/A | Identifies an audit library, auditlib. This audit library is used to audit the object being created at runtime. | -P auditlib | N/A | Identifies an audit library, auditlib. This audit library is used to audit the dependencies of the object being created at runtime. | -Q y|n | N/A (see comment) | Under -Q y, an ident string is added to the .comment section of the output file. -Q n suppresses version identification. This option is ignored by the GNU ld. To achieve this, you could use the #ident directive or the linker script. | -r | -r, --relocatable | Combines relocatable object files to produce one relocatable object file. | -R path | -rpath path | A colon-separated list of directories used to specify library search directories to the runtime linker. | -s | -S, -s | Strips symbolic information from the output file. In GNU ld, the -s option omits all symbol information, whereas the -S option omits only debugger symbol information. | -S supportlib | N/A | The shared object supportlib is loaded with the link-editor and given information regarding the linking process. | -t | N/A | Turns off the warning for multiply-defined symbols that have different sizes or different alignments. | -u symname | -u symname --undefined=symname | Enters symname as an undefined symbol in the symbol table. | -V | -V, --version, -v | Outputs a message giving information about the version of ld being used. | -Y P, dirlist | -Y dirlist | Changes the default directories used for finding libraries. | -z absexec | N/A | Specifies that references to external absolute symbols should be resolved immediately instead of being left for resolution at runtime. | -z allextract|defaultextract|weakextract | N/A | Alters the extraction criteria of objects from any archives that follow. | -z combreloc | -z combreloc | Combines multiple relocation sections. | -z defs|nodefs | -z defs | -z defs forces a fatal error if any undefined symbols remain at the end of the link. The -z nodefs option allows undefined symbols. | -z direct|nodirect | N/A | Enables or disables direct binding to any dependencies that follow on the command line. | -z endfiltee | N/A | Marks a filtee so that when processed by a filter, the filtee terminates any further filtee searches by the filter. | -z finiarray=function | N/A | Appends an entry to the .finiarray section of the object being built. If no .finiarray section is present, a section is created. | -z groupperm|nogroupperm | N/A | Assigns or unassigns each dependency that follows to a unique group. | -z ignore|record | N/A | Ignores, or records, dynamic dependencies that are not referenced as part of the link-edit. | -z initarray=function | N/A | Appends an entry to the .initarray section of the object being built. If no .initarray section is present, a section is created. | -z initfirst | -z initfirst | Marks the object so that its runtime initialization occurs before the runtime initialization of any other objects brought into the process at the same time. | -z interpose | -z interpose | Marks the object as an interposer. | -z lazyload|nolazyload | N/A | Enables or disables the marking of dynamic dependencies to be lazily loaded. | -z ld32=arg1, arg2,... -z ld64=arg1, arg2,... | N/A | Provides a means of defining any link-editor argument, so that the argument is only interpreted, respectively, by the 32-bit class or 64-bit class of the link-editor. | -z loadfltr | -z loadfltr | Marks a filter to indicate that filtees must be processed immediately at runtime. | -z muldefs | -z muldefs | Allows multiple symbol definitions. | -z nocompstrtab | N/A | Disables the compression of ELF string tables. | -z nodefaultlib | -z nodefaultlib | Marks the object so that the runtime default library search path, used after any LD_LIBRARY_PATH or runpaths, is ignored. | -z nodelete | -z nodelete | Marks the object as nondeletable at runtime. | -z nodlopen | -z nodlopen | Marks the object as not available to dlopen(), either as the object specified by the dlopen(), or as any form of dependency required by the object specified by the dlopen(). | -z nodump | -z nodump | Marks the object as not available to dldump(). | -z nopartial | N/A | Partially initialized symbols that are defined within the input relocatable object files are expanded in the output file being generated. | -z noversion | N/A | Does not record any versioning sections. | -z now | -z now | Marks the object as requiring non-lazy runtime binding. | -z origin | -z origin | Marks the object as requiring immediate $ORIGIN processing at runtime. | -z preinitarray=function | N/A | Appends an entry to the .preinitarray section of the object being built. | -z redlocsym | N/A | Eliminates all local symbols except for the SECT symbols from the symbol table SHT_SYMTAB. | -z rescan | N/A | Rescans the archive files that are provided to the link-edit. | -z text | N/A | Forces a fatal error if any relocations against nonwritable, allocatable sections remain. | -z textoff | N/A | Allows relocations against all allocatable sections, including nonwritable ones. | -z textwarn | N/A | Lists a warning if any relocations against nonwritable, allocatable sections remain. | -z verbose | N/A | Provides additional warning diagnostics during a link-edit. |
[13] http://sources.redhat.com/binutils/docs-2.15/ld/Options.html#Options
[14] Sun's ld man page (http://docs.sun.com/app/docs/doc/816-5165/6mbb0m9js?a=view) 4.4.1. Export Maps Export maps enable users to tell the linker explicitly which symbols to export from the generated object. Both the Solaris and GNU linkers support export maps. To generate a shared object with this method, the user has to pass the name of the map file with the -version-script option of the linker: %gcc -shared -o bar.so bar.c -fPIC -Wl,--version-script=bar.map The file bar.map can contain text like this: { global: index; local: *; }; 4.4.2. Linker Tools Solaris has various linker tools such as elfdump, lari, nm, dump, ldd, pvs, and elf. GNU binutils offer similar tools. Refer to Chapter 2 for more information about GNU binutils. Table 4-7 provides a comparison of Solaris linker tools and their equivalents on Linux. Table 4-7. Linker ToolsSolaris Tools | Linux Equivalence | Description |
---|
elfdump | readelf, objdump | Dumps selected parts of an object file. | lari | N/A | Link analysis of runtime interfaces. | nm | nm | Prints name list of an object file. | dump | objdump, readelf | Dumps selected parts of an object file. | ldd | ldd | Lists dynamic dependencies of executable files or shared objects. | pvs | readelf -V | Displays the internal version information of dynamic objects. |
4.4.3. Shared Libraries Linux currently uses ELF (Executable Linkage Format) binary format. The only difference between generating an application and a shared library is in the final link command. The option -shared for GNU ld tells the linker to create a shared library rather than an application. To create shared libraries in Solaris: cc -o libfoo.so -G -K pic foo.c To create shared libraries in Linux: gcc -o libfoo.so -shared -fpic foo.c In Solaris, when one wants to record a soname to a shared object itself, use the -h option: cc -o libfoo.so -G -K pic -h libfoo.so.1 foo.c The equivalent on Linux is this: gcc -o libfoo.so -shared -fpic -Wl,-soname=libfoo.so.1 foo.c or gcc -o libfoo.so -shared -fpic -Wl,-hlibfoo.so.1 foo.c The dump command in Solaris is equivalent to the objdump command in Linux. The following example shows how the soname recording can be displayed using the objdump command in Linux: #objdump -x libGLU.so.1.3 | grep SONAME SONAME libGLU.so.1 4.4.4. Library Versioning In Chapter 3, "Analysis," we provide information about how library versioning is implemented in Linux. Although the external versioning in Solaris is the same as that in Linux, there are some differences in how the symbol versioning works in Solaris and Linux. Solaris symbol versioning works well in coping with the compatible changes in the shared libraries. When there is an incompatible change, the only way to deal with it in Solaris is to fall back to the external versioning (that is, incrementing the major version number in the soname). Linux symbol versioning can be used to handle incompatible changes. With this, it is not necessary to increase the major version number every time you make an incompatible change to your library. In Linux, it is possible to have multiple definitions of a given symbol (the associated version must differ). Also, the application linked with the versioned shared library contains not only a list of the required version, but also records for each symbol which symbol version was used and from which library the definition came. How to take advantage of this advantage in Linux is, however, beyond the scope of this book. For more information about symbol versioning, refer to the paper by Ulrich Drepper titled "How to Write Shared Libraries," located at http://people.redhat.com/~drepper. In addition, the paper by David J. Brown and Karl Runge titled "Library Interface Versioning in Solaris and Linux" is a good source for the library versioning comparison between Solaris and Linux. 4.4.5. Dynamic Linker (or Runtime Linker) Both the Solaris dynamic linker and Linux dynamic linker load library dependencies breadth first. That is, first the dependencies of the executable are added in the order listed in its dynamic section. Then the dependencies of the first dependency are added in the same fashion. More information about the Linux dynamic linker is provided in Chapter 3. |