Linker and Libraries Guide

LOAD_SEGMENT / NOTE_SEGMENT / NULL_SEGMENT Directives

A segment is a contiguous portion of the output object that contains sections. The mapfile segment directives allow the specification of three different segment types.

Segment directives are used to create new segments in the output file, or to change the attribute values of an existing segment. An existing segment is one that was previous defined, or one of the built-in segments discussed in Predefined Segments. Each new segment is added to the object after the last such segment of the same type. Loadable segments are added first, then note segments, and finally null segments. Any program headers associated with these segments are placed in the program header array in the same relative order as the segments themselves. This default placement can be altered by setting an explicit address in the case of a loadable segment, or using the SEGMENT_ORDER directive.

If segment_name is a preexisting segment, then the attributes specified modify the existing segment. Otherwise, a new segment is created and the specified attributes are applied to the new segment. The link-editor fills in default values for attributes not explicitly supplied.


Note –

When selecting a segment name, bear in mind that a future version of the link-editor might add new predefined segments. If the name used in your segment directive matches this new name, the new predefined segment 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. For example, a program named hello_world might use the segment name 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, a segment declaration is as follows.

        
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 of these additional attributes is as follows.

        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 segment attributes. Empty segments are declared as follows.

        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.

ALIGN Attribute (LOAD_SEGMENT only)

The ALIGN attribute is used to specify the alignment for a loadable segment. The value specified is set in the p_align field of the program header corresponding to the segment. Segment alignment is used in calculating the virtual address of the beginning of the segment.

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. When PADDR or VADDR is specified, the p_align field of the corresponding program header will be set to the default value.

ASSIGN_SECTION Attribute

ASSIGN_SECTION specifies a combination of section attributes, such as section name, type, and flags, that collectively qualify a section for assignment to a given segment. Each such set of attributes is called an entrance criterion. A section matches when the section attributes match those of an entrance criterion exactly. An ASSIGN_SECTION that does not specify any attributes matches any section that criterion is compared to.

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 the section matches any one of the ASSIGN_SECTION definitions associated with that segment. The link-editor will not assign sections to a segment unless the segment 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 criterion 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 criterion in turn. The section is assigned to the segment associated with the first entrance criterion 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.

Table 9–7 Section FLAGS Values

Flag Value 

Meaning 

ALLOC

Section is allocable 

WRITE

Section is writable 

EXECUTE

Section is executable 

AMD64_LARGE

Section can be larger than 2GB 

DISABLE Attribute

The DISABLE attribute causes the link-editor to ignore the segment. No sections will be assigned to a disabled segment. The segment is automatically re-enabled when referenced by a following segment directive. Hence, an empty reference suffices to re-enable a disabled section.

segment segment_name;

FLAGS Attribute (LOAD_SEGMENT only)

The FLAGS attribute specifies segment permissions as a space separated list of the permissions in Table 9–3. By default, user defined segments receive READ, WRITE, and EXECUTE permissions. The default flags for the predefined segments described in Predefined Segments are supplied by the link-editor, and in some cases can be platform-dependent.

There are three forms allowed.

        FLAGS  = segment_flags...;
        FLAGS += segment_flags...;
        FLAGS -= segment_flags...;

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.

IS_ORDER Attribute

The link-editor normally places output sections into the segment in the order they are encountered. Similarly, the input sections that make up the output section are placed in the order they are encountered. The IS_ORDER attribute can be used to alter this default placement of input sections. IS_ORDER specifies a space separated list of entrance criterion names (assign_name). Sections matched by one of these entrance criteria are placed at the head of the output section, sorted in the order given by IS_ORDER. Sections matched by entrance criteria not found in the IS_ORDER list are placed following the sorted sections, in the order they are encountered.

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 the % 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(), and main().

MAX_SIZE Attribute (LOAD_SEGMENT only)

By default, the link-editor will allow a segment to grow to the size required by the contents of the segment. The MAX_SIZE attribute can be used to specify a maximum size for the segment. If MAX_SIZE is set, the link-editor will generate an error if the segment grows beyond the specified size.

NOHDR Attribute (LOAD_SEGMENT only)

If a segment with the NOHDR attribute set becomes the first loadable segment in the output object, the ELF and program headers will not be included within the segment.

The NOHDR attribute differs from the top level HDR_NOALLOC directive in that HDR_NOALLOC 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 E, System V Release 4 (Version 1) Mapfiles for more details.

The HDR_NOALLOC directive is recommended in preference to the segment NOHDR attribute.

OS_ORDER Attribute

The link-editor normally places output sections into the segment in the order they are encountered. The OS_ORDER attribute can be used to alter this default placement of output sections. OS_ORDER specifies a space separated list of output section names (section_name). The listed sections are placed at the head of the segment, sorted in the order given by OS_ORDER. Sections not listed in OS_ORDER are placed following the sorted sections, in the order they are encountered.

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.

PADDR Attribute (LOAD_SEGMENT only)

The PADDR attribute is used to specify an explicit physical address for the segment. The value specified is set in the p_addr field of the program header corresponding to the segment. By default, the link-editor sets the physical address of segments to 0, as this field has no meaning for user mode objects, and is primarily of interest non-userland objects such as operating system kernels.

ROUND Attribute (LOAD_SEGMENT only)

The ROUND attribute is used to specify that the size of the segment should be rounded up to the given value. The rounding value specified must be a power of 2. By default, the link-editor sets the rounding factor of a segment to 1, meaning that the segment size is not rounded up.

SIZE_SYMBOL Attribute (LOAD_SEGMENT only)

The SIZE_SYMBOL attribute defines a space separated list of section size symbol names to be created by the link-editor. A size symbol is a global-absolute symbol that represents the size, in bytes, of the segment. These symbols can be referenced in your object files. In order to access the symbol within your code, you should ensure that symbol_name is a legal identifier in that language. The symbol naming rules for the C programming language are recommended, as such symbols are likely to be accessible from any other language.

The “=” form of assignment can be used to establish an initial value, and 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.

VADDR (LOAD_SEGMENT only)

The VADDR attribute is used to specify an explicit virtual address for the segment. The value specified is set in the p_vaddr field of the program header corresponding to the segment. By default, the link-editor assigns virtual addresses to segments as the output file is created.