Memory map and linker¶
Purpose¶
- To get familiar with memory layout in compilation process
- To learn how to use linker
Requirements¶
The following hardware and tools are required:
- PC host
- ARC GNU toolchain/MetaWare Development Toolkit
- nSIM simulator
embarc_osp/arc_labs/labs/lab8_linker
Content¶
- Customizing your program with compiler pragmas.
- Using “pragma code” to specify a new name of section in which the code of function reside.
- Mapping this code section into specified memory location with linker.
- Checking the location of this code section after build process.
Principles¶
By default, compiler-generated code is placed in the .text section. The default code section name can be overridden by using the code pragma. After compilation process, the linker automatically maps all input sections from object files to output sections in executable files. If you want to customize the mapping, you can change the default linker mapping by invoking a linker command file.
Steps¶
Create a project and overriding code section name¶
Open MetaWare IDE, create an empty C project called lab_linker and select ARC EM series processor. Import the main.c and link.cmd files from the embarc_osp/arc_labs/labs/lab8_linker directory into the project.
Open main.c file in MetaWare IDE, use “pragma code” to change the section in which function modify
reside from .text to a new name “modify_seg”.
#pragma Code ("modify_seg")
void modify(int list[], int size) {
int out, in, temp;
for(out=0; out<size; out++)
for(in=out+1; in<size; in++)
if(list[out] > list[in]) {
temp = list[in];
list[in] = list[out];
list[out] = temp;
}
}
#pragma Code ()
Pragma code has two forms that must be used in pairs to bracket the affected function definitions:
#pragma code(Section_name)
/* ----- Affected function definitions go here ---- */
#pragma code() /* No parameters here */
Section_name is a constant string expression that denotes the name of the section.
Note
About detailed usage of the compiler pragmas, see MetaWare C/C++ Programmer’s Guide for the ccac Compiler.
Edit the linker command file¶
Open link.cmd file, there are two parts, one is for memory blocks location, the other is for sections mapping. Add one new block named “MyBlock” in MEMORY, the start address is 0x00002000, and the size is 32KB. Add one new GROUP in SECTIONS, and mapping section “modify_seg” into MyBlock.
MEMORY {
// Note: overlap of code and data spaces is not recommended since it makes
// Address validity checking impossible with the debugger and simulator
MyBlock: ORIGIN = 0x00002000, LENGTH = 32K
MEMORY_BLOCK1: ORIGIN = 0x0010000, LENGTH = 64K
MEMORY_BLOCK2: ORIGIN = 0x0020000, LENGTH = 128K
}
SECTIONS {
GROUP: {
modify_seg: {}
}>MyBlock
......
Note
About format and syntax of the linker command file, see MetaWare ELF Linker and Utilities User’s Guide.
Add the linker command file into the project¶
Right-click the current project lab_linker and select Properties. Click C/C++ build > Settings > Tool Settings to open the linker option settings page.
Select Command files to add linker.cmd file into this project.
Check the result¶
In the linker option settings window, select Map listing to check Generate listing file(=.map)
Build the lab_linker project, then open the lab_linker.map file.
Search SECTIONS SUMMARY, then you can check the size and location of modify_seg section, it resides in MyBlock, similar to you setting in the linker command file.
Exercises¶
Check the memory mapping info of modify_seg section by using elfdump tool.