Debugging Aids
The link-editor provides a debugging facility that allows you to trace the link-editing process in detail. This facility can help you understand and debug the link-edit of your applications and libraries. The type of information that is displayed by using this facility is expected to remain constant. However, the exact format of the information might change slightly from release to release.
Some of the debugging output might be unfamiliar if you do not have an intimate knowledge of the ELF format. However, many aspects might be of general interest to you.
Debugging is enabled by using the -D
option.
This option must be augmented with one or more tokens to indicate the type
of debugging that is required.
The tokens that are available with -D
can be displayed by
typing -D help
at the command line.
$ ld -Dhelp
If the help
token is specified by itself, output goes to
stdout
, the standard output file. If any other
tokens are specified, debug output is sent to stderr
, the
standard error output file. Debug output can be directed to a file instead,
using the output
token. For example, the help text can be
captured in a file named ld-debug.txt
.
$ ld -Dhelp,output=ld-debug.txt
Most compiler drivers assign the -D
option a
different meaning, often to define preprocessing macros. The
LD_OPTIONS
environment variable can be used to bypass
the compiler driver, and supply the -D
option directly to
the link-editor.
The following example shows how input files can be traced. This syntax can be useful to determine what libraries are used as part of a link-edit. Objects that are extracted from an archive are also displayed with this syntax.
$ LD_OPTIONS=-Dfiles cc -o prog main.o -L. -lfoo
....
debug: file=main.o [ ET_REL ]
debug: file=./libfoo.a [ archive ]
debug: file=./libfoo.a(foo.o) [ ET_REL ]
debug: file=./libfoo.a [ archive ] (again)
....
Here, the member foo.o
is extracted from
the archive library libfoo.a
to satisfy the link-edit
of prog
. Notice that the archive is searched twice to
verify that the extraction of foo.o
did not warrant the
extraction of additional relocatable objects. Multiple "(again)"
diagnostics indicates that the archive is a candidate for ordering using
lorder
(1) and
tsort
(1).
By using the symbols
token, you can determine which symbol
caused an archive member to be extracted, and which object made the initial
symbol reference.
$ LD_OPTIONS=-Dsymbols cc -o prog main.o -L. -lfoo
....
debug: symbol table processing; input file=main.o [ ET_REL ]
....
debug: symbol[7]=foo (global); adding
debug:
debug: symbol table processing; input file=./libfoo.a [ archive ]
debug: archive[0]=bar
debug: archive[1]=foo (foo.o) resolves undefined or tentative symbol
debug:
debug: symbol table processing; input file=./libfoo(foo.o) [ ET_REL ]
....
The symbol foo
is referenced by
main.o
. This symbol is added to the link-editor's
internal symbol table. This symbol reference causes the extraction of the
relocatable object foo.o
from the archive
libfoo.a
.
Note:
This output has been simplified for this document.By using the detail
token together with the
symbols
token, the details of symbol resolution
during input file processing can be observed.
$ LD_OPTIONS=-Dsymbols,detail cc -o prog main.o -L. -lfoo
....
debug: symbol table processing; input file=main.o [ ET_REL ]
....
debug: symbol[7]=foo (global); adding
debug: entered 0x000000 0x000000 NOTY GLOB UNDEF REF_REL_NEED
debug:
debug: symbol table processing; input file=./libfoo.a [ archive ]
debug: archive[0]=bar
debug: archive[1]=foo (foo.o) resolves undefined or tentative symbol
debug:
debug: symbol table processing; input file=./libfoo.a(foo.o) [ ET_REL ]
debug: symbol[1]=foo.c
....
debug: symbol[7]=bar (global); adding
debug: entered 0x000000 0x000004 OBJT GLOB 3 REF_REL_NEED
debug: symbol[8]=foo (global); resolving [7][0]
debug: old 0x000000 0x000000 NOTY GLOB UNDEF main.o
debug: new 0x000000 0x000024 FUNC GLOB 2 ./libfoo.a(foo.o)
debug: resolved 0x000000 0x000024 FUNC GLOB 2 REF_REL_NEED
....
The original undefined symbol foo
from
main.o
has been overridden with the symbol
definition from the extracted archive member foo.o
. The
detailed symbol information reflects the attributes of each symbol.
In the previous example, you can see that using some of the debugging tokens
can produce a wealth of output. To monitor the activity around a subset of
the input files, place the -D
option directly in the
link-edit command line. This option can be toggled on and toggled off. In
the following example, the display of symbol processing is switched on only
during the processing of the library libbar
.
$ ld .... -o prog main.o -L. -Dsymbols -lbar -D!symbols ....
Note:
To obtain the link-edit command line, you might have to expand the compilation line from any driver being used. See Using a Compiler Driver.