search    
HP-UX Linker and Libraries User's Guide
Hewlett-Packard
Using Mapfiles

This chapter describes with examples how to use the mapfile option.


Note

In most cases, the linker produces a correct executable without the use of the mapfile option. The mapfile option is an advanced feature of the linker toolset intended for system programming use, not for application programming use. When using the mapfile option, you can easily create executable files that do not execute.


Controlling Mapfiles with the -k Option

The -k option to ld specifies a text file containing mapfile directives:

	ld -k mapfile [flags] files ...
	

The ld command automatically maps sections from input object files onto output segments in executable files. The mapfile option allows you to change the default mapping provided by the linker.

Use the -k mapfile option to specify a text file that contains mapfile directives. The linker appends the specified mapfile to the default mapfile unless you specify the +nodefaultmap option.

Changing Mapfiles with -k filename and +nodefaultmap

The +nodefaultmap option used with -k option prevents the linker from concatenating the default memory map to the map provided by mapfile. If you specify +nodefaultmap, the linker does not append the default mapfile to your mapfile. If you do not specify +nodefaultmap with -k, the linker appends the default to the output file.


Mapfile Example: Using -k mapfile and +nodefaultmap
	cat mapfile
	
	text = LOAD ?RX V0x1000;
	text : .rodata;
	text : .PARISC.milli;
	text : .dynamic;
	text : .dynsym;
	text : .dynstr;
	text : .hash;
	text : $PROGBITS ?AX;
	text : .PARISC.unwind;
	text : $UNWIND;
	data = LOAD ?RW V0x4000000040001000;
	data : .opd;
	data : .plt;
	data : .dlt;
	data : .data;
	data : $PROGBITS ?AW!S;
	data : .sdata;
	data : $PROGBITS ?AWS;
	data : .sbss;
	data : $NOBITS ?AWS;
	data : .bss;
	data : $NOBITS ?AW!S;
	note = NOTE;
	note : $NOTE;
	
	# text segment
	text = LOAD ?RX V0x04000000;
	text : .dynamic;
	text : .dynsym;
	text : .dynstr;
	text : .hash;
	text : .rela.dlt;
	text : .rela.plt;
	text : .rela.opd;
	text : $RELA ?A;
	text : $REL ?A;
	text : .IA_64.unwind_hdr;
	text : $UNWIND ?A;
	text : .IA_64.unwind_info;
	text : $PROGBITS ?A!X!W;
	text : .IA_64.milli;
	text : .text;text : $PROGBITS ?AX!W;
	 
	# data segment
	data = LOAD ?RW V0x40000000;
	data : .data;
	data : $PROGBITS ?AW!S;
	data : .preinit_array;
	data : .init_array;
	data : .fini_array;
	data : .opd;
	data : .plt;
	data : .dlt;
	data : .sdata;
	data : $PROGBITS ?AWS;
	data : .sbss;
	data : $NOBITS ?AWS;
	data : .bss;
	data : $NOBITS ?AW!S;
	
	cc -c main.c ld main.o +nodefaultmap -k mapfile main.o -lc
	
	elfdump -h -S a.out
	
	a.out:
	
	*** Section Header ***
	 
	Index  Type Vaddr    Offset   Size     Name
	 
	1      DYNM 04000138 00000138 000000d0 .dynamic
	2      DYNS 04000208 00000208 00002ec0 .dynsym
	3      STRT 040030c8 000030c8 000022be .dynstr
	4      HASH 04005388 00005388 00001190 .hash
	5      RELA 04006518 00006518 000000cc .rela.dlt
	6      RELA 040065e4 000065e4 00000018 .rela.plt
	7      RELA 040065fc 000065fc 0000000c .rela.HP.preinit
	8      RELA 04006608 00006608 000000b4 .rela.data
	9      PBIT 040066c0 000066c0 00000018 .IA_64.unwind_hdr
	10     UNWI 040066d8 000066d8 00002214 .IA_64.unwind
	11     PBIT 040088ec 000088ec 0000621c .IA_64.unwind_info
	12     HP_O 0400eb08 0000eb08 000044f8 .HP.opt_annot
	13     PBIT 04013000 00013000 00003c08 .rodata
	14     PBIT 04016c08 00016c08 000000a0 .interp
	15     PBIT 04016ca8 00016ca8 00000bb0 .dynhash
	16     PBIT 04017858 00017858 000000d0 .opd
	17     PBIT 04017980 00017980 00065460 .text
	18     PBIT 0407cde0 0007cde0 00000050 .bortext
	19     PBIT 40000000 0007d000 000018c8 .data
	20     PBIT 400018c8 0007e8c8 00000008 .HP.preinit
	21     PBIT 400018d0 0007e8d0 00000020 .plt
	22     PBIT 400018f0 0007e8f0 00000638 .dlt
	23     PBIT 40001f28 0007ef28 00000000 .HP.init
	24     PREI 40001f28 0007ef28 00000000 .preinit_array
	25     INIT 40001f28 0007ef28 00000000 .init_array
	26     FINI 40001f28 0007ef28 00000000 .fini_array
	27     PBIT 40001f28 0007ef28 000002cc .sdata
	28     NOBI 400021f8 0007f1f4 000000e0 .sbss
	29     NOBI 400022e0 0007f1f4 00005420 .bss
	30     NOBI 40007700 0007f1f4 00000028 .tbss
	31     NOBI 40007728 0007f1f4 00000000 .hbss
	32     PBIT 00000000 0007f1f4 00000000 .fastbind
	33     NOTE 00000000 0007f1f8 00006fb8 .note
	34     STRT 00000000 000861b0 0000600a .strtab
	35     SYMT 00000000 0008c1c0 000068e0 .symtab
	36     STRT 00000000 00092aa0 00000152 .shstrtab
	

Simple Mapfile

The following directives show how a simple mapfile would appear:

	# text segment
	text = LOAD ?RX;
	text : .rodata ?A;
	text : $PROGBITS ?AX;
	 
	# data segment
	data = LOAD ?RW;
	data : $PROGBITS ?AW!S;
	data : $PROGBITS ?AWS;
	data : $NOBITS ?AWS;
	data : $NOBITS ?AW!S;
	 
	# note segment
	note = NOTE;
	note : $NOTE;
	 
	# non-segment
	nonsegment = NONSEGMENT;
	

Default HP-UX 11.0 Release Mapfile

The IPF 32-bit linker uses the following default mapfile:

	# text segment
	text = LOAD ?RXlc V0x04000000;
	text : .dynamic;
	text : .dynsym;
	text : .dynstr;
	text : .hash;
	text : .rela.plt;
	text : .rela.dlt;
	text : .rela.opd;
	text : .rela.preinit_array;
	text : .rela.init_array;
	text : .rela.fini_array;
	text : $RELA ?A;
	text : $REL ?A;
	text : .IA_64.unwind_hdr;
	text : $UNWIND ?A;
	text : .IA_64.unwind_info;
	text : .HP.opt_annot;
	text : $PROGBITS ?A!X!W;
	text : .IA_64.milli;
	text : .text;
	text : $PROGBITS ?AX!W;
	text : $OVLBITS ?AX!W;
	 
	# data segment
	data = LOAD ?RWm V0x40000000;
	data : .zeropage;
	data : .hdata;
	data : .data;
	data : $PROGBITS ?AW!S;
	data : .preinit_array;
	data : .init_array;
	data : .fini_array;
	data : .opd;
	data : .plt;
	data : .dlt;
	data : .sdata;
	data : $PROGBITS ?AWS;
	data : .sbss;
	data : $NOBITS ?AWS;
	data : .bss;
	data : $NOBITS ?AW!S;
	data : .hbss;
	 
	# thread specific storage segment
	thread_specific = HP_TLS ?RW;
	thread_specific : .tbss;
	thread_specific : $NOBITS ?AWT;
	 
	# note segment
	note = NOTE;
	note : $NOTE;
	 
	# non-segment
	nonsegment = NONSEGMENT;
	nonsegment : .debug_abbrev;
	nonsegment : .debug_info;
	nonsegment : .debug_loc;
	nonsegment : .debug_line;
	nonsegment : .debug_str;
	

The HP-UX 11i version 1.5 64-bit linker uses the following default mapfile:

	# text segment
	text = LOAD ?RXlc V0x4000000000000000;
	text : .dynamic;
	text : .dynsym;
	text : .dynstr;
	text : .hash;
	text : .rela.plt;
	text : .rela.dlt;
	text : .rela.opd;
	text : .rela.preinit_array;
	text : .rela.init_array;
	text : .rela.fini_array;
	text : $RELA ?A;
	text : $REL ?A;
	text : .IA_64.unwind_hdr;
	text : $UNWIND ?A;
	text : .IA_64.unwind_info;
	text : .HP.opt_annot;
	text : $PROGBITS ?A!X!W;
	text : .IA_64.milli;
	text : .text;
	text : $PROGBITS ?AX!W;
	text : $OVLBITS ?AX!W;
	 
	# data segment
	data = LOAD ?RWmo V0x6000000000000000;
	data : .zeropage;
	data : .hdata;
	data : .data;
	data : $PROGBITS ?AW!S;
	data : .preinit_array;
	data : .init_array;
	data : .fini_array;
	data : .opd;
	data : .plt;
	data : .dlt;
	data : .sdata;
	data : $PROGBITS ?AWS;
	data : .sbss;
	data : $NOBITS ?AWS;
	data : .bss;
	data : $NOBITS ?AW!S;data : .hbss;
	 
	# thread specific storage segment
	thread_specific = HP_TLS ?RW;
	thread_specific : .tbss;
	thread_specific : $NOBITS ?AWT;
	 
	# note segment
	note = NOTE;
	note : $NOTE;
	 
	# non-segment
	nonsegment = NONSEGMENT;
	nonsegment : .debug_abbrev;
	nonsegment : .debug_info;
	nonsegment : .debug_loc;
	nonsegment : .debug_line;
	nonsegment : .debug_str;
	

Defining Syntax for Mapfile Directives

A mapfile can have zero or more mapfile directives. There are two types of mapfile directives: segment declarations and section mapping directives. The directives can span across lines and are terminated by a semicolon.

The following syntax conventions are used to describe the directives:

  • [...]* means zero or more.

  • [...]+ means one or more.

  • [...] means optional.

  • The section_names and segment_names are the same as a C identifier except that a period (.) is treated as a letter.

  • A number can be hexadecimal, following the same syntax as the C language.

  • The section, segment, file, and symbol names are case-sensitive.

  • A string of characters following # and ending at a new-line is considered a comment.

Defining Mapfile Segment Declarations

A segment declaration can create a new segment with a set of attributes or change the attributes of an existing segment.

	segment_name = {segment_attribute_value}* ;
	

The segment attributes and their valid values are as follows:

Attribute Value

segment_type

LOAD (default), HP_TLS, NOTE, NONSEGMENT

segment_flags

?[R][W][X][l][m][c][g][o]]

virtual_address

Vnumber

physical_address

Pnumber

alignment

Anumber

  • NOTE segments cannot be assigned any segment attribute other than a segment_type.

  • If you do not specify virtual_address, physical_address and alignment, the linker calculates these values as it builds the executable. If you specify both a virtual_address and an alignment for a segment, the virtual_address value takes priority.

  • An alignment value greater than the file system block size (4K) also specifies the page size. In that case, the value of the alignment is also the size of the page. The operating system uses the largest page size available that is not greater than the value of the alignment when mapping a segment.

  • The segment_type NONSEGMENT describes sections placed at the end of the executable file. The linker does not create a program header entry for this segment.


Segment Flags

Segment declarations support the following segment flags:

Flag Action

R

Readable

W

Writable

X

Executable

The default segment_flags for a LOADable segment is ?RWX.

Segment declarations support the following special flags:

Flag Action

l

Enables lazy swap allocation for a segment. This flag is not set by default. The lazy swap is disabled by default.

m

Sets the "modification" hint for a segment. When this flag is set, it indicates that the program expects to modify the pages in the segment. If not set, the program does not expect to modify any pages in the segment, even though it may have permission to do so. This flag is not set by default. The modification hint is off by default.

c

Sets the "code" hint for a segment. When this flag is set, it indicates that the segment mostly contains code that may be executed. When not set, it indicates that it is unlikely that the segment contains code. This flag is not set by default. The code hint is off by default.

g

Groups segments together. A segment declared with g flag is grouped with a segment preceding it in the mapfile. Any number of segments can be grouped together. The grouping affects the way in which addresses are assigned to segments. The segments in one group are assigned consecutive virtual addresses.

o

Tells the linker that all the segment attributes declared for this segment can be changed or modified to achieve space and/or time optimization. When this flag is set, the linker considers all other segment attribute specifications (for this segment) as hints and change or modify them as it thinks fit for space and/or time optimization.


Mapfile Segment Declaration Examples
  • The following example declares a segment with segment_type LOAD and segment_flags readable and executable.

    text = LOAD ?RX;

  • The following example declares a LOADable segment (default) with segment_flags readable and writable. The virtual_address and alignment values are set to V0x80000000 and A0x1000 respectively.

    mydata = ?RW V0x80000000 A0x1000;

Defining Mapfile Section Mapping Directives

A section mapping directive specifies how the linker must map the input section onto output segments. This directive tells the linker what attributes of a section must be matched in order to map that section into the named segment. The set of attribute values that a section must have to map into a specific segment is called the entrance criteria.

	segment_name : {section_attribute_value}*
	;
	

The section attributes and their valid values are as follows:

Section Attribute Value

section_name

Any valid section name

section_type

$PROGBITS, $NOBITS, $UNWIND, $NOTE, $REL, $RELA

section_flags

?[[!]A][[!]W][[!]X][[!][S]][[!][T]]

Flag Value

A

Allocatable (takes up virtual memory)

W

Writable

X

Executable

S

Short data

T

TLS (thread local storage)

  • At most one section_type can be specified in a mapping directive.

  • If a section flag is preceded by an exclamation mark (!), it indicates that the flag must not be set to meet the entrance criteria.

    If you do not specify section_flags, the flag can have any value to meet the entrance criteria.

    S1 : ?X;

    The linker maps all executable sections onto segment S1.

  • The section_name attribute indicates that the linker must map the input sections with the specified name onto the named segment.

    text : .rodata;

  • An input section can satisfy more than one entrance criterion.

    S1 : $PROGBITS;

    S2 : $PROGBITS;

    In this case, all sections with section type $PROGBITS are mapped onto segment S1 as the first rule takes precedence.

  • An AND relationship exists between attributes specified on the same line. An OR relationship exists between attributes specified for the same segment that span more than one line.

    • Example 1:

      All sections with section_type $PROGBITS and section_flags AX (allocatable and executable) are mapped onto the text segment.

      text : $PROGBITS ?AX;

    • Example 2:

      text : $PROGBITS ?AX;

      text : .rodata;

      In this case, the linker maps a section onto the text segment if:

      Its section_type is $PROGBITS and section_flags is AX.

      (or)

      Its section_name is .rodata.

Internal Map Structure

The linker use a default map structure corresponding to the default mapfile. When you use the mapfile option with the ld command, the linker appends the default mapfile to the end of your user-specified mapfile. (You can override the default mapfile by using the +nodefaultmap option.)


Placement of Segments in an Executable

As it processes each segment declaration in the mapfile, the linker compares it with the existing list of segment declarations as follows:

  • If the segment does not exist already, but another with the same segment_type exists, the linker adds the segment after all of the existing segments with the same segment_type.

  • If no segment with the same segment_type exists, the linker adds the new segment to the list to maintain the following order based on segment_type:

    • LOAD

    • HP_TLS

    • NOTE

    • NONSEGMENT

  • If segments of same type already exists, the linker adds the new segment after the last segment with the same type.


Mapping Input Sections to Segments

As each section mapping directive in a mapfile is read in, the linker creates a new entrance criteria and appends it to the existing list of entrance criteria. It applies the entrance criteria in the order in which they are specified in the mapfile. The linker maps out the input sections in the same order as their matching entrance criteria.

Figure 31: Map Structure

Figure 31:Map Structure shows the map structure. The entrance criteria boxes correspond to the information from the section mapping directives and the segment attribute descriptors correspond to the information from the segment declarations. The output section descriptors boxes group the sections that fall under each segment based on their section attributes. The linker associates each entrance criteria with a list of "output section descriptors". In Figure 31:Map Structure , the entrance criteria are labeled with numbers to illustrate their associated output section descriptors.

The linker performs the following steps when mapping sections to segments:

  1. When a section is read in, the linker checks the list of entrance criteria looking for a match. All specified criteria must be matched. When an entrance criteria matches, the linker traverses its associated "output section descriptor" list.

  2. If the section attribute values match those of an existing output section descriptor exactly, the linker places the section at the end of the list of sections associated with that output section descriptor.

  3. If no matching output section descriptor is found, but output section descriptors of the same section_type exists, the linker creates a new output section descriptor with the same attribute values as the section and adds that section to the new output section descriptor. It places the new output section descriptor after the last output section descriptor with the same section type.

  4. If no other output section descriptor of the indicated section_type exists, the linker creates a new output section descriptor and associates the section with the new output section descriptor. It places the new output section descriptor after the last output section descriptor associated with that entrance criteria.

  5. If no entrance criteria match is found, the linker places the section at the end of the "nonsegment". It does not create a program header entry for the nonsegment.

The following rules apply when the linker adds a new output section descriptor to a list of output section descriptors associated with an entrance criteria:

  • If an entrance criteria selects both $PROGBITS and $NOBITS sections, the linker enforces an order such that the $PROGBITS sections precede $NOBITS sections.

  • If an entrance criteria selects both S (short data) and !S (non-short data) sections, the layout of the sections depends on section_type and S flag status. The linker maintains the following order:

    $PROGBITS and !S

    $PROGBITS and S

    $NOBITS and S

    $NOBITS and !S

  • The linker always tries to group all $NOBITS sections at the end of the data segment. If it does not place a $NOBITS section at the end of the data segment because of user-specified mapping directives, the linker converts that section to a $PROGBITS section and zero-fills the section contents. The linker issues a warning message when it converts a $NOBITS section into a $PROGBITS section.


Interaction between User-defined and Default Mapfile Directives

The linker adds the section mapping directives from the default mapfile after the user-specified mapping directives. The following rules apply if the you declare a built-in segment (a segment defined in the default mapfile):

  • If the segment_type and "segment_flags" differ from the default mapfile declarations, the linker issues a warning and uses the user-specified segment_type and/or segment_flags for that segment.

  • If your segment declaration does not specify a segment_attribute_value, the linker takes it from the default mapfile's segment declaration.

  • The linker completely ignores the default mapfile if you use the option +nodefaultmap on the ld command line.

Mapfile Option Error Messages


Fatal Errors

The following conditions can result in a fatal error:

  • Specifying more than one -k option at the command line

  • Mapfile cannot be opened or read

  • The linker finds a syntax error in the mapfile

  • More than one segment_type, segment_flags, virtual_address, physical_address or alignment value appears on a single declaration line

  • More than one section_name, section_type, or section_flags value appears on a single directive line

  • A user-defined virtual address causes a segment to overlap the previous segment


Warnings

The following conditions can produce a warning message:

  • A physical_address or a virtual_address value is specified for any segment other than a LOADable segment. The directive is ignored.

  • A second declaration for the same segment changes an attribute value. The second declaration overrides the original.

  • An attribute value for a built-in segment is changed.