5

I'm compiling my FreeRTOS application for Cortex-M4 (STM32F4) with following CFLAGS:

-fpic -msingle-pic-base -mpic-data-is-text-relative -mpic-register=r10

and with -fpic flag set for linker.

Vector table is properly copied to RAM with changed offset value for particular firmware slot device is currently starting from.

However, after starting main application from firmware slot, the device hangs in HardFault with IMPRECISERR set in CFSR register. It occurs in vPortSVCHandler when executing follow line:

ldmia r0!, {r4-r11, r14}

After this operation, Link Register value is equal to 0000 0000.

Should I do anything else to properly create position independent application for STM32? Relocate Global Offset Table? If yes, to what place in memory?


EDIT

According to questions below, my goal is to create application with bootloader and 2 firmware slots. I need firmware slots in FLASH so my device will be able to update in runtime. Why I need firmware to be compiled with PIC flag? Each slot has its space in memory. By default it's compiled for the first slot address. Running such binary from the second slot, prepared for the first slot, is impossible, because data access etc. (to be honest, this is my first time with GOT and PIC compiling) is based on Program Counter register value (current position in the program memory space). Firmware update uses the next free slot, which is not currently in use. Because I don't know which is currently in use, I need to build binary which will be working properly across all slots (2 in that case). That's why, after reading many websites, threads etc., I think I need this.

My flow during switching from bootloader to main application is as follows:

  1. Check which firmware slot should be used
  2. Disable IRQs.
  3. Copy vector table to RAM. That part of RAM is the same for both slots. During copying process I'm changing offset for each address, so they will be compatible with particular firmware slot. By default addresses don't have offset, it's removed in post-compiling stage.
  4. Set stack pointer, according to the first word in vector table in RAM. That addresses is not changed while copying vector table to RAM.
  5. Set SCB->VTOR.
  6. Execute Data Sync Barrier DSB().
  7. Jump to the Reset Handler from vector table copied to RAM.

EDIT AFTER old_timer POSTED ANSWER

So, I tried to compile code for both slots. Here are the results of GOT disassembly:

Disassembly of section .got:

080083ac <_got_address>:
 80083ac:   0800beb9    stmdaeq r0, {r0, r3, r4, r5, r7, r9, sl, fp, ip, sp, pc}
 80083b0:   0800bf4c    stmdaeq r0, {r2, r3, r6, r8, r9, sl, fp, ip, sp, pc}
 80083b4:   20000274    andcs   r0, r0, r4, ror r2
 80083b8:   2000022c    andcs   r0, r0, ip, lsr #4
 80083bc:   20012fb4            ; <UNDEFINED> instruction: 0x20012fb4
 80083c0:   080086c5    stmdaeq r0, {r0, r2, r6, r7, r9, sl, pc}
 80083c4:   20000200    andcs   r0, r0, r0, lsl #4
 80083c8:   200132f0    strdcs  r3, [r1], -r0
 80083cc:   20013330    andcs   r3, r1, r0, lsr r3
 80083d0:   080088e1    stmdaeq r0, {r0, r5, r6, r7, fp, pc}
 80083d4:   20013334    andcs   r3, r1, r4, lsr r3
 80083d8:   20013338    andcs   r3, r1, r8, lsr r3
 80083dc:   20000230    andcs   r0, r0, r0, lsr r2
 80083e0:   200132d0    ldrdcs  r3, [r1], -r0
 80083e4:   20012fb8            ; <UNDEFINED> instruction: 0x20012fb8
 80083e8:   20000234    andcs   r0, r0, r4, lsr r2
 80083ec:   200131cc    andcs   r3, r1, ip, asr #3
 80083f0:   0800bed1    stmdaeq r0, {r0, r4, r6, r7, r9, sl, fp, ip, sp, pc}
 80083f4:   080089a1    stmdaeq r0, {r0, r5, r7, r8, fp, pc}
 80083f8:   0800bf7c    stmdaeq r0, {r2, r3, r4, r5, r6, r8, r9, sl, fp, ip, sp, pc}
 80083fc:   080086a5    stmdaeq r0, {r0, r2, r5, r7, r9, sl, pc}
 8008400:   080087f1    stmdaeq r0, {r0, r4, r5, r6, r7, r8, r9, sl, pc}
 8008404:   200132cc    andcs   r3, r1, ip, asr #5

After changing firmware slot as @old_timer said, this is changed:

 Disassembly of section .got:

081043ac <_got_address>:
 81043ac:   08107eb9    ldmdaeq r0, {r0, r3, r4, r5, r7, r9, sl, fp, ip, sp, lr}
 81043b0:   08107f4c    ldmdaeq r0, {r2, r3, r6, r8, r9, sl, fp, ip, sp, lr}
 81043b4:   20000274    andcs   r0, r0, r4, ror r2
 81043b8:   2000022c    andcs   r0, r0, ip, lsr #4
 81043bc:   20012fb4            ; <UNDEFINED> instruction: 0x20012fb4
 81043c0:   081046c5    ldmdaeq r0, {r0, r2, r6, r7, r9, sl, lr}
 81043c4:   20000200    andcs   r0, r0, r0, lsl #4
 81043c8:   200132f0    strdcs  r3, [r1], -r0
 81043cc:   20013330    andcs   r3, r1, r0, lsr r3
 81043d0:   081048e1    ldmdaeq r0, {r0, r5, r6, r7, fp, lr}
 81043d4:   20013334    andcs   r3, r1, r4, lsr r3
 81043d8:   20013338    andcs   r3, r1, r8, lsr r3
 81043dc:   20000230    andcs   r0, r0, r0, lsr r2
 81043e0:   200132d0    ldrdcs  r3, [r1], -r0
 81043e4:   20012fb8            ; <UNDEFINED> instruction: 0x20012fb8
 81043e8:   20000234    andcs   r0, r0, r4, lsr r2
 81043ec:   200131cc    andcs   r3, r1, ip, asr #3
 81043f0:   08107ed1    ldmdaeq r0, {r0, r4, r6, r7, r9, sl, fp, ip, sp, lr}
 81043f4:   081049a1    ldmdaeq r0, {r0, r5, r7, r8, fp, lr}
 81043f8:   08107f7c    ldmdaeq r0, {r2, r3, r4, r5, r6, r8, r9, sl, fp, ip, sp, lr}
 81043fc:   081046a5    ldmdaeq r0, {r0, r2, r5, r7, r9, sl, lr}
 8104400:   081047f1    ldmdaeq r0, {r0, r4, r5, r6, r7, r8, r9, sl, lr}
 8104404:   200132cc    andcs   r3, r1, ip, asr #5

1. First to do is to reserve in RAM memory space for GOT and request bootloader/startup to copy GOT to that place and add slot offset if necessary. I think I can do that by changing linker code so that it will place GOT in VMA of RAM. So I assume, in the rest of application, GOT address will change to the address placed in RAM, am I right?

Why this binary is not working in the device? This is because I should add compilation flag -mpic-register=r10 and set this register to the GOT address after copying GOT to RAM and before executing main application from the slot? Ooh! Wait, this is working on firmware slot 0, but i don't know why. I haven't checked the second slot, will update soon.

VIPPER
  • 326
  • 4
  • 24
  • back up to what you are trying to do, why you think you need PIC, your toolchain since this is a toolchain specific thing, and then what the tools built and how you moved/patched the GOT, to match the relocation, etc. – old_timer Jun 03 '18 at 03:47
  • provide a simple example, show the disassembly of that example or the relevant parts, where you patched the got and what values you modified, etc. – old_timer Jun 03 '18 at 03:48
  • if you are talking about a microcontroller with a flash and a vector table why would you not just build for the desired address rather than copy and patch it? a copy and jump would be MUCH easier. – old_timer Jun 03 '18 at 03:48
  • Updated post above. What disassembly I need to show you? A dump file? A part of elf? – VIPPER Jun 04 '18 at 19:53
  • yeah, dont know if that will work what you are trying to do. the code/disassembly is how are you modifying the got? are you planning to have your bootloader modify it based on which bank you are hitting? If you are assuming there is compiler or linker magic that makes it work there isnt, the tool builds for your linked address, you want to modify that you modify the got at least for gnu. but since this is going into a flash you have to modify it before you commit to the flash. – old_timer Jun 04 '18 at 21:23
  • bank 1 you dont modify bank2 you have to modify the .text at least, assuming that sram is the same address space for programs in both banks, if not then you have to modify all of the got entries... – old_timer Jun 04 '18 at 21:24
  • there is also the question of why not link for both spaces and only download/flash the one linked for the destination address space? – old_timer Jun 04 '18 at 21:25
  • if you do two builds with the PIC stuff set, for the two address spaces, then compare the GOT and see what has to change when you load, will want/need some scheme for the bootloader to know where the GOT is. I would go with the build both use one, but if this is an educational exercise, build for different spaces and compare what the tools generate for each, to get a feel for how that table works and how you have to modify it... – old_timer Jun 04 '18 at 21:27
  • Hah! Yep, this is exactly what I thought that compiler and linker do all magic for me :P So, GOT simply includes offset to data/functions in my code and all what should be done is the same what I already have done for VTOR? Just add firmware slot address offset to these records? – VIPPER Jun 05 '18 at 11:40
  • that is my understanding. try building with different linker scripts for different address spaces and see how that affects the GOT, and/or disassemble code around items that reference it and see what needs to be changed. – old_timer Jun 05 '18 at 12:16
  • your bootstrap and what it does depends on the C library and/or other packaging you are using. You can disassemble that or look at the source to see what it does, but I dont see how it could know where you want the code. So assume it is up to you. – old_timer Jun 05 '18 at 12:19
  • working on an example. reminding me that the code should generally be all built..as requested...position independent. so generally relative for .text just place it somewhere. but data is assumed to be movable and uses the GOT. There are perhaps more complicated linker scripts that make some section of code relocatable relative to others? I assume you are not doing that... – old_timer Jun 05 '18 at 12:48
  • Regarding your lost comment... honestly.. how it differs from all above? Is it not the same? I thought that's a goal... to get binary position independent so it could be run from any FLASH memory address – VIPPER Jun 05 '18 at 19:29
  • @VIPPER Did you patch the FreeRTOS code also? to preserv the r10 value when starting FreeRTOS kernel... And did you manage to make it all work as you planed ? Two slots, arbitrary flash address? – Dabo Dec 07 '20 at 11:33

1 Answers1

6

There are likely countless ways to do this, but hopefully this gives you some ammo to start with to start to see what is going on.

boot.s

.thumb
.globl _start
_start:
reset:
    mov r0,pc
    ldr r1,=0xFFFF0000
    and r0,r1
    ldr r1,gotbase
    add r0,r1
    bl centry
    b .
    .align
gotbase:
    .word _GLOBAL_OFFSET_TABLE_-(_start)
    .word _start
    .word _GLOBAL_OFFSET_TABLE_
    .word _GLOBAL_OFFSET_TABLE_

so.c

extern unsigned int fun ( unsigned int );
unsigned int x;
unsigned int y;
unsigned int z;
void centry ( void )
{
    x=5;
    y=6;
    z=fun(77);
}

fun.c

unsigned int fun ( unsigned int x )
{
    return(x+3);
}

flash.ld

MEMORY
{
    rom : ORIGIN = 0x08020000, LENGTH = 0x1000
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000
}
SECTIONS
{
    .text : { *(.text*) } > rom
    .rodata : { *(.rodata*) } > rom
    .bss : { *(.bss*) } > ram
}

build

arm-none-eabi-as --warn  boot.s -o boot.o
arm-none-eabi-gcc -Wall -O2 -mthumb -fpic -mthumb -c so.c -o so.o
arm-none-eabi-gcc -Wall -O2 -mthumb -fpic -mthumb -c fun.c -o fun.o
arm-none-eabi-ld -o so.elf -T flash.ld boot.o so.o fun.o
arm-none-eabi-objdump -D so.elf > so.list
arm-none-eabi-objcopy --srec-forceS3 so.elf -O srec so.srec
arm-none-eabi-objcopy so.elf so.bin -O binary

disassemble

Disassembly of section .text:
08020000 <_start>:
 8020000:   4678        mov r0, pc
 8020002:   4907        ldr r1, [pc, #28]   ; (8020020 <gotbase+0x10>)
 8020004:   4008        ands    r0, r1
 8020006:   4902        ldr r1, [pc, #8]    ; (8020010 <gotbase>)
 8020008:   1840        adds    r0, r0, r1
 802000a:   f000 f80b   bl  8020024 <centry>
 802000e:   e7fe        b.n 802000e <_start+0xe>

08020010 <gotbase>:
 8020010:   00000060
 8020014:   08020000
 8020018:   00000048
 802001c:   00000044
 8020020:   ffff0000

08020024 <centry>:
 8020024:   2205        movs    r2, #5
 8020026:   b510        push    {r4, lr}
 8020028:   4c08        ldr r4, [pc, #32]   ; (802004c <centry+0x28>)
 802002a:   4b09        ldr r3, [pc, #36]   ; (8020050 <centry+0x2c>)
 802002c:   447c        add r4, pc
 802002e:   58e3        ldr r3, [r4, r3]
 8020030:   601a        str r2, [r3, #0]
 8020032:   4b08        ldr r3, [pc, #32]   ; (8020054 <centry+0x30>)
 8020034:   58e3        ldr r3, [r4, r3]
 8020036:   3201        adds    r2, #1
 8020038:   204d        movs    r0, #77 ; 0x4d
 802003a:   601a        str r2, [r3, #0]
 802003c:   f000 f80e   bl  802005c <fun>
 8020040:   4b05        ldr r3, [pc, #20]   ; (8020058 <centry+0x34>)
 8020042:   58e3        ldr r3, [r4, r3]
 8020044:   6018        str r0, [r3, #0]
 8020046:   bc10        pop {r4}
 8020048:   bc01        pop {r0}
 802004a:   4700        bx  r0
 802004c:   00000030
 8020050:   00000000
 8020054:   00000008
 8020058:   00000004

0802005c <fun>:
 802005c:   3003        adds    r0, #3
 802005e:   4770        bx  lr

Disassembly of section .got:

08020060 <.got>:
 8020060:   20000000
 8020064:   20000004
 8020068:   20000008

Disassembly of section .got.plt:

0802006c <_GLOBAL_OFFSET_TABLE_>:
    ...

Disassembly of section .bss:

20000000 <x>:
20000000:   00000000

20000004 <z>:
20000004:   00000000

20000008 <y>:
20000008:   00000000

This is intentionally somewhat, well a lot, minimal. The first and most interesting item with respect to position independence is this:

Disassembly of section .got:

08020060 <.got>:
 8020060:   20000000
 8020064:   20000004
 8020068:   20000008

And what this clearly is is the three global data items that we have in the program. Add more items you will see this change.

if you change the addresses in the linker script

rom : ORIGIN = 0x08010000, LENGTH = 0x1000
ram : ORIGIN = 0x30000000, LENGTH = 0x1000

at least for this simple program with the tools I used, the machine code doesnt change (it is technically possible with optimizations, but is assumed to be position independent so you should not care about the code location with reason) but the got does to reflect the 0x30000000 address.

Being all thumb (probably doesnt matter) and all built position independent and flashes being relatively small (compared to the range of the branch and branch link instructions) the linker shouldnt have any issues or magic making relative branches, so no program counter math, I would hope, although if you really really tried I bet you could make it happen and I would assume, but you will find if you push it, if that is the case. And likely if you push it maybe you will end up with .text or other based offsets here:

Disassembly of section .got.plt:

0802006c <_GLOBAL_OFFSET_TABLE_>:
    ...

So if your alternate locations for your programs also include alternate locations for the data, then you need to patch up the global offset table.

My bootstrap is more than minimal, was messing around with one brute force way to get at the address of the GOT. There are no doubt linker script and/or ghee whiz code ways to get at this information. Likewise you can likely use the linker script to force/place the GOT.

 8020024:   2205        movs    r2, #5

 8020028:   4c08        ldr r4, [pc, #32]   ; (802004c <centry+0x28>)

 802002c:   447c        add r4, pc

 8020032:   4b08        ldr r3, [pc, #32]   ; (8020054 <centry+0x30>)
 8020034:   58e3        ldr r3, [r4, r3]
 8020036:   3201        adds    r2, #1

 802003a:   601a        str r2, [r3, #0]

these items are doing a position independent version of y = 6; they compute the offset to the got, then an offset into that and use that to address the memory location, remove the pic command line options and see how this changes.

So same machine code dependent on the got for the actual address for the item.

if we have 0x20000004 then that is where y lives if the table has 0x30000004 then that is where y lives.

as coded and built above

08020060 <.got>:
 8020060:   20000000
 8020064:   20000004
 8020068:   20000008

the table lives in flash, so the code you use to place this program in flash will need to patch this table as it writes to the flash. if you play linker games to put the table in ram but in the flash on the way there like .data that are bytes in ram that go somewhere, but are in flash then copied by the bootstrap, combination of bootstrap and linker script code.

In either case I dont see how it is possible that any stock bootstrap would know where you want this located. .text code is assumed to be relocatable with some alignment assumptions, but .data and other are assumed to be not in the same memory space and do not move linearly with .text (cant just take some linked .text address and discovered .text address and adjust the data offsets by that amount, as the two are assumed to be separate and are in this case (cortex-m microcontroller))

So I would (other than answers here have never had a need to mess with this) start with the ammo above be it simply knowing how to disassemble and read the code and/or some of the code above, and examine what the tools are building for you, where they are putting things. I would assume that you are building the program itself (.text if you will) as one big blob so the tools should build that all with relative addressing for the accesses within that section. If you didnt write the bootstrap then it is not a toolchain thing it is a C library or other (RTOS, HAL, etc) thing, and I would not expect this to have position independent global offset table patchup code as how would the bootstrap know where you want the the .data/.bss to move? Ponder that for a bit. Even worse in this case if the GOT is in flash, then it has to be patched up BEFORE execution, not during so some other program has to do this. Which is probably why the elf file format contains the location/size of the GOT so that the loader, the operating system or other tool that loads this program before running it. can find and patch this up.

If you want your programs to be loaded into one of two different flash spaces then you need to solve this with whatever is loading. Again very crude brute force way to start:

.thumb
.globl _start
_start:
reset:
    b skip
    .align
    .word _GLOBAL_OFFSET_TABLE_-(_start)
skip:


08020000 <_start>:
 8020000:   e002        b.n 8020008 <skip>
 8020002:   46c0        nop         ; (mov r8, r8)
 8020004:   00000068    andeq   r0, r0, r8, rrx

08020008 <skip>:

your loader can find the offset in a place that you left (offset 0x4 into the binary), but of course you need to figure out (linker magic) and place the size of the global offset table in a known place. that or support full blown elf or other format files and parse through those.

EDIT:

08020068 <.got>:
 8020068:   20000000
 802006c:   20000004
 8020070:   20000008

08020068 <.got>:
 8020068:   30000000
 802006c:   30000004
 8020070:   30000008

The GOT doesnt/cannot move it has to be pc relative so the code as compiled in .text can find it. What it points to which is the whole idea has to be modified if/when you move where you want those items. So as shown above if it were linked such that x,y,z are at 0x20000000, 0x20000004, 0x20000008. But if you wish to run with x,y,z at 0x30000000, relocate basically, then you need to modify the GOT itself to point at those items just like the second example above. Because the got is in .text so that it is pc relative to the code (as shown above how the code is constructed with the command line option I used) and this is a mcu and if you have .text in flash, then the got has to be modified before being placed in flash which is not at runtime for this code. So your bootloader or whatever places this program in flash would need to do that patch, IF you want .data/.bss to be somewhere other than linked.

08020068 <.got>:
 8020068:   20000000
 802006c:   20000004
 8020070:   20000008

08020068 <.got>:
 8020068:   30000000
 802006c:   30000004
 8020070:   30000008

The GOT doesnt/cannot move it has to be pc relative so the code as compiled in .text can find it. What it points to which is the whole idea has to be modified if/when you move where you want those items. So as shown above if it were linked such that x,y,z are at 0x20000000, 0x20000004, 0x20000008. But if you wish to run with x,y,z at 0x30000000, relocate basically, then you need to modify the GOT itself to point at those items just like the second example above. Because the got is in .text so that it is pc relative to the code (as shown above how the code is constructed with the command line option I used) and this is a mcu and if you have .text in flash, then the got has to be modified before being placed in flash which is not at runtime for this code. So your bootloader or whatever places this program in flash would need to do that patch, IF you want .data/.bss to be somewhere other than linked.

Using your compiler flags

Disassembly of section .text:

08020000 <_start>:
 8020000:   e002        b.n 8020008 <skip>
 8020002:   46c0        nop         ; (mov r8, r8)
 8020004:   00000064    andeq   r0, r0, r4, rrx

08020008 <skip>:
 8020008:   4678        mov r0, pc
 802000a:   4907        ldr r1, [pc, #28]   ; (8020028 <gotbase+0x10>)
 802000c:   4008        ands    r0, r1
 802000e:   4902        ldr r1, [pc, #8]    ; (8020018 <gotbase>)
 8020010:   1840        adds    r0, r0, r1
 8020012:   f000 f80b   bl  802002c <centry>
 8020016:   e7fe        b.n 8020016 <skip+0xe>

08020018 <gotbase>:
 8020018:   00000064    andeq   r0, r0, r4, rrx
 802001c:   08020000    stmdaeq r2, {}  ; <UNPREDICTABLE>
 8020020:   00000044    andeq   r0, r0, r4, asr #32
 8020024:   00000040    andeq   r0, r0, r0, asr #32
 8020028:   ffff0000            ; <UNDEFINED> instruction: 0xffff0000

0802002c <centry>:
 802002c:   b510        push    {r4, lr}
 802002e:   4654        mov r4, r10
 8020030:   2205        movs    r2, #5
 8020032:   4b08        ldr r3, [pc, #32]   ; (8020054 <centry+0x28>)
 8020034:   58e3        ldr r3, [r4, r3]
 8020036:   601a        str r2, [r3, #0]
 8020038:   4b07        ldr r3, [pc, #28]   ; (8020058 <centry+0x2c>)
 802003a:   58e3        ldr r3, [r4, r3]
 802003c:   3201        adds    r2, #1
 802003e:   204d        movs    r0, #77 ; 0x4d
 8020040:   601a        str r2, [r3, #0]
 8020042:   f000 f80d   bl  8020060 <fun>
 8020046:   4b05        ldr r3, [pc, #20]   ; (802005c <centry+0x30>)
 8020048:   58e3        ldr r3, [r4, r3]
 802004a:   6018        str r0, [r3, #0]
 802004c:   bc10        pop {r4}
 802004e:   bc01        pop {r0}
 8020050:   4700        bx  r0
 8020052:   46c0        nop         ; (mov r8, r8)
 8020054:   00000000    andeq   r0, r0, r0
 8020058:   00000008    andeq   r0, r0, r8
 802005c:   00000004    andeq   r0, r0, r4

08020060 <fun>:
 8020060:   3003        adds    r0, #3
 8020062:   4770        bx  lr

Disassembly of section .got:

08020064 <.got>:
 8020064:   20000000    andcs   r0, r0, r0
 8020068:   20000004    andcs   r0, r0, r4
 802006c:   20000008    andcs   r0, r0, r8

which changes it to use this

 802002e:   4654        mov r4, r10

but notice that the tools do not set r10, you have to add code to point r10 to the GOT for this to work at all even at the linked address.

So again the GOT itself does not move, thats the whole point, the contents change to point at the relocated location for .data/.bss. See the last example above the GOT is in the same place but the addresses for x,y,z have changed to reflect their new location. The disassembly shows linked address based addresses, but if you link for a different address, and compare just the machine code you will see it doesnt change, the instructions used are pc-relative.

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • of course try all the additional command line options you specified and see how they affect the build of the code. trivial examples like mine or full applications like yours or somewhere in the middle. – old_timer Jun 05 '18 at 13:52
  • 1. Why y variable is in GOT? This is used only in one file. – VIPPER Jun 05 '18 at 21:38
  • 2. Why GOT need to be patched, it consists of addresses in RAM, so everything seems to be ok – VIPPER Jun 05 '18 at 21:38
  • 3. Why GOT need to be copied to RAM? – VIPPER Jun 05 '18 at 21:41
  • 4. "I dont see how it is possible that any stock bootstrap would know where you want this located". You mean where GOT is located? It seems to be easy, linker knows where it is located... or am I missing something? – VIPPER Jun 05 '18 at 21:43
  • 1
    5. If this need to be patched... could I use in linker command for that section such as: >RAM AT >FLASH? Will it cause that address of GOT will be in RAM? If yes, I could copy GOT to RAM during booting and then dynamically change the addresses... make sense? – VIPPER Jun 05 '18 at 21:48
  • 6. In my GOT, first two records point to place in FLASH, not in RAM. Is it ok? – VIPPER Jun 05 '18 at 21:49
  • 7. .data section is assumed to be in the same place each time, I mean start of this region in RAM – VIPPER Jun 05 '18 at 21:51
  • 8. How does using GOT affects using FreeRTOS which is partly written in assembler, so compiler don't have control over using registers? – VIPPER Jun 05 '18 at 21:56
  • 9. It seems that GOT is used only in high-level application, like Linux/Windows OS'es, hmm? It's not often used in MCU projects. It seems really complicated to do what I want to have. – VIPPER Jun 05 '18 at 22:05
  • I assume since you wanted the application to be in one of two places then you may have wished for .data and .bss to be in one of two places. The code is pic as built, pc relative addressing to get around (branching, etc), so it should not need any modifications, put the code in an aligned location and branch to it (remember to set the lsbit of the address). .data/.bss are not relative to .text so it is not possible for the toolchain to know where other than the linked location where you may want .data/.bss so it is up to you. – old_timer Jun 05 '18 at 23:29
  • x,y,z are global variables, so .bss so GOT. didnt even need to use them, just used them lightly to demonstrate how the compiler generates the code to access them. – old_timer Jun 05 '18 at 23:29
  • the bootstrap would not know where you want the .data/.bss to be relocated, not where the GOT is that is at least as linked here, at a known location relative within .text (so pc relative). the bootstrap can discover where the code is from the program counter, but other than some possibly minimal alignment (maybe as minimal as an even address) the tool shouldnt have an issue building all the .text to be pc relative addressing/branching. – old_timer Jun 05 '18 at 23:33
  • taking this code and porting it to mips for example requires more work, and has a relocation for the call to fun(), so other code not just data. Was my first try, was thinking it would take a few tries to find one that was not as simple as arm/thumb. – old_timer Jun 05 '18 at 23:54
  • While debugging I would need to compile build for the specified position in the memory. If I have let's say 2 slots and each time I create a position independent binary so it can be run at both slots - then I need to check which slot is currently in use and compile for that slot. Is it possible to inform debugger which slot is in use and require it to add some offset so no additional compilation would be needed? – VIPPER Mar 18 '21 at 08:15