5. Linker Map Files
A map file provides detailed information about the link and helps analyze output images, debug build issues, and better understand linker decisions. It contains detailed information for input files, linker scripts, memory regions, image memory layout, and so much more. Effectively using map files can significantly reduce the time spent analyzing and debugging builds.
Use -Map
to generate map files for your builds.
5.1. Map File Styles
Map files are available in three distinct styles:
Text
YAML
Binary
Use option -MapStyle
to specify the map file style. Text map file
is the default map style.
5.2. Navigating Text Map File
5.2.1. Map file contents
Section |
Description |
---|---|
Tools Version, and System and Link features |
Information about tools version, and system and link features. |
Link Stats |
Quick overview of key link information |
Archive Member Information |
Specifies which archive members were included and why. |
Allocating Common Symbols |
Lists the common symbols which got allocated |
Linker Script and Memory Map |
Specifies input object files |
Build statistics |
|
Linker scripts used |
Specifies the linker scripts used by the link. |
Linker plugin information |
Details plugin information. |
Output Section and Layout |
Delineates output image layout |
Let’s explore each of these sections in detail!
5.2.2. Tools Version, and System and Link Features
As the title suggests, this consists information about tools version, and system and link features. An example of this section is shown below:
# Linker from QuIC LLVM Hexagon Clang version Version 19.0-alpha2 Engineering Release: hexagon-clang-190-229
# Linker based on LLVM version: 19.0
# Linker: d8a255719548f774e7e73cd97959ca04fd780b54
# LLVM: 9ab18b8e7547380db4fb83b2ada1d7704876b334
# Notable linker command/script options:
# CPU Architecture Version:
# Target triple environment for the link: unknown
# Maximum GP size: 8
# Link type: Static
# ABI Page Size: 0x1000
# CommandLine : hexagon-link -o main.elf main.o libs/libfoo.a libs/libbar.a -Map main.map.txt
5.2.3. Link Stats
‘Link Stats’ provides a quick overview of key link information. Link stats are not displayed if their value is 0.
An example of ‘Link Stats’ is shown below:
# LinkStats Begin
# ObjectFiles : 2
# LinkerScripts : 2
# ThreadCount : 64
# NumInputSections : 37
# ZeroSizedSections : 28
# Total Symbols: 6 { Global: 3, Local: 2, Weak: 0, Absolute: 3, Hidden: 1, Protected: 0 }
# Discarded Symbols: 1 { Global: 1, Local: 0, Weak: 0, Absolute: 0, Hidden: 1, Protected: 0 }
# NumLinkerScriptRules : 2
# NumOutputSections : 7
# NumOrphans : 5
# NoRuleMatches : 3
# NumSegments : 1
# OutputFileSize : 4920 bytes
# LinkStats End
There might be more or less link stats than what is shown here depending on your tools version. Remember that only non-zero stats are displayed.
5.2.4. Archive Member Information
‘Archive Member Information’ tells which archive members were included in the link and due to which symbol. Archive members are only included in the link if they satisfy an undefined symbol reference. The format of each entry of ‘Archive Member Information’ is:
<ArchiveFile> (<ArchiveMember>)
<CompilationUnitReferringArchiveMember> (<ReferencedSymbol>)
The below example shows that archive members ‘libs/libfoo.a(Foo.o)’ and ‘libs/libbar.a(Bar.o)’ are included in the link because ‘main.o’ referenced symbols ‘foo’ and ‘bar’ from the archive members.
Archive member included because of file (symbol)
libs/libfoo.a(Foo.o)
main.o (foo)
libs/libbar.a(Bar.o)
main.o (bar)
5.2.5. Allocating Common Symbols
‘Allocating Common Symbols’ list the common symbols that were allocated by the linker. Each entry in the common symbols section contains the following items:
The name of the symbol
The size of the memory area allocated for the symbol
The full pathname of the archive file accessed by the linker
The name of the archived object file that defines the symbol (in parentheses)
In the following example, the __eh_nodes symbol has size of 0x4 and is defined in the the object file: xregister.o
1Common symbol size file
2
3__eh_nodes 0x4 $PATH/../target/hexagon/lib/v65/G0/libc.a(xregister.o)
5.2.6. Linker Script and Memory Map Section
The linker script section of a link map lists the complete linker script that is specified for the link.
Note
Linker scripts are optional. If a script is not specified on the linker command line, the link map does not include a linker script.
The following example shows the initial lines of a linker script section:
1Linker Script and memory map 2LOAD $PATH/../target/hexagon/lib/v65/G0/crt0_standalone.o[hexagonv65] 3LOAD target/main.o[hexagonv65] 4START GROUP 5LOAD $PATH/../target/hexagon/lib/v65/G0/libstandalone.a(_exit.o)[hexagonv65] 6... 7LOAD $PATH/../target/hexagon/lib/v65/G0/libgcc.a(vmemcpy_h.o)[hexagonv65] 8END GROUP 9LOAD $PATH/../target/hexagon/lib/v65/G0/fini.o[hexagonv65]
5.2.7. Linker Scripts Used
‘Linker Scripts Used’ specifies the linker scripts used by the link.
1Linker scripts used (including INCLUDE command) 2target/linker.script
Todo
Add ‘Linker Plugin Information’ section docs!
Todo
Add ‘Build statistics’ section docs!
5.2.8. Output Section and Layout
‘Output Section and Layout’ describes the image layout.
It tells where output sections are placed and what they consist of. It presents
information in an elaborate format loosely based on the linker script
SECTIONS
command. This format allows users to easily visualize and
understand how SECTIONS
subcommands, linker script expressions and
assignment to the location counter affect the output layout.
‘Output Section and Layout’ contains detailed information about output sections, input section descriptions (commonly called rules), input sections, symbols, padding and linker script expressions. It is the most complex part of the map file. Let’s explore its structure to better understand its content.
5.2.8.1. Simplified ‘Output Section and Layout’ Structure
We will first see its simplified structure. Padding and linker script expressions are missing from this simplified structure. As we move forward in the documentation, these missing components will be gradually covered to make the structure complete.
5.2.8.1.1. <OutputSectionAndLayout>
# Output Section and Layout
<OutputSection_1>
<OutputSection_2>
...
<OutputSection_N>
Each <OutputSection> describes one output section. Let’s see what it consists of.
5.2.8.1.2. <OutputSection>
<OutputSection> is represented as:
<OutputSectionName> <size> <VMA> # Offset: <offset>, LMA: <LMA>, Alignment: <alignment>, Flags: <SectionFlags>, Type: <SectionType>, Segments: <segments>
<Rule_1>
<Rule_2>
...
<Rule_N>
<OutputSection> tells output section properties and contains a list of :code:`Rule`s. Placement of rules conveys the placement of the rule contents in the output image layout. The contents of Rule_1 are placed before the contents of Rule_2 and so on. The contents of a rule is the merged content of all the sections that were matched to the rule. Now, let’s see what does <Rule> consist of.
5.2.8.1.3. <Rule>
<Rule> (input section description) is represented as:
<InputSectionDesc> #Rule <RuleNumber>, <InputFile>
<InputSection_1>
<InputSection_2>
...
<InputSection_N>
RuleNumber
makes it easier to refer to a particular input
section description. <Rule> contains a list of <InputSection>
that got matched to this rule.
5.2.8.1.4. <InputSection>
<InputSection> is typically represented as:
<InputSectionName> <VMA> <size> <InputFile> #<SectionType>,<SectionFlags>,<SectionAlignment>
<Symbol_1>
<Symbol_2>
...
<Symbol_N>
However, garbage-collected input sections are prefixed with ‘#’, are
annotated with <GC>
and do not have <VMA>
component.
The <InputSection> for garbage-collected input sections
is represented as:
# <InputSectionName> <GC> <VMA> <InputFile> #<SectionType>,<SectionFlags>,<SectionAlignment>
<Symbol_1>
<Symbol_2>
...
<Symbol_N>
5.2.8.1.5. <Symbol>
<Symbol> is typically represented as:
<VMA> <SymbolName>
However, garbage-collected symbols are prefixed with ‘#’, and do not have
VMA
component. The <Symbol> for garbage-collected symbol is represented
as:
# <SymbolName>
5.2.8.1.6. Example
We have covered the simplified <OutputSectionAndLayout> structure. Now, let’s see a practical example.
Foo.c
int foo() { return 1; }
Bar.c
int bar() { return 3; }
script.t
SECTIONS {
FOO : { *(*foo*) }
BAR : { *(*bar*) }
}
Generate the map-file:
hexagon-clang -o Foo.o Foo.c -c -ffunction-sections
hexagon-clang -o Bar.o Bar.c -c -ffunction-sections
hexagon-link -o FooBar.elf Foo.o Bar.o -T script.t -Map FooBar.map.txt
Output Section and Layout excerpt from the map-file
# Output Section and Layout
FOO 0x0 0xc # Offset: 0x1000, LMA: 0x0, Alignment: 0x10, Flags: SHF_ALLOC|SHF_EXECINSTR, Type: SHT_PROGBITS
*(*foo*) #Rule 1, script.t [1:0]
.text.foo 0x0 0xc Foo.o #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,16
0x0 foo
*(FOO) #Rule 2, Internal-LinkerScript (Implicit rule inserted by Linker) [0:0]
BAR 0x10 0xc # Offset: 0x1010, LMA: 0x10, Alignment: 0x10, Flags: SHF_ALLOC|SHF_EXECINSTR, Type: SHT_PROGBITS
*(*bar*) #Rule 3, script.t [1:0]
.text.bar 0x10 0xc Bar.o #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,16
0x10 bar
*(BAR) #Rule 4, Internal-LinkerScript (Implicit rule inserted by Linker) [0:0]
We can see precisely how output sections are laid in the final layout and
what they are composed of. For instance, the FOO
output section
contains the .text.foo
input section because the .text.foo
matches the rule *(*foo*)
. Under the input section information,
we can also see where each symbol of the section is placed in the output layout.
5.2.8.2. Other <OutputSectionAndLayout> substructures
5.2.8.2.1. <LinkerScriptExpression>
<LinkerScriptExpression> entries are interspersed in <OutputSectionAndLayout>, <OutputSection> and <Rule> and indicates their placement in the linker script. <LinkerScriptExpression> contains the linker script expression annotated with the values.
For example, if the linker script contains:
SECTIONS {
FOO : {
v = . + 0x5;
*(*foo*)
}
}
Then the map-file will contain:
FOO 0x0 0x100c # Offset: 0x1000, LMA: 0x0, Alignment: 0x10, Flags: SHF_ALLOC|SHF_EXECINSTR, Type: SHT_PROGBITS, Segments : [ FOO ]
v(0x5) = .(0x0) + 0x5; # v = . + 0x5; script.t
*(*foo*) #Rule 1, script.t [1:0]
.text.foo 0x0 0xc 1.eld.o #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,16
0x0 foo
Note the v(0x5) = .(0x0) + 0x5;
line under FOO
output section.
5.2.8.2.2. <Padding>
<Padding> describes a padding in the output image layout. Paddings are either requested explicitly by the user or are added automatically by the linker to satisfy alignment constraints. Like <LinkerScriptExpression>, <padding> is also interspersed in <OutputSectionAndLayout>, <OutputSection> and <Rule>. The position of <padding> entry in the map-file conveys the position of padding in the memory layout.
Let’s see an example of explicitly requested padding.
If the linker script contains:
SECTIONS {
FOO : {
. = . + 0x10;
*(*foo*)
}
}
Then the map-file will contain:
# Output Section and Layout
FOO 0x0 0x1c # Offset: 0x1000, LMA: 0x0, Alignment: 0x10, Flags: SHF_ALLOC|SHF_EXECINSTR, Type: SHT_PROGBITS
PADDING 0x0 0x10 0x0
.(0x10) = .(0x0) + 0x10; # . = . + 0x10; script.t
*(*foo*) #Rule 1, script.t [1:0]
.text.foo 0x10 0xc Foo.o #SHT_PROGBITS,SHF_ALLOC|SHF_EXECINSTR,16
0x10 foo
*(FOO) #Rule 2, Internal-LinkerScript (Implicit rule inserted by Linker) [0:0]
Please note the PADDING
details under the FOO
output section.
5.2.8.3. Link map in YAML format
If you use the MapStyle option to specify YAML-style output for the map file, the linker generates a YAML file instead of the text file that shows the memory map for the program.
To derive statistics from the YAML map file produced by the linker, use the YAMLMapParser.py tool and include any of the following options:
–info=architecture – List the architecture
sizes – List the code and data sizes for the objects in the image
summarysizes – List the code and data sizes of the image
totals – List the total size of all objects in the image
unused – List the sections eliminated from the image
unusedsymbols – List the symbols eliminated from the image
–map – Display the memory map of the images
–xref – List the cross references between input sections
list – Redirect the output to a file
The following table describes the sections of a YAML file
Section
Description
Header
Top level information of the program that was built
Version
Information Tools version information
Archive Records
Archive files pulled in by the linker
Inputs
Inputs that were used
InputInfo
Inputs that were used and not used
Linker script used
Linker script file that was used
BuildType
Type of build
OutputFile
Name of the output file
EntryAddress
Entry address for the image built
CommandLine
information on how the linker was called
CommandLineDefaults
Various defaults applied in the linker
OutputSections
All output sections
DiscardedComdats
COMDAT C++ section groups that discarded
DiscardedSections
Sections discarded by garbage collection
DiscardedCommonSymbols
Common symbols that were discarded
LoadRegions
Segments that the program loader will load
CrossReferences
Cross-reference table for the program
5.2.8.4. Link map in Binary format
If you use the
-MapStyle
option to specify “binary” output for the map file, thelinker generates a binary file instead of the text file that contains the memory map.
“-MapStyle binary” can be used along with other map styles as well.
E.g. “-MapStyle txt -MapStyle binary -Map outputfile.map” will produce a text format map
file “outputfile.map” and a binary format “xmap.bin” file.