Linkerscope
Create memory map diagrams directly from linker map files
Install / Use
/learn @raulgotor/LinkerscopeREADME
LinkerScope
Project summary
LinkerScope is a memory map diagram generator. It can be fed either with a GNU Linker map file or with a custom yaml file
and generate beautiful and detailed diagrams of the different areas and sections such as the one below.
Installing LinkerScope
Optionally create and activate an environment for LinkerScope:
python3 -m venv venv
source env/bin/activate
Install the needed requirements by executing:
pip3 install -r requirements.txt
Usage
Execution
LinkerScope needs a file with memory information for basic functionality:
that could be either GNU Linker map files (.map) or custom structured YAML file (.yaml).
./linkerscope.py linker.map [<options>]
This will output memory map diagram to a default map.svg file.
While this enables a quick generation of memory map, one might want to carefully tune the
different properties of the diagram such as visual and style properties, memory regions, names, links, ...
For that, a configuration file with the desired characteristics has to be specified:
./linkerscope.py linker.map --config config.yaml --output map.svg
where:
- First parameter specifies the path to the input file, where LinkerScope should get the data to represent from. It can come from a GNU Linker map file
.mapor from an already parsed or hand-crafted.yamlfile. Check [Manually crafting input file](#Manually crafting input file) section for learning how to do this. -c, --config[OPTIONAL] specifies the path to the configuration file. This file contains all the custom information to tell LinkerScope what to and how to draw the memory maps. While it is optional, the default parameters will most likely not apply to a given use case.-o, --output[OPTIONAL] specifies the path to the output file, which will be a newly generated SVG.--convert[OPTIONAL] tells LinkerScope to perform a conversion from a.mapfile to.yamlfile containing memory information. After conversion, proqram will quit.
Input files
LinkerScope can use two types of input files: GNU linker map files (.map) or custom defined yaml files (.yaml).
Using .map files
Under the hood, LinkerScope will convert .map files to custom .yaml ones, and will work from there.
Since this operation is time-consuming and makes no sense to do it multiple times, two strategies can be
performed when using .map files:
- Convert
.mapfiles to.yamlfile and then use the.yamlfile as an input to LinkerScopeThis is specially useful if you plan to execute LinkerScope multiple times, since this conversion is time-consuming. Therefore better doing the conversion step once, right? Execute the example below:
# Conversion step ./linkerscope.py examples/sample_map.map --convert # Map diagram generation. You can execute multiple times without having to do the conversion again ./linkerscope.py map.yaml -c examples/sample_config.yaml -o sample_map.svg - Directly use the
.mapfiles to output a memory map diagram.Use this strategy when you already have a configuration file, and you know that LinkerScope will produce the expected result. Execute the example below:
./linkerscope.py examples/sample_map.map -c examples/sample_config.yaml -o sample_map.svg
Manually crafted memory map files
Custom memory map files can be manually crafted and can run from a couple of memory sections up to very complex memory schemes with hundreds of sections. Normally you would do that when representing simple memory maps.
For making a memory map file, one has to specify at least a single section. Each section must include
an id, an address and a size.
While these three are needed, there are other possible attributes that are optional:
name: Friendly text name that would be used instead of theidtype: Section type, which can be used for different purposes. Current possibilities aresection(default) andarea.
The input file should contain the map keyword whose value is an array of sections. Below an example
of how an input file should look like:
- address: 0x80045D4
size: 0x0000F00
id: .rodata
name: Read Only Data
type: area
- address: 0x8002C3C
id: SysTick_Handler
size: 0x0000008
- ...
In order to use this file, invoke LinkerScope and specify the yaml map file as input:
./linkerscope.py memory_map.yaml -o memory_map.svg -c config.yaml
Creating a configuration file
The configuration file is a .yaml file containing all the required information to tell
LinkerScope what and how to draw the memory map. All information there is optional, including the
file itself. If this information is not provided, the default values will be used.
Normally, a configuration file contains areas, links and style information.
Areas provides a list of memory areas to be displayed, with information regarding its position and size on the map, memory range to include or specific drawing style. Additionally, it can contain a sections sub-property where specific sections can be added to modify desired properties
Links provides a simple way of graphically relating same memory addresses across different areas
Style defines the parent drawing style properties that will be used at the document. Additionally, each area can override specific style properties at its style section. Lastly, sections can override parent (area) style as well
style:
background: '#99B898'
stroke: 'black'
# ...
areas:
- area:
style:
# ...
title: Register Map
range: [0x0, 0x100000000]
sections:
- names: [USART1, USART2]
style:
hide-name: true
# ...
- area:
# ...
links:
addresses: [0x80045d4]
sections: [__malloc_av_, [TIM2, TIM3]]
Areas
The diagram can have one or multiple areas. When multiple areas are declared,
first area has a special status since all links will start on it and go to the corresponding sections on the other areas
The areas are declared at root level under areas. Then each area must use the key area.
Areas can be placed at any position in the document, and some of its properties can be tuned.elements such as labels, memory addresses,
For instance, some elements such as the name / id, size, address, can be show or hidden, labels at
specific memory regions can be configured, sections can be marked as break sections, and the
visual style of the area and its sections can be modified independently from the others.
For each area, the following characteristics of an area can be defined:
title: [Optional, none]- The title of the area, which will appear on top of it
pos: [Optional, (50, 50)] [x, y]- absolute position of the area's top-left corner in pixels
size: [Optional, (300, 600)] [width, height]- area size in pixels
range: [Optional, (0, no limit)] [min, max]- range of addresses that will be taken into account in this area.
start: [start, end] force area to start in to a given addresssection-size: [Optional, (0, no limit)] [min, max]- size range of the sections that should be shown. Exclude others.
style: [Optional, default: parent style]- specific style for current area. See Styles section.
sections: [Optional, none]- specify or modify a section or group of sections property such as
style,flags,...names:- list of one or more sections to modify with the parameters below
flags: [Optional, none]- flags to append to the specified section/s. See [Flags](#### Section flags) section.
style: [Optional, parent style]- style properties to or modify to the specified section/s
- specify or modify a section or group of sections property such as
labels: [Optional, none]- Add text labels to specific memory positions of the current area
address:- Memory address where the label should be placed
text:- Text to display for this label
length: [Optional, none]- length of the label line in pixels
directions: [Optional, none]- direction or list of directions for the arrow head. Possible values are none,
in,outor both.
- direction or list of directions for the arrow head. Possible values are none,
side: [Optional,right]- Area side at which the label should be placed
style: [Optional, parent style]- style properties to or modify to the specified section/s
- Add text labels to specific memory positions of the current area
Below an example of area definition:
areas:
- area:
title: 'Full Memory Map'
pos: [30, 50]
size: [300, 900]
range: [0x0, 0x100000000]
section-size: [0x02F00000]
style:
fill: *pastel_green
sections:
- names: [ External Device ]
flags: grows-up
style:
hide-size: true
Labels
Labels can bind a text string with a specific memory position. This property falls inside area.
An extract from the labels example can be found below:
areas:
- area:
labels:
- address: 0xe8043800
text: In direction
length: 150
directions: in
style:
stroke-dasharray: '5,1,3,1,3'
# ...
The example can be executed at the root folder by running:
./linkerscope.py examples/labels_map.yaml -c examples/labels_config.yaml
Section flags
Section flags allows flagging specified sections with special properties.
These properties are hidden, break, grows-up and grows-down.
Flags are listed under property flags and can be specified both at the map files under eac
