This chapter describes with examples how to use the mapfile option.
NoteIn 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:
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.
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.
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.
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.
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.
|
|