This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Run an image with static library objects placed in a specific execution region

Hi all,

First I want to deliver some background information to the given problem: I'm developing a firmware on a SoC with a cortex-M0 (with Arm Compiler for Embedded 6.21) for a metering device with legally relevant software parts. This means, that after certification a change in the legally part of the firmware is not allowed without re-certification. My idea is, to compile the legally relevant code separately and pack the objects into a static library. This code contains only functions which modify data in a fixed positioned data structure in RAM.

At link time, I want to place all those objects from the library in a specific execution region with use of a scatter file. So far so good, up to this step everything was possible to do for me.

My compiler flags to build the library object user_function.o (it contains only one function: add_num) are:

Fullscreen
1
-xc -mcpu=cortex-m0 --target=arm-arm-none-eabi -std=c99 -c -fno-rtti -funsigned-char -fshort-enums -fshort-wchar -mlittle-endian -gdwarf-4 -O0 -fbare-metal-pie
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

After this step, I create an archive with armar:

Fullscreen
1
armar --create libMetering_1.0.0.a user_function.o
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

My compiler flags to build the main firmware objects are:

Fullscreen
1
-xc -mcpu=cortex-m0 --target=arm-arm-none-eabi -std=c99 -c -fno-rtti -funsigned-char -fshort-enums -fshort-wchar -mlittle-endian -gdwarf-4 -O0 -fno-function-sections
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The linker flags to link the whole image are:

Fullscreen
1
--cpu=cortex-m0 --library_type=microlib --strict --scatter "${CMAKE_SOURCE_DIR}/linker/myScatter.sct" --pad=0xFF --remove --summary_stderr --info summarysizes --bestdebug --map --load_addr_map_info --xref --callgraph --symbols --info=sizes --info=totals --info=unused --info=veneers --verbose
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

My scatter file looks like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
LR_IROM1 0x00000000 0x00040000 { ; load region size_region
ER_IROM1 0x00000000 0x0001E204 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
.ANY (+XO)
}
ER_IROM2 0x0001E204 0x000205FC {
*libMetering*.a(+RO) ; place all RO code objets from libMeter here
}
RW_IRAM1 0x20000480 0x00000C00 { ; place meter struct (meter_t) here
*(meter_rc)
}
RW_IRAM2 0x20001080 0x00004F80 {
.ANY (+RW +ZI)
}
RW_IRAM3 0x20006000 0x00001000 { ; NVRAM, will be powered from supercap during
*(nv_ram) ; powerloss
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

This ends up in an image like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Memory Map of the image
Image Entry point : 0x000000c1
Load Region LR_IROM1 (Base: 0x00000000, Size: 0x00000e78, Max: 0x00040000, ABSOLUTE)
Execution Region ER_IROM1 (Exec base: 0x00000000, Load base: 0x00000000, Size: 0x00000e60, Max: 0x0001e204, ABSOLUTE)
Exec Addr Load Addr Size Type Attr Idx E Section Name Object
0x00000000 0x00000000 0x000000c0 Data RO 3 RESET startup_dev_Keil.o
0x000000c0 0x000000c0 0x00000000 Code RO 62 * .ARM.Collect$$$$00000000 mc_p.l(entry.o)
0x000000c0 0x000000c0 0x00000004 Code RO 69 .ARM.Collect$$$$00000001 mc_p.l(entry2.o)
0x000000c4 0x000000c4 0x00000004 Code RO 72 .ARM.Collect$$$$00000004 mc_p.l(entry5.o)
0x000000c8 0x000000c8 0x00000000 Code RO 74 .ARM.Collect$$$$00000008 mc_p.l(entry7b.o)
0x000000c8 0x000000c8 0x00000000 Code RO 76 .ARM.Collect$$$$0000000A mc_p.l(entry8b.o)
0x000000c8 0x000000c8 0x00000008 Code RO 77 .ARM.Collect$$$$0000000B mc_p.l(entry9a.o)
0x000000d0 0x000000d0 0x00000000 Code RO 79 .ARM.Collect$$$$0000000D mc_p.l(entry10a.o)
0x000000d0 0x000000d0 0x00000000 Code RO 81 .ARM.Collect$$$$0000000F mc_p.l(entry11a.o)
0x000000d0 0x000000d0 0x00000004 Code RO 70 .ARM.Collect$$$$00002712 mc_p.l(entry2.o)
0x000000d4 0x000000d4 0x00000078 Code RO 4 .text startup_dev_Keil.o
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

As I said before, this is the result I wanted to achieve. My user_function.o is placed at 0x0001e204. But, if I debug the firmware in gdb, the program runs until my function "add_num" in user_function.o. After that, the program crashes. If I have a look on the disassembly output, it shows:

Fullscreen
1
2
3
4
5
─── Assembly ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
0x0001e204 add_num+0 @ <UNDEFINED> instruction: 0xffffffff
0x0001e208 add_num+4 @ <UNDEFINED> instruction: 0xffffffff
0x0001e20c add_num+8 @ <UNDEFINED> instruction: 0xffffffff
0x0001e210 add_num+12 @ <UNDEFINED> instruction: 0xffffffff
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The output with fromelf -c of user_function.o looks like this:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
========================================================================
** Section #1 '.strtab' (SHT_STRTAB)
Size : 187 bytes
** Section #2 '.text' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
Size : 0 bytes (alignment 4)
Address: 0x00000000
** Section #3 '.text.add_num' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
Size : 16 bytes (alignment 2)
Address: 0x00000000
[Anonymous symbol #2]
$t.0
add_num
0x00000000: b082 .. SUB sp,sp,#8
0x00000002: 9001 .. STR r0,[sp,#4]
0x00000004: 9100 .. STR r1,[sp,#0]
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

What am I missing here? My first guess was, that I have to compile location independent code for the lib objects, therefore I added "-fbare-metal-pie". Without success.

I would be very happy about any advice

Thanks in advance

0