11.1.3 Resolving Symbols
Once memory has been allocated, the linker begins the process of resolving symbols. Symbols defined in each input section have offsets that are relative to the beginning of the section. The linker converts these values into output section offsets.
Next, the linker attempts to match all external symbol references with a corresponding symbol definition. Multiple definitions of the same external symbol result in an error. If an external symbol is not found, an attempt is made to locate the symbol definition in an archive file. If the symbol definition is found in an archive, the corresponding archive module is loaded.
Modules loaded from archives may contain additional symbol references, so the process continues until all external symbol references have matching definitions. External symbols that are defined as “weak” receive special processing, as explained in Global and Weak Symbols. If any external symbol reference remains undefined, an error is generated.
References to redundant functions in archive files will be merged in order
to conserve memory. For example, both integer and floating-point versions of the standard C
formatted I/O functions are included in libc99-elf.a
. The
XC32 compiler will generate references to the
appropriate function, based on a static analysis of format strings. When multiple object
files are combined by the linker, both versions of a particular I/O function may be
referenced. In such cases the integer functions are redundant, since they represent a
subset of the floating-point functionality. The linker will detect this situation, and
merge the I/O functions together to conserve memory. This optimization may be disabled with
the --no-smart-io
option.