1153 lines
44 KiB
Plaintext
1153 lines
44 KiB
Plaintext
|
This is Info file ld.info, produced by Makeinfo-1.64 from the input
|
|||
|
file ./ld.texinfo.
|
|||
|
|
|||
|
START-INFO-DIR-ENTRY
|
|||
|
* Ld: (ld). The GNU linker.
|
|||
|
END-INFO-DIR-ENTRY
|
|||
|
|
|||
|
This file documents the GNU linker LD.
|
|||
|
|
|||
|
Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software
|
|||
|
Foundation, Inc.
|
|||
|
|
|||
|
Permission is granted to make and distribute verbatim copies of this
|
|||
|
manual provided the copyright notice and this permission notice are
|
|||
|
preserved on all copies.
|
|||
|
|
|||
|
Permission is granted to copy and distribute modified versions of
|
|||
|
this manual under the conditions for verbatim copying, provided also
|
|||
|
that the entire resulting derived work is distributed under the terms
|
|||
|
of a permission notice identical to this one.
|
|||
|
|
|||
|
Permission is granted to copy and distribute translations of this
|
|||
|
manual into another language, under the above conditions for modified
|
|||
|
versions.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Assignment, Next: Arithmetic Functions, Prev: Evaluation, Up: Expressions
|
|||
|
|
|||
|
Assignment: Defining Symbols
|
|||
|
----------------------------
|
|||
|
|
|||
|
You may create global symbols, and assign values (addresses) to
|
|||
|
global symbols, using any of the C assignment operators:
|
|||
|
|
|||
|
`SYMBOL = EXPRESSION ;'
|
|||
|
`SYMBOL &= EXPRESSION ;'
|
|||
|
`SYMBOL += EXPRESSION ;'
|
|||
|
`SYMBOL -= EXPRESSION ;'
|
|||
|
`SYMBOL *= EXPRESSION ;'
|
|||
|
`SYMBOL /= EXPRESSION ;'
|
|||
|
Two things distinguish assignment from other operators in `ld'
|
|||
|
expressions.
|
|||
|
* Assignment may only be used at the root of an expression; `a=b+3;'
|
|||
|
is allowed, but `a+b=3;' is an error.
|
|||
|
|
|||
|
* You must place a trailing semicolon (";") at the end of an
|
|||
|
assignment statement.
|
|||
|
|
|||
|
Assignment statements may appear:
|
|||
|
* as commands in their own right in an `ld' script; or
|
|||
|
|
|||
|
* as independent statements within a `SECTIONS' command; or
|
|||
|
|
|||
|
* as part of the contents of a section definition in a `SECTIONS'
|
|||
|
command.
|
|||
|
|
|||
|
The first two cases are equivalent in effect--both define a symbol
|
|||
|
with an absolute address. The last case defines a symbol whose address
|
|||
|
is relative to a particular section (*note SECTIONS::.).
|
|||
|
|
|||
|
When a linker expression is evaluated and assigned to a variable, it
|
|||
|
is given either an absolute or a relocatable type. An absolute
|
|||
|
expression type is one in which the symbol contains the value that it
|
|||
|
will have in the output file; a relocatable expression type is one in
|
|||
|
which the value is expressed as a fixed offset from the base of a
|
|||
|
section.
|
|||
|
|
|||
|
The type of the expression is controlled by its position in the
|
|||
|
script file. A symbol assigned within a section definition is created
|
|||
|
relative to the base of the section; a symbol assigned in any other
|
|||
|
place is created as an absolute symbol. Since a symbol created within a
|
|||
|
section definition is relative to the base of the section, it will
|
|||
|
remain relocatable if relocatable output is requested. A symbol may be
|
|||
|
created with an absolute value even when assigned to within a section
|
|||
|
definition by using the absolute assignment function `ABSOLUTE'. For
|
|||
|
example, to create an absolute symbol whose address is the last byte of
|
|||
|
an output section named `.data':
|
|||
|
SECTIONS{ ...
|
|||
|
.data :
|
|||
|
{
|
|||
|
*(.data)
|
|||
|
_edata = ABSOLUTE(.) ;
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
The linker tries to put off the evaluation of an assignment until all
|
|||
|
the terms in the source expression are known (*note Evaluation::.). For
|
|||
|
instance, the sizes of sections cannot be known until after allocation,
|
|||
|
so assignments dependent upon these are not performed until after
|
|||
|
allocation. Some expressions, such as those depending upon the location
|
|||
|
counter "dot", `.' must be evaluated during allocation. If the result
|
|||
|
of an expression is required, but the value is not available, then an
|
|||
|
error results. For example, a script like the following
|
|||
|
SECTIONS { ...
|
|||
|
text 9+this_isnt_constant :
|
|||
|
{ ...
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
will cause the error message "`Non constant expression for initial
|
|||
|
address'".
|
|||
|
|
|||
|
In some cases, it is desirable for a linker script to define a symbol
|
|||
|
only if it is referenced, and only if it is not defined by any object
|
|||
|
included in the link. For example, traditional linkers defined the
|
|||
|
symbol `etext'. However, ANSI C requires that the user be able to use
|
|||
|
`etext' as a function name without encountering an error. The
|
|||
|
`PROVIDE' keyword may be used to define a symbol, such as `etext', only
|
|||
|
if it is referenced but not defined. The syntax is `PROVIDE(SYMBOL =
|
|||
|
EXPRESSION)'.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Arithmetic Functions, Next: Semicolons, Prev: Assignment, Up: Expressions
|
|||
|
|
|||
|
Arithmetic Functions
|
|||
|
--------------------
|
|||
|
|
|||
|
The command language includes a number of built-in functions for use
|
|||
|
in link script expressions.
|
|||
|
`ABSOLUTE(EXP)'
|
|||
|
Return the absolute (non-relocatable, as opposed to non-negative)
|
|||
|
value of the expression EXP. Primarily useful to assign an
|
|||
|
absolute value to a symbol within a section definition, where
|
|||
|
symbol values are normally section-relative.
|
|||
|
|
|||
|
`ADDR(SECTION)'
|
|||
|
Return the absolute address of the named SECTION. Your script must
|
|||
|
previously have defined the location of that section. In the
|
|||
|
following example, `symbol_1' and `symbol_2' are assigned identical
|
|||
|
values:
|
|||
|
SECTIONS{ ...
|
|||
|
.output1 :
|
|||
|
{
|
|||
|
start_of_output_1 = ABSOLUTE(.);
|
|||
|
...
|
|||
|
}
|
|||
|
.output :
|
|||
|
{
|
|||
|
symbol_1 = ADDR(.output1);
|
|||
|
symbol_2 = start_of_output_1;
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
`LOADADDR(SECTION)'
|
|||
|
Return the absolute load address of the named SECTION. This is
|
|||
|
normally the same as `ADDR', but it may be different if the `AT'
|
|||
|
keyword is used in the section definition (*note Section
|
|||
|
Options::.).
|
|||
|
|
|||
|
`ALIGN(EXP)'
|
|||
|
Return the result of the current location counter (`.') aligned to
|
|||
|
the next EXP boundary. EXP must be an expression whose value is a
|
|||
|
power of two. This is equivalent to
|
|||
|
(. + EXP - 1) & ~(EXP - 1)
|
|||
|
|
|||
|
`ALIGN' doesn't change the value of the location counter--it just
|
|||
|
does arithmetic on it. As an example, to align the output `.data'
|
|||
|
section to the next `0x2000' byte boundary after the preceding
|
|||
|
section and to set a variable within the section to the next
|
|||
|
`0x8000' boundary after the input sections:
|
|||
|
SECTIONS{ ...
|
|||
|
.data ALIGN(0x2000): {
|
|||
|
*(.data)
|
|||
|
variable = ALIGN(0x8000);
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
The first use of `ALIGN' in this example specifies the location of
|
|||
|
a section because it is used as the optional START attribute of a
|
|||
|
section definition (*note Section Options::.). The second use
|
|||
|
simply defines the value of a variable.
|
|||
|
|
|||
|
The built-in `NEXT' is closely related to `ALIGN'.
|
|||
|
|
|||
|
`DEFINED(SYMBOL)'
|
|||
|
Return 1 if SYMBOL is in the linker global symbol table and is
|
|||
|
defined, otherwise return 0. You can use this function to provide
|
|||
|
default values for symbols. For example, the following
|
|||
|
command-file fragment shows how to set a global symbol `begin' to
|
|||
|
the first location in the `.text' section--but if a symbol called
|
|||
|
`begin' already existed, its value is preserved:
|
|||
|
|
|||
|
SECTIONS{ ...
|
|||
|
.text : {
|
|||
|
begin = DEFINED(begin) ? begin : . ;
|
|||
|
...
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
`NEXT(EXP)'
|
|||
|
Return the next unallocated address that is a multiple of EXP.
|
|||
|
This function is closely related to `ALIGN(EXP)'; unless you use
|
|||
|
the `MEMORY' command to define discontinuous memory for the output
|
|||
|
file, the two functions are equivalent.
|
|||
|
|
|||
|
`SIZEOF(SECTION)'
|
|||
|
Return the size in bytes of the named SECTION, if that section has
|
|||
|
been allocated. In the following example, `symbol_1' and
|
|||
|
`symbol_2' are assigned identical values:
|
|||
|
SECTIONS{ ...
|
|||
|
.output {
|
|||
|
.start = . ;
|
|||
|
...
|
|||
|
.end = . ;
|
|||
|
}
|
|||
|
symbol_1 = .end - .start ;
|
|||
|
symbol_2 = SIZEOF(.output);
|
|||
|
... }
|
|||
|
|
|||
|
`SIZEOF_HEADERS'
|
|||
|
`sizeof_headers'
|
|||
|
Return the size in bytes of the output file's headers. You can
|
|||
|
use this number as the start address of the first section, if you
|
|||
|
choose, to facilitate paging.
|
|||
|
|
|||
|
`MAX(EXP1, EXP2)'
|
|||
|
Returns the maximum of EXP1 and EXP2.
|
|||
|
|
|||
|
`MIN(EXP1, EXP2)'
|
|||
|
Returns the minimum of EXP1 and EXP2.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Semicolons, Prev: Arithmetic Functions, Up: Expressions
|
|||
|
|
|||
|
Semicolons
|
|||
|
----------
|
|||
|
|
|||
|
Semicolons (";") are required in the following places. In all other
|
|||
|
places they can appear for aesthetic reasons but are otherwise ignored.
|
|||
|
|
|||
|
`Assignment'
|
|||
|
Semicolons must appear at the end of assignment expressions.
|
|||
|
*Note Assignment::
|
|||
|
|
|||
|
`PHDRS'
|
|||
|
Semicolons must appear at the end of a `PHDRS' statement. *Note
|
|||
|
PHDRS::
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: MEMORY, Next: SECTIONS, Prev: Expressions, Up: Commands
|
|||
|
|
|||
|
Memory Layout
|
|||
|
=============
|
|||
|
|
|||
|
The linker's default configuration permits allocation of all
|
|||
|
available memory. You can override this configuration by using the
|
|||
|
`MEMORY' command. The `MEMORY' command describes the location and size
|
|||
|
of blocks of memory in the target. By using it carefully, you can
|
|||
|
describe which memory regions may be used by the linker, and which
|
|||
|
memory regions it must avoid. The linker does not shuffle sections to
|
|||
|
fit into the available regions, but does move the requested sections
|
|||
|
into the correct regions and issue errors when the regions become too
|
|||
|
full.
|
|||
|
|
|||
|
A command file may contain at most one use of the `MEMORY' command;
|
|||
|
however, you can define as many blocks of memory within it as you wish.
|
|||
|
The syntax is:
|
|||
|
|
|||
|
MEMORY
|
|||
|
{
|
|||
|
NAME (ATTR) : ORIGIN = ORIGIN, LENGTH = LEN
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
`NAME'
|
|||
|
is a name used internally by the linker to refer to the region. Any
|
|||
|
symbol name may be used. The region names are stored in a separate
|
|||
|
name space, and will not conflict with symbols, file names or
|
|||
|
section names. Use distinct names to specify multiple regions.
|
|||
|
|
|||
|
`(ATTR)'
|
|||
|
is an optional list of attributes, permitted for compatibility
|
|||
|
with the AT&T linker but not used by `ld' beyond checking that the
|
|||
|
attribute list is valid. Valid attribute lists must be made up of
|
|||
|
the characters "`LIRWX'". If you omit the attribute list, you may
|
|||
|
omit the parentheses around it as well.
|
|||
|
|
|||
|
`ORIGIN'
|
|||
|
is the start address of the region in physical memory. It is an
|
|||
|
expression that must evaluate to a constant before memory
|
|||
|
allocation is performed. The keyword `ORIGIN' may be abbreviated
|
|||
|
to `org' or `o' (but not, for example, `ORG').
|
|||
|
|
|||
|
`LEN'
|
|||
|
is the size in bytes of the region (an expression). The keyword
|
|||
|
`LENGTH' may be abbreviated to `len' or `l'.
|
|||
|
|
|||
|
For example, to specify that memory has two regions available for
|
|||
|
allocation--one starting at 0 for 256 kilobytes, and the other starting
|
|||
|
at `0x40000000' for four megabytes:
|
|||
|
|
|||
|
MEMORY
|
|||
|
{
|
|||
|
rom : ORIGIN = 0, LENGTH = 256K
|
|||
|
ram : org = 0x40000000, l = 4M
|
|||
|
}
|
|||
|
|
|||
|
Once you have defined a region of memory named MEM, you can direct
|
|||
|
specific output sections there by using a command ending in `>MEM'
|
|||
|
within the `SECTIONS' command (*note Section Options::.). If the
|
|||
|
combined output sections directed to a region are too big for the
|
|||
|
region, the linker will issue an error message.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: SECTIONS, Next: PHDRS, Prev: MEMORY, Up: Commands
|
|||
|
|
|||
|
Specifying Output Sections
|
|||
|
==========================
|
|||
|
|
|||
|
The `SECTIONS' command controls exactly where input sections are
|
|||
|
placed into output sections, their order in the output file, and to
|
|||
|
which output sections they are allocated.
|
|||
|
|
|||
|
You may use at most one `SECTIONS' command in a script file, but you
|
|||
|
can have as many statements within it as you wish. Statements within
|
|||
|
the `SECTIONS' command can do one of three things:
|
|||
|
|
|||
|
* define the entry point;
|
|||
|
|
|||
|
* assign a value to a symbol;
|
|||
|
|
|||
|
* describe the placement of a named output section, and which input
|
|||
|
sections go into it.
|
|||
|
|
|||
|
You can also use the first two operations--defining the entry point
|
|||
|
and defining symbols--outside the `SECTIONS' command: *note Entry
|
|||
|
Point::., and *Note Assignment::. They are permitted here as well for
|
|||
|
your convenience in reading the script, so that symbols and the entry
|
|||
|
point can be defined at meaningful points in your output-file layout.
|
|||
|
|
|||
|
If you do not use a `SECTIONS' command, the linker places each input
|
|||
|
section into an identically named output section in the order that the
|
|||
|
sections are first encountered in the input files. If all input
|
|||
|
sections are present in the first file, for example, the order of
|
|||
|
sections in the output file will match the order in the first input
|
|||
|
file.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Section Definition:: Section Definitions
|
|||
|
* Section Placement:: Section Placement
|
|||
|
* Section Data Expressions:: Section Data Expressions
|
|||
|
* Section Options:: Optional Section Attributes
|
|||
|
* Overlays:: Overlays
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Section Definition, Next: Section Placement, Up: SECTIONS
|
|||
|
|
|||
|
Section Definitions
|
|||
|
-------------------
|
|||
|
|
|||
|
The most frequently used statement in the `SECTIONS' command is the
|
|||
|
"section definition", which specifies the properties of an output
|
|||
|
section: its location, alignment, contents, fill pattern, and target
|
|||
|
memory region. Most of these specifications are optional; the simplest
|
|||
|
form of a section definition is
|
|||
|
SECTIONS { ...
|
|||
|
SECNAME : {
|
|||
|
CONTENTS
|
|||
|
}
|
|||
|
... }
|
|||
|
|
|||
|
SECNAME is the name of the output section, and CONTENTS a specification
|
|||
|
of what goes there--for example, a list of input files or sections of
|
|||
|
input files (*note Section Placement::.). As you might assume, the
|
|||
|
whitespace shown is optional. You do need the colon `:' and the braces
|
|||
|
`{}', however.
|
|||
|
|
|||
|
SECNAME must meet the constraints of your output format. In formats
|
|||
|
which only support a limited number of sections, such as `a.out', the
|
|||
|
name must be one of the names supported by the format (`a.out', for
|
|||
|
example, allows only `.text', `.data' or `.bss'). If the output format
|
|||
|
supports any number of sections, but with numbers and not names (as is
|
|||
|
the case for Oasys), the name should be supplied as a quoted numeric
|
|||
|
string. A section name may consist of any sequence of characters, but
|
|||
|
any name which does not conform to the standard `ld' symbol name syntax
|
|||
|
must be quoted. *Note Symbol Names: Symbols.
|
|||
|
|
|||
|
The special SECNAME `/DISCARD/' may be used to discard input
|
|||
|
sections. Any sections which are assigned to an output section named
|
|||
|
`/DISCARD/' are not included in the final link output.
|
|||
|
|
|||
|
The linker will not create output sections which do not have any
|
|||
|
contents. This is for convenience when referring to input sections that
|
|||
|
may or may not exist. For example,
|
|||
|
.foo { *(.foo) }
|
|||
|
will only create a `.foo' section in the output file if there is a
|
|||
|
`.foo' section in at least one input file.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Section Placement, Next: Section Data Expressions, Prev: Section Definition, Up: SECTIONS
|
|||
|
|
|||
|
Section Placement
|
|||
|
-----------------
|
|||
|
|
|||
|
In a section definition, you can specify the contents of an output
|
|||
|
section by listing particular input files, by listing particular
|
|||
|
input-file sections, or by a combination of the two. You can also place
|
|||
|
arbitrary data in the section, and define symbols relative to the
|
|||
|
beginning of the section.
|
|||
|
|
|||
|
The CONTENTS of a section definition may include any of the
|
|||
|
following kinds of statement. You can include as many of these as you
|
|||
|
like in a single section definition, separated from one another by
|
|||
|
whitespace.
|
|||
|
|
|||
|
`FILENAME'
|
|||
|
You may simply name a particular input file to be placed in the
|
|||
|
current output section; *all* sections from that file are placed
|
|||
|
in the current section definition. If the file name has already
|
|||
|
been mentioned in another section definition, with an explicit
|
|||
|
section name list, then only those sections which have not yet
|
|||
|
been allocated are used.
|
|||
|
|
|||
|
To specify a list of particular files by name:
|
|||
|
.data : { afile.o bfile.o cfile.o }
|
|||
|
|
|||
|
The example also illustrates that multiple statements can be
|
|||
|
included in the contents of a section definition, since each file
|
|||
|
name is a separate statement.
|
|||
|
|
|||
|
`FILENAME( SECTION )'
|
|||
|
`FILENAME( SECTION , SECTION, ... )'
|
|||
|
`FILENAME( SECTION SECTION ... )'
|
|||
|
You can name one or more sections from your input files, for
|
|||
|
insertion in the current output section. If you wish to specify a
|
|||
|
list of input-file sections inside the parentheses, you may
|
|||
|
separate the section names by either commas or whitespace.
|
|||
|
|
|||
|
`* (SECTION)'
|
|||
|
`* (SECTION, SECTION, ...)'
|
|||
|
`* (SECTION SECTION ...)'
|
|||
|
Instead of explicitly naming particular input files in a link
|
|||
|
control script, you can refer to *all* files from the `ld' command
|
|||
|
line: use `*' instead of a particular file name before the
|
|||
|
parenthesized input-file section list.
|
|||
|
|
|||
|
If you have already explicitly included some files by name, `*'
|
|||
|
refers to all *remaining* files--those whose places in the output
|
|||
|
file have not yet been defined.
|
|||
|
|
|||
|
For example, to copy sections `1' through `4' from an Oasys file
|
|||
|
into the `.text' section of an `a.out' file, and sections `13' and
|
|||
|
`14' into the `.data' section:
|
|||
|
SECTIONS {
|
|||
|
.text :{
|
|||
|
*("1" "2" "3" "4")
|
|||
|
}
|
|||
|
|
|||
|
.data :{
|
|||
|
*("13" "14")
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
`[ SECTION ... ]' used to be accepted as an alternate way to
|
|||
|
specify named sections from all unallocated input files. Because
|
|||
|
some operating systems (VMS) allow brackets in file names, that
|
|||
|
notation is no longer supported.
|
|||
|
|
|||
|
`FILENAME`( COMMON )''
|
|||
|
`*( COMMON )'
|
|||
|
Specify where in your output file to place uninitialized data with
|
|||
|
this notation. `*(COMMON)' by itself refers to all uninitialized
|
|||
|
data from all input files (so far as it is not yet allocated);
|
|||
|
FILENAME`(COMMON)' refers to uninitialized data from a particular
|
|||
|
file. Both are special cases of the general mechanisms for
|
|||
|
specifying where to place input-file sections: `ld' permits you to
|
|||
|
refer to uninitialized data as if it were in an input-file section
|
|||
|
named `COMMON', regardless of the input file's format.
|
|||
|
|
|||
|
In any place where you may use a specific file or section name, you
|
|||
|
may also use a wildcard pattern. The linker handles wildcards much as
|
|||
|
the Unix shell does. A `*' character matches any number of characters.
|
|||
|
A `?' character matches any single character. The sequence `[CHARS]'
|
|||
|
will match a single instance of any of the CHARS; the `-' character may
|
|||
|
be used to specify a range of characters, as in `[a-z]' to match any
|
|||
|
lower case letter. A `\' character may be used to quote the following
|
|||
|
character.
|
|||
|
|
|||
|
When a file name is matched with a wildcard, the wildcard characters
|
|||
|
will not match a `/' character (used to separate directory names on
|
|||
|
Unix). A pattern consisting of a single `*' character is an exception;
|
|||
|
it will always match any file name. In a section name, the wildcard
|
|||
|
characters will match a `/' character.
|
|||
|
|
|||
|
Wildcards only match files which are explicitly specified on the
|
|||
|
command line. The linker does not search directories to expand
|
|||
|
wildcards. However, if you specify a simple file name--a name with no
|
|||
|
wildcard characters--in a linker script, and the file name is not also
|
|||
|
specified on the command line, the linker will attempt to open the file
|
|||
|
as though it appeared on the command line.
|
|||
|
|
|||
|
In the following example, the command script arranges the output file
|
|||
|
into three consecutive sections, named `.text', `.data', and `.bss',
|
|||
|
taking the input for each from the correspondingly named sections of
|
|||
|
all the input files:
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
.text : { *(.text) }
|
|||
|
.data : { *(.data) }
|
|||
|
.bss : { *(.bss) *(COMMON) }
|
|||
|
}
|
|||
|
|
|||
|
The following example reads all of the sections from file `all.o'
|
|||
|
and places them at the start of output section `outputa' which starts
|
|||
|
at location `0x10000'. All of section `.input1' from file `foo.o'
|
|||
|
follows immediately, in the same output section. All of section
|
|||
|
`.input2' from `foo.o' goes into output section `outputb', followed by
|
|||
|
section `.input1' from `foo1.o'. All of the remaining `.input1' and
|
|||
|
`.input2' sections from any files are written to output section
|
|||
|
`outputc'.
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
outputa 0x10000 :
|
|||
|
{
|
|||
|
all.o
|
|||
|
foo.o (.input1)
|
|||
|
}
|
|||
|
outputb :
|
|||
|
{
|
|||
|
foo.o (.input2)
|
|||
|
foo1.o (.input1)
|
|||
|
}
|
|||
|
outputc :
|
|||
|
{
|
|||
|
*(.input1)
|
|||
|
*(.input2)
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
This example shows how wildcard patterns might be used to partition
|
|||
|
files. All `.text' sections are placed in `.text', and all `.bss'
|
|||
|
sections are placed in `.bss'. For all files beginning with an upper
|
|||
|
case character, the `.data' section is placed into `.DATA'; for all
|
|||
|
other files, the `.data' section is placed into `.data'.
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
.text : { *(.text) }
|
|||
|
.DATA : { [A-Z]*(.data) }
|
|||
|
.data : { *(.data) }
|
|||
|
.bss : { *(.bss) }
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Section Data Expressions, Next: Section Options, Prev: Section Placement, Up: SECTIONS
|
|||
|
|
|||
|
Section Data Expressions
|
|||
|
------------------------
|
|||
|
|
|||
|
The foregoing statements arrange, in your output file, data
|
|||
|
originating from your input files. You can also place data directly in
|
|||
|
an output section from the link command script. Most of these
|
|||
|
additional statements involve expressions (*note Expressions::.).
|
|||
|
Although these statements are shown separately here for ease of
|
|||
|
presentation, no such segregation is needed within a section definition
|
|||
|
in the `SECTIONS' command; you can intermix them freely with any of the
|
|||
|
statements we've just described.
|
|||
|
|
|||
|
`CREATE_OBJECT_SYMBOLS'
|
|||
|
Create a symbol for each input file in the current section, set to
|
|||
|
the address of the first byte of data written from that input
|
|||
|
file. For instance, with `a.out' files it is conventional to have
|
|||
|
a symbol for each input file. You can accomplish this by defining
|
|||
|
the output `.text' section as follows:
|
|||
|
SECTIONS {
|
|||
|
.text 0x2020 :
|
|||
|
{
|
|||
|
CREATE_OBJECT_SYMBOLS
|
|||
|
*(.text)
|
|||
|
_etext = ALIGN(0x2000);
|
|||
|
}
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
If `sample.ld' is a file containing this script, and `a.o', `b.o',
|
|||
|
`c.o', and `d.o' are four input files with contents like the
|
|||
|
following--
|
|||
|
/* a.c */
|
|||
|
|
|||
|
afunction() { }
|
|||
|
int adata=1;
|
|||
|
int abss;
|
|||
|
|
|||
|
`ld -M -T sample.ld a.o b.o c.o d.o' would create a map like this,
|
|||
|
containing symbols matching the object file names:
|
|||
|
00000000 A __DYNAMIC
|
|||
|
00004020 B _abss
|
|||
|
00004000 D _adata
|
|||
|
00002020 T _afunction
|
|||
|
00004024 B _bbss
|
|||
|
00004008 D _bdata
|
|||
|
00002038 T _bfunction
|
|||
|
00004028 B _cbss
|
|||
|
00004010 D _cdata
|
|||
|
00002050 T _cfunction
|
|||
|
0000402c B _dbss
|
|||
|
00004018 D _ddata
|
|||
|
00002068 T _dfunction
|
|||
|
00004020 D _edata
|
|||
|
00004030 B _end
|
|||
|
00004000 T _etext
|
|||
|
00002020 t a.o
|
|||
|
00002038 t b.o
|
|||
|
00002050 t c.o
|
|||
|
00002068 t d.o
|
|||
|
|
|||
|
`SYMBOL = EXPRESSION ;'
|
|||
|
`SYMBOL F= EXPRESSION ;'
|
|||
|
SYMBOL is any symbol name (*note Symbols::.). "F=" refers to any
|
|||
|
of the operators `&= += -= *= /=' which combine arithmetic and
|
|||
|
assignment.
|
|||
|
|
|||
|
When you assign a value to a symbol within a particular section
|
|||
|
definition, the value is relative to the beginning of the section
|
|||
|
(*note Assignment::.). If you write
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
abs = 14 ;
|
|||
|
...
|
|||
|
.data : { ... rel = 14 ; ... }
|
|||
|
abs2 = 14 + ADDR(.data);
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
`abs' and `rel' do not have the same value; `rel' has the same
|
|||
|
value as `abs2'.
|
|||
|
|
|||
|
`BYTE(EXPRESSION)'
|
|||
|
`SHORT(EXPRESSION)'
|
|||
|
`LONG(EXPRESSION)'
|
|||
|
`QUAD(EXPRESSION)'
|
|||
|
By including one of these four statements in a section definition,
|
|||
|
you can explicitly place one, two, four, or eight bytes
|
|||
|
(respectively) at the current address of that section. `QUAD' is
|
|||
|
only supported when using a 64 bit host or target.
|
|||
|
|
|||
|
Multiple-byte quantities are represented in whatever byte order is
|
|||
|
appropriate for the output file format (*note BFD::.).
|
|||
|
|
|||
|
`FILL(EXPRESSION)'
|
|||
|
Specify the "fill pattern" for the current section. Any otherwise
|
|||
|
unspecified regions of memory within the section (for example,
|
|||
|
regions you skip over by assigning a new value to the location
|
|||
|
counter `.') are filled with the two least significant bytes from
|
|||
|
the EXPRESSION argument. A `FILL' statement covers memory
|
|||
|
locations *after* the point it occurs in the section definition; by
|
|||
|
including more than one `FILL' statement, you can have different
|
|||
|
fill patterns in different parts of an output section.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Section Options, Next: Overlays, Prev: Section Data Expressions, Up: SECTIONS
|
|||
|
|
|||
|
Optional Section Attributes
|
|||
|
---------------------------
|
|||
|
|
|||
|
Here is the full syntax of a section definition, including all the
|
|||
|
optional portions:
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
...
|
|||
|
SECNAME START BLOCK(ALIGN) (NOLOAD) : AT ( LDADR )
|
|||
|
{ CONTENTS } >REGION :PHDR =FILL
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
SECNAME and CONTENTS are required. *Note Section Definition::, and
|
|||
|
*Note Section Placement::, for details on CONTENTS. The remaining
|
|||
|
elements--START, `BLOCK(ALIGN)', `(NOLOAD)', `AT ( LDADR )', `>REGION',
|
|||
|
`:PHDR', and `=FILL'--are all optional.
|
|||
|
|
|||
|
`START'
|
|||
|
You can force the output section to be loaded at a specified
|
|||
|
address by specifying START immediately following the section name.
|
|||
|
START can be represented as any expression. The following example
|
|||
|
generates section OUTPUT at location `0x40000000':
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
...
|
|||
|
output 0x40000000: {
|
|||
|
...
|
|||
|
}
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
`BLOCK(ALIGN)'
|
|||
|
You can include `BLOCK()' specification to advance the location
|
|||
|
counter `.' prior to the beginning of the section, so that the
|
|||
|
section will begin at the specified alignment. ALIGN is an
|
|||
|
expression.
|
|||
|
|
|||
|
`(NOLOAD)'
|
|||
|
Use `(NOLOAD)' to prevent a section from being loaded into memory
|
|||
|
each time it is accessed. For example, in the script sample
|
|||
|
below, the `ROM' segment is addressed at memory location `0' and
|
|||
|
does not need to be loaded into each object file:
|
|||
|
|
|||
|
SECTIONS {
|
|||
|
ROM 0 (NOLOAD) : { ... }
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
`AT ( LDADR )'
|
|||
|
The expression LDADR that follows the `AT' keyword specifies the
|
|||
|
load address of the section. The default (if you do not use the
|
|||
|
`AT' keyword) is to make the load address the same as the
|
|||
|
relocation address. This feature is designed to make it easy to
|
|||
|
build a ROM image. For example, this `SECTIONS' definition
|
|||
|
creates two output sections: one called `.text', which starts at
|
|||
|
`0x1000', and one called `.mdata', which is loaded at the end of
|
|||
|
the `.text' section even though its relocation address is
|
|||
|
`0x2000'. The symbol `_data' is defined with the value `0x2000':
|
|||
|
|
|||
|
SECTIONS
|
|||
|
{
|
|||
|
.text 0x1000 : { *(.text) _etext = . ; }
|
|||
|
.mdata 0x2000 :
|
|||
|
AT ( ADDR(.text) + SIZEOF ( .text ) )
|
|||
|
{ _data = . ; *(.data); _edata = . ; }
|
|||
|
.bss 0x3000 :
|
|||
|
{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}
|
|||
|
}
|
|||
|
|
|||
|
The run-time initialization code (for C programs, usually `crt0')
|
|||
|
for use with a ROM generated this way has to include something like
|
|||
|
the following, to copy the initialized data from the ROM image to
|
|||
|
its runtime address:
|
|||
|
|
|||
|
char *src = _etext;
|
|||
|
char *dst = _data;
|
|||
|
|
|||
|
/* ROM has data at end of text; copy it. */
|
|||
|
while (dst < _edata) {
|
|||
|
*dst++ = *src++;
|
|||
|
}
|
|||
|
|
|||
|
/* Zero bss */
|
|||
|
for (dst = _bstart; dst< _bend; dst++)
|
|||
|
*dst = 0;
|
|||
|
|
|||
|
`>REGION'
|
|||
|
Assign this section to a previously defined region of memory.
|
|||
|
*Note MEMORY::.
|
|||
|
|
|||
|
`:PHDR'
|
|||
|
Assign this section to a segment described by a program header.
|
|||
|
*Note PHDRS::. If a section is assigned to one or more segments,
|
|||
|
then all subsequent allocated sections will be assigned to those
|
|||
|
segments as well, unless they use an explicitly `:PHDR' modifier.
|
|||
|
To prevent a section from being assigned to a segment when it would
|
|||
|
normally default to one, use `:NONE'.
|
|||
|
|
|||
|
`=FILL'
|
|||
|
Including `=FILL' in a section definition specifies the initial
|
|||
|
fill value for that section. You may use any expression to
|
|||
|
specify FILL. Any unallocated holes in the current output section
|
|||
|
when written to the output file will be filled with the two least
|
|||
|
significant bytes of the value, repeated as necessary. You can
|
|||
|
also change the fill value with a `FILL' statement in the CONTENTS
|
|||
|
of a section definition.
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Overlays, Prev: Section Options, Up: SECTIONS
|
|||
|
|
|||
|
Overlays
|
|||
|
--------
|
|||
|
|
|||
|
The `OVERLAY' command provides an easy way to describe sections
|
|||
|
which are to be loaded as part of a single memory image but are to be
|
|||
|
run at the same memory address. At run time, some sort of overlay
|
|||
|
manager will copy the overlaid sections in and out of the runtime memory
|
|||
|
address as required, perhaps by simply manipulating addressing bits.
|
|||
|
This approach can be useful, for example, when a certain region of
|
|||
|
memory is faster than another.
|
|||
|
|
|||
|
The `OVERLAY' command is used within a `SECTIONS' command. It
|
|||
|
appears as follows:
|
|||
|
OVERLAY START : [ NOCROSSREFS ] AT ( LDADDR )
|
|||
|
{
|
|||
|
SECNAME1 { CONTENTS } :PHDR =FILL
|
|||
|
SECNAME2 { CONTENTS } :PHDR =FILL
|
|||
|
...
|
|||
|
} >REGION :PHDR =FILL
|
|||
|
|
|||
|
Everything is optional except `OVERLAY' (a keyword), and each
|
|||
|
section must have a name (SECNAME1 and SECNAME2 above). The section
|
|||
|
definitions within the `OVERLAY' construct are identical to those
|
|||
|
within the general `SECTIONS' contruct (*note SECTIONS::.), except that
|
|||
|
no addresses and no memory regions may be defined for sections within
|
|||
|
an `OVERLAY'.
|
|||
|
|
|||
|
The sections are all defined with the same starting address. The
|
|||
|
load addresses of the sections are arranged such that they are
|
|||
|
consecutive in memory starting at the load address used for the
|
|||
|
`OVERLAY' as a whole (as with normal section definitions, the load
|
|||
|
address is optional, and defaults to the start address; the start
|
|||
|
address is also optional, and defaults to `.').
|
|||
|
|
|||
|
If the `NOCROSSREFS' keyword is used, and there any references among
|
|||
|
the sections, the linker will report an error. Since the sections all
|
|||
|
run at the same address, it normally does not make sense for one
|
|||
|
section to refer directly to another. *Note NOCROSSREFS: Option
|
|||
|
Commands.
|
|||
|
|
|||
|
For each section within the `OVERLAY', the linker automatically
|
|||
|
defines two symbols. The symbol `__load_start_SECNAME' is defined as
|
|||
|
the starting load address of the section. The symbol
|
|||
|
`__load_stop_SECNAME' is defined as the final load address of the
|
|||
|
section. Any characters within SECNAME which are not legal within C
|
|||
|
identifiers are removed. C (or assembler) code may use these symbols
|
|||
|
to move the overlaid sections around as necessary.
|
|||
|
|
|||
|
At the end of the overlay, the value of `.' is set to the start
|
|||
|
address of the overlay plus the size of the largest section.
|
|||
|
|
|||
|
Here is an example. Remember that this would appear inside a
|
|||
|
`SECTIONS' construct.
|
|||
|
|
|||
|
OVERLAY 0x1000 : AT (0x4000)
|
|||
|
{
|
|||
|
.text0 { o1/*.o(.text) }
|
|||
|
.text1 { o2/*.o(.text) }
|
|||
|
}
|
|||
|
|
|||
|
This will define both `.text0' and `.text1' to start at address
|
|||
|
0x1000. `.text0' will be loaded at address 0x4000, and `.text1' will
|
|||
|
be loaded immediately after `.text0'. The following symbols will be
|
|||
|
defined: `__load_start_text0', `__load_stop_text0',
|
|||
|
`__load_start_text1', `__load_stop_text1'.
|
|||
|
|
|||
|
C code to copy overlay `.text1' into the overlay area might look
|
|||
|
like the following.
|
|||
|
|
|||
|
extern char __load_start_text1, __load_stop_text1;
|
|||
|
memcpy ((char *) 0x1000, &__load_start_text1,
|
|||
|
&__load_stop_text1 - &__load_start_text1);
|
|||
|
|
|||
|
Note that the `OVERLAY' command is just syntactic sugar, since
|
|||
|
everything it does can be done using the more basic commands. The above
|
|||
|
example could have been written identically as follows.
|
|||
|
|
|||
|
.text0 0x1000 : AT (0x4000) { o1/*.o(.text) }
|
|||
|
__load_start_text0 = LOADADDR (.text0);
|
|||
|
__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0);
|
|||
|
.text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) { o2/*.o(.text) }
|
|||
|
__load_start_text1 = LOADADDR (.text1);
|
|||
|
__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1);
|
|||
|
. = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1));
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: PHDRS, Next: Entry Point, Prev: SECTIONS, Up: Commands
|
|||
|
|
|||
|
ELF Program Headers
|
|||
|
===================
|
|||
|
|
|||
|
The ELF object file format uses "program headers", which are read by
|
|||
|
the system loader and describe how the program should be loaded into
|
|||
|
memory. These program headers must be set correctly in order to run the
|
|||
|
program on a native ELF system. The linker will create reasonable
|
|||
|
program headers by default. However, in some cases, it is desirable to
|
|||
|
specify the program headers more precisely; the `PHDRS' command may be
|
|||
|
used for this purpose. When the `PHDRS' command is used, the linker
|
|||
|
will not generate any program headers itself.
|
|||
|
|
|||
|
The `PHDRS' command is only meaningful when generating an ELF output
|
|||
|
file. It is ignored in other cases. This manual does not describe the
|
|||
|
details of how the system loader interprets program headers; for more
|
|||
|
information, see the ELF ABI. The program headers of an ELF file may
|
|||
|
be displayed using the `-p' option of the `objdump' command.
|
|||
|
|
|||
|
This is the syntax of the `PHDRS' command. The words `PHDRS',
|
|||
|
`FILEHDR', `AT', and `FLAGS' are keywords.
|
|||
|
|
|||
|
PHDRS
|
|||
|
{
|
|||
|
NAME TYPE [ FILEHDR ] [ PHDRS ] [ AT ( ADDRESS ) ]
|
|||
|
[ FLAGS ( FLAGS ) ] ;
|
|||
|
}
|
|||
|
|
|||
|
The NAME is used only for reference in the `SECTIONS' command of the
|
|||
|
linker script. It does not get put into the output file.
|
|||
|
|
|||
|
Certain program header types describe segments of memory which are
|
|||
|
loaded from the file by the system loader. In the linker script, the
|
|||
|
contents of these segments are specified by directing allocated output
|
|||
|
sections to be placed in the segment. To do this, the command
|
|||
|
describing the output section in the `SECTIONS' command should use
|
|||
|
`:NAME', where NAME is the name of the program header as it appears in
|
|||
|
the `PHDRS' command. *Note Section Options::.
|
|||
|
|
|||
|
It is normal for certain sections to appear in more than one segment.
|
|||
|
This merely implies that one segment of memory contains another. This
|
|||
|
is specified by repeating `:NAME', using it once for each program
|
|||
|
header in which the section is to appear.
|
|||
|
|
|||
|
If a section is placed in one or more segments using `:NAME', then
|
|||
|
all subsequent allocated sections which do not specify `:NAME' are
|
|||
|
placed in the same segments. This is for convenience, since generally
|
|||
|
a whole set of contiguous sections will be placed in a single segment.
|
|||
|
To prevent a section from being assigned to a segment when it would
|
|||
|
normally default to one, use `:NONE'.
|
|||
|
|
|||
|
The `FILEHDR' and `PHDRS' keywords which may appear after the
|
|||
|
program header type also indicate contents of the segment of memory.
|
|||
|
The `FILEHDR' keyword means that the segment should include the ELF
|
|||
|
file header. The `PHDRS' keyword means that the segment should include
|
|||
|
the ELF program headers themselves.
|
|||
|
|
|||
|
The TYPE may be one of the following. The numbers indicate the
|
|||
|
value of the keyword.
|
|||
|
|
|||
|
`PT_NULL' (0)
|
|||
|
Indicates an unused program header.
|
|||
|
|
|||
|
`PT_LOAD' (1)
|
|||
|
Indicates that this program header describes a segment to be
|
|||
|
loaded from the file.
|
|||
|
|
|||
|
`PT_DYNAMIC' (2)
|
|||
|
Indicates a segment where dynamic linking information can be found.
|
|||
|
|
|||
|
`PT_INTERP' (3)
|
|||
|
Indicates a segment where the name of the program interpreter may
|
|||
|
be found.
|
|||
|
|
|||
|
`PT_NOTE' (4)
|
|||
|
Indicates a segment holding note information.
|
|||
|
|
|||
|
`PT_SHLIB' (5)
|
|||
|
A reserved program header type, defined but not specified by the
|
|||
|
ELF ABI.
|
|||
|
|
|||
|
`PT_PHDR' (6)
|
|||
|
Indicates a segment where the program headers may be found.
|
|||
|
|
|||
|
EXPRESSION
|
|||
|
An expression giving the numeric type of the program header. This
|
|||
|
may be used for types not defined above.
|
|||
|
|
|||
|
It is possible to specify that a segment should be loaded at a
|
|||
|
particular address in memory. This is done using an `AT' expression.
|
|||
|
This is identical to the `AT' command used in the `SECTIONS' command
|
|||
|
(*note Section Options::.). Using the `AT' command for a program
|
|||
|
header overrides any information in the `SECTIONS' command.
|
|||
|
|
|||
|
Normally the segment flags are set based on the sections. The
|
|||
|
`FLAGS' keyword may be used to explicitly specify the segment flags.
|
|||
|
The value of FLAGS must be an integer. It is used to set the `p_flags'
|
|||
|
field of the program header.
|
|||
|
|
|||
|
Here is an example of the use of `PHDRS'. This shows a typical set
|
|||
|
of program headers used on a native ELF system.
|
|||
|
|
|||
|
PHDRS
|
|||
|
{
|
|||
|
headers PT_PHDR PHDRS ;
|
|||
|
interp PT_INTERP ;
|
|||
|
text PT_LOAD FILEHDR PHDRS ;
|
|||
|
data PT_LOAD ;
|
|||
|
dynamic PT_DYNAMIC ;
|
|||
|
}
|
|||
|
|
|||
|
SECTIONS
|
|||
|
{
|
|||
|
. = SIZEOF_HEADERS;
|
|||
|
.interp : { *(.interp) } :text :interp
|
|||
|
.text : { *(.text) } :text
|
|||
|
.rodata : { *(.rodata) } /* defaults to :text */
|
|||
|
...
|
|||
|
. = . + 0x1000; /* move to a new page in memory */
|
|||
|
.data : { *(.data) } :data
|
|||
|
.dynamic : { *(.dynamic) } :data :dynamic
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Entry Point, Next: Version Script, Prev: PHDRS, Up: Commands
|
|||
|
|
|||
|
The Entry Point
|
|||
|
===============
|
|||
|
|
|||
|
The linker command language includes a command specifically for
|
|||
|
defining the first executable instruction in an output file (its "entry
|
|||
|
point"). Its argument is a symbol name:
|
|||
|
ENTRY(SYMBOL)
|
|||
|
|
|||
|
Like symbol assignments, the `ENTRY' command may be placed either as
|
|||
|
an independent command in the command file, or among the section
|
|||
|
definitions within the `SECTIONS' command--whatever makes the most
|
|||
|
sense for your layout.
|
|||
|
|
|||
|
`ENTRY' is only one of several ways of choosing the entry point.
|
|||
|
You may indicate it in any of the following ways (shown in descending
|
|||
|
order of priority: methods higher in the list override methods lower
|
|||
|
down).
|
|||
|
* the `-e' ENTRY command-line option;
|
|||
|
|
|||
|
* the `ENTRY(SYMBOL)' command in a linker control script;
|
|||
|
|
|||
|
* the value of the symbol `start', if present;
|
|||
|
|
|||
|
* the address of the first byte of the `.text' section, if present;
|
|||
|
|
|||
|
* The address `0'.
|
|||
|
|
|||
|
For example, you can use these rules to generate an entry point with
|
|||
|
an assignment statement: if no symbol `start' is defined within your
|
|||
|
input files, you can simply define it, assigning it an appropriate
|
|||
|
value--
|
|||
|
|
|||
|
start = 0x2020;
|
|||
|
|
|||
|
The example shows an absolute address, but you can use any expression.
|
|||
|
For example, if your input object files use some other symbol-name
|
|||
|
convention for the entry point, you can just assign the value of
|
|||
|
whatever symbol contains the start address to `start':
|
|||
|
|
|||
|
start = other_symbol ;
|
|||
|
|
|||
|
|
|||
|
File: ld.info, Node: Version Script, Next: Option Commands, Prev: Entry Point, Up: Commands
|
|||
|
|
|||
|
Version Script
|
|||
|
==============
|
|||
|
|
|||
|
The linker command script includes a command specifically for
|
|||
|
specifying a version script, and is only meaningful for ELF platforms
|
|||
|
that support shared libraries. A version script can be build directly
|
|||
|
into the linker script that you are using, or you can supply the
|
|||
|
version script as just another input file to the linker at the time
|
|||
|
that you link. The command script syntax is:
|
|||
|
VERSION { version script contents }
|
|||
|
The version script can also be specified to the linker by means of
|
|||
|
the `--version-script' linker command line option. Version scripts are
|
|||
|
only meaningful when creating shared libraries.
|
|||
|
|
|||
|
The format of the version script itself is identical to that used by
|
|||
|
Sun's linker in Solaris 2.5. Versioning is done by defining a tree of
|
|||
|
version nodes with the names and interdependencies specified in the
|
|||
|
version script. The version script can specify which symbols are bound
|
|||
|
to which version nodes, and it can reduce a specified set of symbols to
|
|||
|
local scope so that they are not globally visible outside of the shared
|
|||
|
library.
|
|||
|
|
|||
|
The easiest way to demonstrate the version script language is with a
|
|||
|
few examples.
|
|||
|
|
|||
|
VERS_1.1 {
|
|||
|
global:
|
|||
|
foo1;
|
|||
|
local:
|
|||
|
old*;
|
|||
|
original*;
|
|||
|
new*;
|
|||
|
};
|
|||
|
|
|||
|
VERS_1.2 {
|
|||
|
foo2;
|
|||
|
} VERS_1.1;
|
|||
|
|
|||
|
VERS_2.0 {
|
|||
|
bar1; bar2;
|
|||
|
} VERS_1.2;
|
|||
|
|
|||
|
In this example, three version nodes are defined. `VERS_1.1' is the
|
|||
|
first version node defined, and has no other dependencies. The symbol
|
|||
|
`foo1' is bound to this version node, and a number of symbols that have
|
|||
|
appeared within various object files are reduced in scope to local so
|
|||
|
that they are not visible outside of the shared library.
|
|||
|
|
|||
|
Next, the node `VERS_1.2' is defined. It depends upon `VERS_1.1'.
|
|||
|
The symbol `foo2' is bound to this version node.
|
|||
|
|
|||
|
Finally, the node `VERS_2.0' is defined. It depends upon
|
|||
|
`VERS_1.2'. The symbols `bar1' and `bar2' are bound to this version
|
|||
|
node.
|
|||
|
|
|||
|
Symbols defined in the library which aren't specifically bound to a
|
|||
|
version node are effectively bound to an unspecified base version of the
|
|||
|
library. It is possible to bind all otherwise unspecified symbols to a
|
|||
|
given version node using `global: *' somewhere in the version script.
|
|||
|
|
|||
|
Lexically the names of the version nodes have no specific meaning
|
|||
|
other than what they might suggest to the person reading them. The
|
|||
|
`2.0' version could just as well have appeared in between `1.1' and
|
|||
|
`1.2'. However, this would be a confusing way to write a version
|
|||
|
script.
|
|||
|
|
|||
|
When you link an application against a shared library that has
|
|||
|
versioned symbols, the application itself knows which version of each
|
|||
|
symbol it requires, and it also knows which version nodes it needs from
|
|||
|
each shared library it is linked against. Thus at runtime, the dynamic
|
|||
|
loader can make a quick check to make sure that the libraries you have
|
|||
|
linked against do in fact supply all of the version nodes that the
|
|||
|
application will need to resolve all of the dynamic symbols. In this
|
|||
|
way it is possible for the dynamic linker to know with certainty that
|
|||
|
all external symbols that it needs will be resolvable without having to
|
|||
|
search for each symbol reference.
|
|||
|
|
|||
|
The symbol versioning is in effect a much more sophisticated way of
|
|||
|
doing minor version checking that SunOS does. The fundamental problem
|
|||
|
that is being addressed here is that typically references to external
|
|||
|
functions are bound on an as-needed basis, and are not all bound when
|
|||
|
the application starts up. If a shared library is out of date, a
|
|||
|
required interface may be missing; when the application tries to use
|
|||
|
that interface, it may suddenly and unexpectedly fail. With symbol
|
|||
|
versioning, the user will get a warning when they start their program if
|
|||
|
the libraries being used with the application are too old.
|
|||
|
|
|||
|
There are several GNU extensions to Sun's versioning approach. The
|
|||
|
first of these is the ability to bind a symbol to a version node in the
|
|||
|
source file where the symbol is defined instead of in the versioning
|
|||
|
script. This was done mainly to reduce the burden on the library
|
|||
|
maintainer. This can be done by putting something like:
|
|||
|
|
|||
|
__asm__(".symver original_foo,foo@VERS_1.1");
|
|||
|
|
|||
|
in the C source file. This renamed the function `original_foo' to
|
|||
|
be an alias for `foo' bound to the version node `VERS_1.1'. The
|
|||
|
`local:' directive can be used to prevent the symbol `original_foo'
|
|||
|
from being exported.
|
|||
|
|
|||
|
The second GNU extension is to allow multiple versions of the same
|
|||
|
function to appear in a given shared library. In this way an
|
|||
|
incompatible change to an interface can take place without increasing
|
|||
|
the major version number of the shared library, while still allowing
|
|||
|
applications linked against the old interface to continue to function.
|
|||
|
|
|||
|
This can only be accomplished by using multiple `.symver' directives
|
|||
|
in the assembler. An example of this would be:
|
|||
|
|
|||
|
__asm__(".symver original_foo,foo@");
|
|||
|
__asm__(".symver old_foo,foo@VERS_1.1");
|
|||
|
__asm__(".symver old_foo1,foo@VERS_1.2");
|
|||
|
__asm__(".symver new_foo,foo@@VERS_2.0");
|
|||
|
|
|||
|
In this example, `foo@' represents the symbol `foo' bound to the
|
|||
|
unspecified base version of the symbol. The source file that contains
|
|||
|
this example would define 4 C functions: `original_foo', `old_foo',
|
|||
|
`old_foo1', and `new_foo'.
|
|||
|
|
|||
|
When you have multiple definitions of a given symbol, there needs to
|
|||
|
be some way to specify a default version to which external references to
|
|||
|
this symbol will be bound. This can be accomplished with the
|
|||
|
`foo@@VERS_2.0' type of `.symver' directive. Only one version of a
|
|||
|
symbol can be declared 'default' in this manner - otherwise you would
|
|||
|
effectively have multiple definitions of the same symbol.
|
|||
|
|
|||
|
If you wish to bind a reference to a specific version of the symbol
|
|||
|
within the shared library, you can use the aliases of convenience (i.e.
|
|||
|
`old_foo'), or you can use the `.symver' directive to specifically bind
|
|||
|
to an external version of the function in question.
|
|||
|
|