Note: The link-editor used without a mapfile will always produce a valid ELF output file. The mapfile option provides the user with a great deal of flexibility and control over the output object, some of which has the potential to produce an invalid or unusable object. The user is expected to have knowledge of the rules and conventions that govern the ELF format.
The -M command line option is used to specify the mapfile to be used. Multiple mapfiles can be used in a single link operation. When more than one mapfile is specified, the link-editor processes each one in the order given, as if they represented a single logical mapfile. This occurs before any input objects are processed.
The system provides sample mapfiles for solving common problems in the /usr/lib/ld directory.
Any other character following a backslash is an error.
Escape Sequence Meaning \a alert (bell) \b backspace \f formfeed \n newline \r return \t horizontal tab \v vertical tab \\ backslash \' single quote \" double quote \ooo An octal constant, where ooo is one to three octal digits (0...7)
The following is a list of widely used names and other strings found in mapfiles:
Name Purpose segment_name Name of ELF segment section_name Name of ELF section symbol_name Name of ELF symbol file_path A Unix file path of slash (/) delimited names used to reference an ELF object, or an archive that contains ELF objects file_basename Final component (basename(1)) of a file_path objname Either a file_basename, or the name of an object contained within an archive soname Sharable object name, as used for the SONAME of a sharable object (e.g. libc.so.1) version_name Name of a symbol version, as used within an ELF versioning section inherited_version_name Name of a symbol version inherited by another symbol version
DATA and STACK are not unique values. Rather, they are formed from the combination of the READ, WRITE, and EXECUTE flags appropriate for the target platform.
Flag Value Meaning READ Segment is readable WRITE Segment is writable EXECUTE Segment is executable 0 All permission flags are cleared DATA Data segment flags for target platform (platform dependent) STACK Default stack flags as defined by platform ABI
$mapfile_version 2
A mapfile that does not begin with a version declaration is assumed to be written in the original mapfile language defined for System V Release 4 Unix (SVR4) by AT&T. The link-editor retains the ability to process such mapfiles. Their syntax is documented in Appendix ZZZ - AT&T System V Release 4 Mapping Syntax.
$if expr ... [$elif expr] ... [$else] ... $endif
Each of the directives ($if, $elif, $else, and $endif) appear alone on a line. The logical expressions in $if and subsequent $elif lines are evaluated in order until an expression that evaluates to True is found. Text following a line with a False value is discarded. The text following a successful directive line is treated normally. "Text" here refers to any material, that is not part of the conditional structure. Once a successful $if or $elif has been found, and its text processed, succeeding $elif and $else lines, together with their text, are discarded. If all the expressions are zero, and there is a $else, the text following the $else is treated normally.
The scope of an $if directive cannot extend across multiple mapfiles. A $if directive must be terminated by a matching $endif within the mapfile that uses it, or the link-editor will issue an error.
The link-editor maintains an internal table of names that can be used in the logical expressions evaluated by $if and $elif. At startup, this table is initialized with each of the following names that apply to the output object being created:
Name Meaning _ELF32 32-bit object _ELF64 64-bit object _sparc Sparc machine (32 or 64-bit) _x86 x86 machine (32 or 64-bit) true Always defined
The names are case sensitive, and must be used exactly as shown. For example, true is defined, but TRUE is not. Any of these names can be used by themselves as a logical expression. For example:
will evaluate to true, and allow the link-editor to process the enclosed text, when the output object is 64-bit. Although numeric values are not allowed in these logical expressions, a special exception is made for the value '1' which evaluates to true, and '0' for false.$if _ELF64 ... $endif
More complex logical expressions can be written, using the following operators:
Expressions are evaluated from left to right. Sub-expressions are evaluated before enclosing expressions.
Operator Meaning && Logical AND || Logical OR (expr) Sub-expression ! Negate boolean value of following expression
For example, the lines in the following construct will be evaluated when building 64-bit objects for X86 platforms:
The $add directive can be used to add a new name to the link-editor's table of known names. Using the above example, it might be convenient to define the name amd64 to stand for 64-bit x86 objects, in order to simplify $if directives:$if _ELF64 && _x86 ... $endif
We can use this to simplify our previous example:$if _ELF64 && _x86 $add amd64 $endif
The $clear directive is the reverse of the $add directive. It is used to remove names from the internal table:$if amd64 ... $endif
$clear amd64
The effect of the $add directive persists beyond the end of the mapfile that uses it, and is visible to any subsequent mapfile that is processed by the link-editor in the same link operation. If this is not desired, use $clear at the end of the mapfile containing the $add to remove it.
Finally, the $error directive causes the link-editor to print all remaining text on the line as a fatal error, and halt the link operation. This can be used to ensure that a programmer porting an object to a new machine type will not be able to silently build an incorrect object that is missing a necessary mapfile definition:
$if _sparc ... $elif _x86 ... $else $error unknown machine type $endif
C language programmers will recognize that the syntax used for mapfile conditional input resembles that of the C preprocessor macro language (cpp). This similarity is intentional. However, mapfile conditional input directives are by design considerably less powerful than those provided by cpp. They provide only the most basic facilities required to support linking operations in a cross platform environment.
Among the significant differences between the two languages:
The syntax of mapfile directives is based on the following generic forms:
Directive Purpose CAPABILITY Hardware and software capabilities DEPEND_VERSIONS Specify allowed versions from sharable object dependencies HDR_NOALLOC ELF header and program headers are not allocable LOAD_SEGMENT Create new loadable segment, or modify an existing one NOTE_SEGMENT Create note segment, or modify an existing one NULL_SEGMENT Create null segment, or modify an existing one PHDR_ADD_NULL Add Null Program Header Entries SEGMENT_ORDER Specify the order of segments in the output object and program header array. STACK Process Stack Attributes SYMBOL_SCOPE Set symbol attributes and scope within the unnamed global version SYMBOL_VERSION Set symbol attributes and scope within an explicitly named version
The simplest form is a directive name without a value:
The next form is a directive name with a value, or a whitespace separated list of values:directive;
directive = value...;
In addition to the '=' operator shown, the '+=' and '-=' forms of assignment are allowed. The '=' operator sets the given directive to the given value, or value list. The '+=' operator can be used to specify that the value on the right hand side is to be added to the current value, and the '-=' operator is used to remove values.
More complex directives manipulate items that take multiple attributes enclosed within {...} brackets to group the attributes together as a unit:
directive [name] {
attribute [= value];
...
} [name...];
There can be a name before the opening '{', which is used to name the result of the given statement. Similarly, one or more optional names may follow the closing '}', prior to the terminating ';'. These names are used to express that the named item being defined has relationship with other named items.
Note that the format for attributes within a grouping use the same syntax described for simple directives with a value above, with a '=', '+=', or '-=' assignment operator, followed by a value, or whitespace sepated list of values, terminated with a semicolon (';').
A directive may have sub-attributes that in turn have sub-attributes. In such cases, the sub-attributes are also grouped within nested { ... } brackets to reflect this hierarchy:
directive [name] {
attribute {
subattribute [= value];
...
};
...
} [name...];
The mapfile syntax grammar puts no limit on the depth to which such nesting is allowed. It depends solely on the requirements of the directive.
The specific syntax for each supported mapfile directive is shown in the sections that follow.
CAPABILITY {
HW = hwcap_flags;
HW += hwcap_flags;
HW -= hwcap_flags;
SF = sfcap_flags;
SF += sfcap_flags;
SF -= sfcap_flags;
HW_1 = value;
HW_1 += value;
HW_1 -= value;
HW_2 = value;
HW_2 += value;
HW_2 -= value;
SF_1 = value;
SF_1 += value;
SF_1 -= value;
};
For each capability, the link-editor maintains a current value (value),
and a set of values to be excluded (exclude). Prior to processing
mapfiles, both values are 0.
When processing a CAPABILITY mapfile directive:
Prior to wring the resulting capability value to the output object, the link-editor subtracts any capability values specified with the '-=' operator.
Within an ELF object, hardware and software capabilities are represented as bit assignments within one or more bitmasks found in the capabilities section of the object. The HW and SF mapfile attributes provide a more abstract view of this implementation, accepting a space separated list of symbolic capability names that the link-editor maps internally to the appropriate mask and bit. The numbered attributes (HW_1, etc) exist in order to allow direct numeric access to the underlying capability bitmasks. They can be used to specify capability bits that have not been officially defined. When possible, the HW and SF attributes should be used.
DEPEND_VERSIONS objname {
ALLOW = version_name;
REQUIRE = version_name;
...
}
objname is the name of the sharable object, as specified on the command line. In the common case where the object is specified via the -l command line option, this will be the specified name with a 'lib' prefix. For instance, libc is commonly referenced as '-lc' on the command line, and is therefore specified as 'libc.so' in a DEPEND_VERSIONS directive.
When HDR_NOALLOC is specified, the ELF header and Program Header array still appear at the start of the resulting output object file, but are not contained in a loadable segment, and virtual address calculations for the image start at the first section of the first segment rather than at the base of the ELF header.HDR_NOALLOC;
value must be a positive integer value, and gives the number of extra PT_NULL entries to create. All fields of the resulting program header entries will be set to 0.PHDR_ADD_NULL = value;
If segment_name is a pre-existing segment, then the attributes specified modify it. Otherwise, a new segment is created and the specified attributes are applied to it. The link-editor fills in default values for attributes not explicitly supplied.
Note: When selecting a segment name, bear in mind that future versions of the link-editor may add new predefined segments. If the name used in your segment directive matches this new name, it will alter the meaning of your mapfile, from creating a new segment to modifying an existing one. The best way to prevent this situation is to avoid generic names for segments, and give all of your segment names a unique prefix, such as a company/project identifier, or even the name of the program (e.g. hello_world_data_segment).
All three segment directives share a common set of core attributes. Substituting one of (LOAD_SEGMENT, NOTE_SEGMENT, NULL_SEGMENT) for directive in the following, the syntax for this shared core is:
directive segment_name {
ASSIGN_SECTION [assign_name];
ASSIGN_SECTION [assign_name] {
FILE_BASENAME = file_basename;
FILE_OBJNAME = objname;
FILE_PATH = file_path;
FLAGS = section_flags;
IS_NAME = section_name;
TYPE = section_type;
};
DISABLE;
IS_ORDER = assign_name ...;
IS_ORDER += assign_name ...;
OS_ORDER = section_name ...;
OS_ORDER += section_name ...;
};
The LOAD_SEGMENT directive accepts an additional set of attributes specific to loadable segments. The syntax for these additional attributes is:
LOAD_SEGMENT segment_name {
ALIGN = value;
FLAGS = segment_flags;
FLAGS += segment_flags;
FLAGS -= segment_flags;
MAX_SIZE = value;
NOHDR;
PADDR = value;
ROUND = value;
SIZE_SYMBOL = symbol_name ...;
SIZE_SYMBOL += symbol_name ...;
VADDR = value;
};
Any of the segment directives can be specified as an empty directive. When an empty segment directive creates a new segment, default values are established for all of its attributes:
LOAD_SEGMENT segment_name; NOTE_SEGMENT segment_name; NULL_SEGMENT segment_name;
All of the attributes accepted by one or more of the segment directives are described below.
The alignment specified must be a power of 2. By default, the link-editor sets the alignment of a segment to the built-in default. This default differs from one CPU to another and might even be different between software revisions.
The ALIGN attribute is mutually exclusive to the PADDR and VADDR attributes, and cannot be used with them together. When PADDR or VADDR is specified, the p_align field of the corresponding program header will be set to the default value.
Multiple ASSIGN_SECTION attributes are allowed for a given segment. Each ASSIGN_SECTION attribute is independent of the others. A section will be assigned to a segment if it satisfies any one of the ASSIGN_SECTION attributes. The link-editor will not assign sections to a segment unless it has at least one ASSIGN_SECTION attribute.
The link-editor uses an internal list of entrance criteria to assign sections to segments. Each ASSIGN_SECTION declaration encountered in the mapfile is placed on this list, in the order encountered. The entrance criteria for the built-in segments discussed in Predefined Segments are placed on this list immediately following the final mapfile defined entry.
The entrance criteria can be given an optional name (assign_name). This name can be used in conjunction with the IS_ORDER attribute to specify the order in which input sections are placed in the output section.
To place an input section, the link-editor starts at the head of the entrance criteria list, and compares the attributes of the section to each entrance criteria in turn. The section is assigned to the segment associated with the first entrance criteria that matches the section attributes exactly. If there is no match, the section is placed at the end of the file, as is generally the case for all non-allocable sections.
ASSIGN_SECTION accepts the following:
- FILE_BASENAME, FILE_OBJNAME, FILE_PATH
- These attribute allows the selection of sections based on the path (FILE_PATH), basename (FILE_BASENAME), or object name (FILE_OBJNAME) of the file they come from.
File paths are specified using the standard Unix slash delimited convention. The final path segment is the basename of the path, also known simply as the filename. In the case of an archive, the basename can be augmented with the name of the archive member, using the form archive_name(component_name) . For example, /lib/libc.a(printf.o) specifies the object printf.o, found in an archive named /lib/libc.a.
FILE_BASENAME and FILE_OBJNAME are equivalent when applied to a non-archive, and compare the given name to the basename of the file. When applied to an archive, FILE_BASENAME still examines the basename of the file (the archive name), while FILE_OBJNAME examines the name of the object contained within the archive.
Each ASSIGN_SECTION maintains a list of all FILE_BASENAME, FILE_PATH, and FILE_OBJNAME values. A file match occurs if any one of these definitions match an input file.
- IS_NAME
- Input section name
- TYPE
- Specifies an ELF section_type, which can be any of the SHT_ constants defined in
, with the SHT_ prefix removed. (e.g. PROGBITS, SYMTAB, NOBITS, etc). - FLAGS
- The FLAGS attribute uses section_flags to specify section attributes as a space separated list of one or more of the following values, which correspond to the SHF_ values defined in <sys/elf.h>:
If an individual flag is preceded by an exclamation mark (!), that attribute must explicitly not be present. For example,
Flag Value Meaning ALLOC Section is allocable WRITE Section is writable EXECUTE Section is executable AMD64_LARGE Section can be larger than 2GB ALLOC !WRITEspecifies that a section must be allocable, and not writable. Flags not explicitly in a section_flags list are ignored. In the above example, only the value of ALLOC and WRITE are examined when matching a section against the specified flags. The other section flags can have any value.
segment segment_name;
There are three forms allowed:
The simple '=' assignment operator replaces the current flags with the new set, the '+=' form adds the new flags to the existing set, and the '-=' form removes the specified flags from the existing set.FLAGS = segment_flags; FLAGS += segment_flags; FLAGS -= segment_flags;
When the '=' form of assignment is used, the previous value of IS_ORDER for the given segment is discarded, and replaced with the new list. The '+=' form of IS_ORDER concatenates the new list to the end of the existing list.
The IS_ORDER attribute is of particular interest when used in conjunction with the -xF option to the compilers. When a file is compiled with the -xF option, each function in that file is placed in a separate section with the same attributes as the .text section. These sections are called .text%function_name.
For example, a file containing three functions, main(), foo() and bar(), when compiled with the -xF option, yields a relocatable object file with text for the three functions being placed in sections called .text%main, .text%foo, and .text%bar. When the link-editor places these sections into the output, the '%' and anything following it are removed. Hence, all three of these functions will be placed in the .text output section. The IS_ORDER attribute can be used to force them to be placed in a specific order within the .text output section relative to each other.
Consider the following user-defined mapfile.
$mapfile_version 2
LOAD_SEGMENT text {
ASSIGN_SECTION text_bar { IS_NAME = .text%bar };
ASSIGN_SECTION text_main { IS_NAME = .text%main };
ASSIGN_SECTION text_foo { IS_NAME = .text%foo };
IS_ORDER = text_foo text_bar text_main;
};
No matter the order in which these three functions are found in the source
code, or encountered by the link-editor, their order in the output object
text segment will be foo, bar, main.
The NOHDR attribute differs from the top level HDR_NOALLOC directive in that it is a per-segment value, and only has an effect if the segment becomes the first loadable segment. This feature exists primarily to provide feature parity with the older mapfiles. See Appendix ZZZ - AT&T System V Mapping Syntax for more details.
The HDR_NOALLOC directive is recommended in preference to the segment NOHDR attribute.
The '=' form of assignment can be used to establish an initial value. It can only be used once per link-editor session. The '+=' form of SIZE_SYMBOL concatenates the new list to the end of the existing list, and can be used as many times as desired.
When the '=' form of assignment is used, the previous value of OS_ORDER for the given segment is discarded, and replaced with the new list. The '+=' form of OS_ORDER concatenates the new list to the end of the existing list.
SEGMENT_ORDER accepts a space separated list of segment names:
SEGMENT_ORDER = segment_name ...; SEGMENT_ORDER += segment_name ...;
When the '=' form of assignment is used, the previous segment order list is discarded, and replaced with the new list. The '+=' form of assignment concatenates the new list to the end of the existing list.
By default, the link-editor orders segments as follows:
Note: ELF has some implicit conventions that must be followed by a well formed object:Unless the HDR_NOALLOC directive is specified, the link-editor enforces the requirement that the first segment must be a loadable segment, and not a note or null segment. As HDR_NOALLOC cannot be used for non-kernel executables, it is of little practical use for most objects.Mapfiles can be used to create objects that violate these requirements. This should be avoided, as the result of running such an object is undefined.
- The first loadable segment is expected to be readonly, allocable, and executable, and receives the ELF header and program header array. This is usually the predefined text segment.
- The final loadable segment in an executable is expected to be writable, and the head of the dynamic heap is usually located immediately following within the same virtual memory mapping.
STACK {
FLAGS = segment_flags;
FLAGS += segment_flags;
FLAGS -= segment_flags;
};
The FLAGS attribute specifies
segment permissions as a
space separated list of permissions.
There are three forms allowed. The simple '=' assignment operator replaces the current flags with the new set, the '+=' form adds the new flags to the existing set, and the '-=' form removes the specified flags from the existing set.
The default stack permissions are defined by the platform ABI, and vary between platforms. The value for the target platform can be specified using the segment flag name 'STACK'.
On some platforms, the ABI mandated default permissions include EXECUTE. It is rarely if ever needed and is generally considered to be a potential security risk. Removing EXECUTE permission from the stack is a recommended practice:
STACK {
FLAGS -= EXECUTE;
};
The STACK directive is reflected in the output ELF object as a PT_SUNWSTACK program header entry.
The syntax for SYMBOL_VERSION is:
SYMBOL_VERSION version_name {
symbol_scope:
*;
symbol_name;
symbol_name {
AUXILIARY = soname;
FILTER = soname;
FLAGS = symbol_flags;
SIZE = value;
TYPE = symbol_type
VALUE = value;
};
} [inherited_version_name...];
SYMBOL_SCOPE is identical, except that it does not accept version names:
SYMBOL_SCOPE {
...
};
In a SYMBOL_VERSION directive, version_name
provides a label for this set of symbol definitions. It identifies a
version definition within the output object.
One or more inherited versions
(inherited_version_name) can
be specified,
separated by whitespace, in which case the newly defined version inherits from
the versions named.
See Chapter 5, "Application Binary Interfaces and Versioning."
symbol_scope defines the scope of symbols in a SYMBOL_SCOPE or SYMBOL_VERSION mapfile directive. By default, symbols are assumed to have global scope. This can be modified by specifying a symbol_scope followed by a colon (:). These lines determine the symbol scope for all symbols that follow, until changed by a subsequent scope declaration. The possible scope values and their meanings are given in the following table:
A symbol_name is the name of a symbol. This name can result in a symbol definition, or a symbol reference, depending on any qualifying attributes. In the simplest form, without any qualifying attributes, a symbol reference is created. This reference is exactly the same as would be generated using the -u option discussed in "Defining Additional Symbols with the -u option" on page 50. Typically, if the symbol name is followed by any qualifying attributes, then a symbol definition is generated using the associated attributes.
Scope Meaning default / global Global symbols of this scope are visible to all external objects. References to such symbols from within the object are bound at runtime, thus allowing interposition to take place. This visibility scope provides a default, that can be demoted, or eliminated by other symbol visibility techniques. This scope definition has the same affect as a symbol with STV_DEFAULT visibility. See Table 7-20. hidden / local Global symbols of this scope are reduced to symbols with a local binding. Symbols of this scope are not visible to other external objects. This scope definition has the same affect as a symbol with STV_HIDDEN visibility. See Table 7-20. protected / symbolic Global symbols of this scope are visible to all external objects. References to these symbols from within the object are bound at link-edit, thus preventing runtime interposition. This visibility scope can be demoted, or eliminated by other symbol visibility techniques. This scope definition has the same affect as a symbol with STV_PROTECTED visibility. See Table 7-20. exported Global symbols of this scope are visible to all external objects. References to such symbols from within the object are bound at runtime, thus allowing interposition to take place. This symbol visibility can not be demoted, or eliminated by any other symbol visibility technique. This scope definition has the same affect as a symbol with STV_EXPORTED visibility. See Table 7-20. singleton Global symbols of this scope are visible to all external objects. References to such symbols from within the object are bound at runtime, and ensure that only one instance of the symbol is bound to from all references within a process. This symbol visibility can not be demoted, or eliminated by any other symbol visibility technique. This scope definition has the same affect as a symbol with STV_SINGLETON visibility. See Table 7-20. eliminate Global symbols of this scope are hidden. Their symbol table entries are eliminated. This scope definition has the same affect as a symbol with STV_ELIMINATE visibility. See Table 7-20. Note that local symbols can also be eliminated by using the link-editor -z redlocsym option.
When a local scope is defined, the symbol name can be defined as the special auto-reduction directive "*". Symbols that have no explicitly defined visibility are demoted to a local binding within the dynamic object being generated. Explicit visibility definitions originate from mapfile definitions, or visibility definitions that are encapsulated within relocatable objects. Similarly, when an eliminate scope is defined, the symbol name can be defined as the special auto-elimination directive "*". Symbols that have no explicitly defined visibility are eliminated from the dynamic object being generated.
A symbol_name can be listed by itself in order to simply assign it to a version and/or specify its scope. Optional symbol attributes can be specified within {} brackets. Valid attributes are described below.
Flag Meaning DIRECT Indicates that this symbol should be directly bound to. When used with a symbol definition, this flag results in any reference from within the object being built to be directly bound to the definition. When used with a symbol reference, this flag results in a direct binding to the dependency that provides the definition. See Appendix D, "Direct Bindings." This flag can also be used with the PARENT flag to establish a direct binding to any parent at runtime. DYNSORT Indicates that this symbol should be included in a sort section. See "Symbol Sort Sections" on page 270. The symbol type must be STT_FUNC, STT_OBJECT, STT_COMMON, or STT_TLS. EXTERN Indicates the symbol is defined externally to the object being created. This flag is typically defined to label callback routines. Undefined symbols that would be flagged with the -z defs option are suppressed with this flag.
This flag is only meaningful when generating a symbol reference. Should a definition for this symbol occur within the objects combined at link-edit, then the flag is silently ignored.
INTERPOSE Indicates that this symbol acts an interposer. This flag can only be used when generating a dynamic executable. This flag provides for finer control of defining interposing symbols than is possible by using the -z interpose option. NODIRECT Indicates that this symbol should not be directly bound to. This state applies to references from within the object being created and from external references. See Appendix D, "Direct Bindings." This flag can also be used with the PARENT flag to prevent a direct binding to any parent at runtime. NODYNSORT Indicates that this symbol should not be included in a sort section. See "Symbol Sort Sections" on page 270. PARENT Indicates the symbol is defined in the parent of the object being created. A parent is an object that references this object at runtime as an explicit dependency. A parent can also reference this object at runtime using dlopen(3C). This flag is typically defined to label callback routines. This flag can be used with the DIRECT or NODIRECT flags to establish individual direct, or no-direct references to the parent. Undefined symbols that would be flagged with the -z defs option are suppressed with this flag. This flag is only meaningful when generating a symbol reference. Should a definition for this symbol occur within the objects combined at link-edit, then the flag is silently ignored.
A data attribute results in the creation of an OBJT symbol. A data attribute that is accompanied with a size, but no value creates a section symbol by associating the symbol with an ELF section. This section is filled with zeros. A function attribute results in the creation of an FUNC symbol.
A function attribute that is accompanied with a size, but no value creates a section symbol by associating the symbol with an ELF section. This section is assigned a void function, generated by the link-editor, with the signature:
void (*)(void)
A data or function attribute that is accompanied with a value results in the appropriate symbol type together with an absolute, ABS, section index.
The creation of a section data symbol is useful for the creation of filters. External references to a section data symbol of a filter from an executable result in the appropriate copy relocation being generated. See "Copy Relocations" on page 146.
The text, data, and extra segments are of primary interest, while the others serve more specialized purposes, as described below.
The text segment is the first segment in the process, so the link-editor will place the ELF header, and the program header array into it. This can be prevented using the HDR_NOALLOC mapfile directive.
If p_memsz is greater than p_filesz, the extra bytes are NOBITS. The first p_filesz bytes come from the object file, and any remaining bytes up to p_memsz are zeroed by the system prior to use.p_memsz >= p_filesz
The default assignment rules send readonly NOBITS sections to the text segment, and writable NOBITS sections to the data segment. The link-editor defines the bss segment as an alternative segment that can accept writable NOBITS sections. This segment is disabled by default, and must be explicitly enabled to be used.
Since writable NOBITS sections are easily handled as part of the data segment, the benefit of having a separate bss segment may not be immediately obvious. By convention, the process dynamic memory heap starts at the end of the final segment, which must be writable. This is usually the data segment, but if bss is enabled, it becomes the final segment. When building a dynamic executable, enabling the bss segment with an appropriate alignment can be used to enable large page assignment of the heap. For example, the following enables the bss segment and sets an alignment of 4MB:
LOAD_SEGMENT bss {
ALIGN=0x400000;
};
Note:
Users are cautioned that an alignment specification may be machine-specific,
and may lose its benefit on different hardware platforms. A more flexible
means of requesting the most optimal underlying page size may evolve in
future releases.
1 $mapfile_version 2
2 LOAD_SEGMENT elephant {
3 ASSIGN_SECTION {
4 IS_NAME=.data;
5 FILE_PATH=peanuts.o;
6 };
7 ASSIGN_SECTION {
8 IS_NAME=.data;
9 FILE_OBJNAME=popcorn.o;
10 };
11 };
12
13 LOAD_SEGMENT monkey {
14 VADDR=0x80000000;
15 MAX_SIZE=0x4000;
16 ASSIGN_SECTION {
17 TYPE=progbits;
18 FLAGS=ALLOC EXECUTE;
19 };
20 ASSIGN_SECTION {
21 IS_NAME=.data
22 };
23 };
24
25 LOAD_SEGMENT donkey {
26 FLAGS=READ EXECUTE;
27 ALIGN=0x1000;
28 ASSIGN_SECTION {
29 IS_NAME=.data;
30 };
31 };
32
33 LOAD_SEGMENT text {
34 VADDR=0x80008000
35 };
Four separate segments are manipulated in this example.
Every mapfile starts with a mapfile version declaration as shown
on line 1. Segment elephant
(lines 2-11) receives all of the data sections from the files peanuts.o
or popcorn.o. Note that popcorn .o
can come from an archive (in which case the archive file can have
any name), or it can come from any file with a basename of popcorn.o.
In contrast, peanuts.o can only come from a file with exactly that name.
For example, if /var/tmp/peanuts.o was supplied to the link-edit, it
does not match peanuts.o.
Segment monkey (lines 13-23) has a virtual address of 0x80000000, and a maximum length of 0x4000. This segment receives all sections that are both PROGBITS and allocable-executable, as well as all sections not already in the segment elephant with the name .data. The .data sections entering the monkey segment need not be PROGBITS or allocable-executable, because they match the entrance criteria on line 20 rather than the one on line 16. This illustrates that an "and" relationship exists between the sub-attributes within a ASSIGN_SECTION attribute, while an "or" relationship exists between the different ASSIGN_SECTION attributes for a single segment.
The donkey segment (lines 25-31) is given non-default permission flags and alignment, and will accept all sections named .data. However, this segment will never be assigned any sections, and as a result, segment donkey will never appear in the output object. The reason for this is that the link-editor examines entrance criteria in the order they appear in the mapfile. In this mapfile, segment elephant accepts some .data sections, and segment takes any that are left, leaving none for donkey.
Lines 33-35 set the virtual address of the text segment to 0x80008000. The text segment is one of the standard predefined segments, as described in Predefined Segments, so this statement modifies the existing segment rather than creating a new one.
1 $mapfile_version 2
2 HDR_NOALLOC;
3
4 LOAD_SEGMENT text {
5 VADDR=0xf0004000;
6 FLAGS=READ EXECUTE;
7 OS_ORDER=.text .rodata;
9 ASSIGN_SECTION {
10 TYPE=PROGBITS;
11 FLAGS=ALLOC !WRITE;
12 };
13 };
14
15 LOAD_SEGMENT data {
16 FLAGS=READ WRITE EXECUTE;
17 ALIGN=0x1000;
18 ROUND=0x1000;
19 };
As always, the first line declares the mapfile language version used by
the mapfile. The HDR_NOALLOC directive (line 2) specifies that the
resulting object should not include the ELF header or program
header array within the first allocable segment in the object, which
is the predefined text segment.
The segment directive on lines 4-13 set a virtual address and permission flags for the text segment. It also specifies that sections named .text sections should be placed at the head of the segment, followed by any sections named .rodata, and that all other sections will follow these. Finally, allocable, non-writable PROGBITS sections are assigned to it.
The segment directive on lines 15-19 specifies that the data segment must be aligned on a boundary of 0x1000. This has the effect of aligning the first section within the segment at the same alignment. The length of the segment is to be rounded up to a multiple of the same value as the alignment. The segment permissions are set to read, write, and execute.