Oracle® Solaris 11.2 Linkers and Libraries Guide

Exit Print View

Updated: July 2014
 
 

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.

  • LOAD_SEGMENT

    A loadable segment contains code or data that is mapped into the address space of a process at runtime. The link-editor creates a PT_LOAD program header entry for each allocable segment, which is used by the runtime linker to locate and map the segment.

  • NOTE_SEGMENT

    A note segment contains note sections. The link-editor creates a PT_NOTE program header entry that references the segment. Note segments are not allocable.

  • NULL_SEGMENT

    A null segment holds sections that are included in the output object, but which are not available to the object at runtime. Common examples of such sections are the .symtab symbol table, and the various sections produced for the benefit of debuggers. No program header is created for a null segment.

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 0 or 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 related to the PADDR and VADDR attributes, and must be compatible with them.

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.

FILE_BASENAME, FILE_OBJNAME, FILE_PATH

These attributes allow 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/libfoo.a(bar.o)specifies the object bar.o, found in an archive named /lib/libfoo.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 examines the basename of 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 <sys/elf.h>, with the SHT_ prefix removed. For example, PROGBITS, SYMTAB, or NOBITS.

FLAGS

The FLAGS attribute uses section_flags to specify section attributes as a space separated list of one or more of the values given in Table 8–7, 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. In the following example, a section is defined allocable and not writable.

        ALLOC !WRITE

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.

Table 8-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 2 Gbytes

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 8–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 B, 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 must be 0 or a power of 2. 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 0 or 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.