I am using IAR linker and I need to define exported symbols of start/end address of my defined blocks in linker file:
Example:
I defined my block like this:
define block AppFlash with fixed order, alignment = 32
{
block App_1,
block App_2,
block App_3,
};
And now I need to get the start address of the blocks, by using __section_begin("App_1"), etc.
The problem that I have is that I only am able to retrieve this info at runtime, but not at startup, and I have assembler files that need some start address references of the linker for vector table configuring...
Explanation:
C code Files:
result = __section_begin("App_1") -> Runs fine, info retrieved is the expected
Assembler files:
EXTERN MAINSTACK_START -->> I cant make a define with the __Section_begin function in the same way
Is there any way to define a exported symbol with the start address of a block in IAR linker file?
I know it's possible with regions, but I dont know how to do this with blocks.
In assembler you can use the operators SFB, SFE, and SIZEOF to get the start, end, and length of a block. They are used as in the example below. Note that the block you want to find must be declared before the operators are used.
;; Forward declaration of section App_1
SECTION App_1:DATA:NOALLOC:NOROOT(0)
PUBLIC begin, beginsym
PUBLIC end, endsym
PUBLIC size, sizesym
SECTION `.text`:CODE:NOROOT(2)
THUMB
begin: LDR R0, =SFB(App_1)
BX LR
end: LDR R0, =SFE(App_1)
BX LR
size: LDR R0, =SIZEOF(App_1)
BX LR
SECTION `.data`:DATA:NOROOT(2)
DATA
beginsym:
DC32 SFB(App_1)
endsym:
DC32 SFE(App_1)
sizesym:
DC32 SIZEOF(App_1)
END
Related
I am in a situation in an embedded system (an xtensa processor) where I need to manually override a symbol, but the symbol happens to be in the middle of another symbol. When I try using -Wl,--wrap=symbol it won't work, since the symbol isn't its own thing.
What I need to do is specify (preferably in a GCC .S, though .c is okay) where the code will end up. Though the actual symbol will be located somewhere random by the compiler, I will be memcpying the code into the correct place.
40101388 <replacement_user_vect>:
40101388: 13d100 wsr.excsave1 a0
4010138b: 002020 esync
4010138e: 011fc5 call0 4010258c <_UserExceptionVector_1>
My problem is GCC creates the assembly with relative jumps assuming the code will be located where it is in flash, while the eventual location will be fixed in an interrupt vector. How do I tell GCC / GNU as "put the code wherever you feel like, but, trust me it will actually execute from {here}"
Though my code is at 0x40101388 (GCC decided) it will eventually reside and execute from 0x40100050. How do I trick GCC by telling it "put the code HERE" but pretend it's located "HERE"
EDIT: I was able to get around this, as it turns out, the function I needed to modify was held in the linker script, individually. I was able to just switch it out in the linker script. Though I still would love to know the answer, I now have a work-around.
In the linker script each output section has two associated addresses: VMA and LMA -- the address for which the code is linked and the address where the code will be loaded.
Put the code that needs to be relocated into separate section, add an output section to your linker script with desired VMA and LMA and put an input section matching the name of the code section inside it.
E.g. the following C code
void f(void) __attribute__((section(".relocatable1.text")))
{
...
}
extern char _relocatable1_lma[];
extern char _relocatable1_vma_start[];
extern char _relocatable1_vma_end[];
void relocatable1_copy(void)
{
memcpy(_relocatable1_vma_start, _relocatable1_lma,
_relocatable1_vma_end - _relocatable1_vma_start);
}
Together with the following piece of ld script, with VMA substituted with the desired target code location
SECTIONS {
...
.some_section : { ... }
.relocatable1 VMA : AT(LOADADDR(.some_section) + SIZEOF(.some_section)) {
_relocatable1_vma_start = . ;
*(.relocatable1.literal .relocatable1.text) ;
_relocatable1_vma_end = . ;
}
_relocatable1_lma = LOADADDR(.relocatable1) ;
...
}
should do what you want.
I am using LPC1788 micro-controller with Keil4, when i create a project Keil adds a file called "startup_LPC177x_8x.s". In this file at one stage a IMPORT command is trying to import SystemInit, but when i compile, i get an error as follow:
compiling main.c...
main.c(6): warning: #1-D: last line of file ends without a newline
linking...
project_1.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_lpc177x_8x.o).
Target not created
the piece of code is as follow:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
I have included the header file "lpc177x_8x.h" in my project.
Please guide me friends ...i am new to Keil...thanks a lot.
It is an IMPORT symbol in this file - that is it defined elsewhere.
It will probably be in a file named system_LPC177x_8x.c or similar; it may need customisation for your project to set the PLL and initialise external memory interfaces, and other clock dependent features.
It is normally included in your project automatically if you ask for start-up files to be included when you create the project; otherwise it will be in the CMSIS target specific support folder in the Keil ARM-MDK installation, in this case I would guess: CMSIS\CM3\DeviceSupport\NXP\LPC17xx\ or similar, the exact directory structure has changed between CMSIS versions.
depends on where you installed Keil.
here is the address in my computer:
D:\Program Files\keil\ARM\INC\NXP\LPC17xx
(here contains the header files you use)
D:\Program Files\keil\ARM\Startup\NXP\LPC17xx
(here contains startup files you use, the SystemInit function is defined here in the system_LPC13xx.c)
Is there a way to prohibit the use of global variables?
I want GCC to generate an error on compile time when a global variable is defined.
We have a code that should be run per thread and want to allow only use of stack (which is thread safe)
Is there way to enforce it ?
Some GCC flag or other way to verify it ?
One approach would be to generate a linker map file (e.g. pass option -Wl,-Map,program.map to gcc), and examine the .data and .bss output sections for any contributions from the object files that you want to run without globals.
For instance, if my source file hello.c has:
static int gTable[100];
the linker map file will have something like this in it:
.bss 0x0000000000600940 0x1b0
*(.dynbss)
.dynbss 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
*(.bss .bss.* .gnu.linkonce.b.*)
.bss 0x0000000000600940 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o
.bss 0x0000000000600940 0x0 /usr/lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o
.bss 0x0000000000600940 0x1 /usr/lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o
*fill* 0x0000000000600941 0x1f 00
.bss 0x0000000000600960 0x190 hello.o
You can see that hello.o is contributing 0x190 (400) bytes to the .bss section. I've used the approach of parsing a link map file with a Python script to generate code size and RAM usage metrics for an embedded project with reasonable success in the past; the text output format from the linker is pretty stable.
No such functionality in gcc. Some workaround would be to incorporate in the build process a static analysis tool which can detect globals. Still the compilation would not fail, but at least you would be warned in some way. I can see that PC-Lint (www.gimpel.com) has a check for
non const non volatile global variables, locating these can assist multi-threaded applications in detecting non re-entrant situations
Probably other tools may include similar functionality.
I would use ctags to extract the symbols from the source code and then search the output with a (perl or python) script for global variables.
E.g. following line would tell you whether a C soucre file hello.c contains global variables:
ctags -f- hello.c | perl -ne"#a=split(/\t/, $_); if ($a[3] eq qq(v)){ print qq(Has global variables.); exit 0; }"
I am facing a trivial prblem.
I am doing an ldr r0, _buff
in arm assembly, where _buff is defined in a c file. _buff is not static.
How should I define external linkage in assembly file (similar to extern in C)
is it required or is there anything which I am missing.
You don't need to. If the symbol can't be found in the source file, it'll be assumed to be defined elsewhere.
It's not necessary to do that. If *_buff* has been defined as global in the C file, you can compile and build the files together:
arm-none-gnuaebi-gcc -o output assembly.s cfile.c
You can also compile them separately, it's also going to work. But _buff does not exist, you will get a link error.
I'm working on a toy operating system and bootloader. I'm trying to write the kernel in C, and then convert it to binary for direct jumping to from the bootloader (i.e., I'm not loading an ELF or anything like that).
I've got the linker file setup with the proper origin (I'm loading the kernel to address 0xC0000000) and confirm with objdump that it's using it correctly. However, it's not placing my entry point at the start (0xC0000000) like I wanted. I guess that's not what the ENTRY directive is for.
My problem is simply that I want to place a particular function, kernel_main at address 0xC0000000. Is there a way I can accomplish this using gcc for compiling and linking?
Here is what the relevant parts of my linker file look like:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
*(.text)
}
/* etc. */
}
The ENTRY linker command tells the linker which symbol the loader should jump to when it loads the program. If you're making your own operating system it's really not used since there is no loader.
Instead, as you know, the program simply starts at the first code address.
To make place a special segment of code first, you could place it in a special code segment, and put it first in the list:
.text BLOCK(4K) : ALIGN(4K)
{
*(.text.boot) *(.text)
}
The segments in the list is placed in the order they are given.
The ENTRY directive is only useful for output formats that support an entrypoint. Since you're using a binary output, this won't work. What you can do is write a small stub in a separate source file (i.e. entry.c or entry.asm or whatever). Then, in the ld script, before the *(.text) line, you can put entry.o(.text). This instructs ld to load the symbols from a specific object file (whereas * denotes all object files). So the new ld script would look like this:
ENTRY(kernel_main)
SECTIONS
{
/* Origin */
. = 0xC0000000;
.text BLOCK(4K) : ALIGN(4K)
{
entry.o(.text)
*(.text)
}
/* etc. */
}
As long as entry.o contains just one function (that simply calls your kernel main), this should work.