I'm trying to use PIE on ARM (STM32F4DISCOVERY, GCC ARM Embedded Toolchain).
Here is linker script:
Code: Select all
MEMORY {
rom (rx): ORIGIN = 0x08000000, LENGTH = 1M
ram (rw): ORIGIN = 0x20000000, LENGTH = 128k
}
_vector_table_size = 0x400;
_stack_size = 2048;
SECTIONS {
.vec : {
KEEP(startup.o(vector_table))
. = ALIGN(4);
} > rom
.text : {
*(.text*)
} > rom
.rodata : {
*(.rodata*)
} > rom
.bss (NOLOAD) : {
*(.bss*)
. = ALIGN(4);
} > ram
.data : {
*(.data*)
. = ALIGN(4);
} > ram AT > rom
.stack (NOLOAD) : {
_sstack = .;
. = . + _stack_size;
. = ALIGN(4);
_estack = .;
} > ram
}
Code: Select all
__attribute__ (( noinline )) void start void() { }
__attribute__ (( section("vector_table") )) static uint32_t *vectors[] = {
(uint32_t *) &_estack,
(uint32_t *) start,
<...>
};
Code: Select all
(gdb) print *(uint32_t*)0x8000000
0x20005000
(gdb) print *(uint32_t*)0x8000004
0x8000d39
(gdb) print &_estack
0x20005000
Code: Select all
CFLAGS += -fpie -msingle-pic-base -mpic-register=r9 -mno-pic-data-is-text-relative
LDFLAGS += -pie
Code: Select all
(gdb) print $r9
0x8004400
(gdb) print *(uint32_t*)0x8000000
0x0
(gdb) print *(uint32_t*)0x8000004
0x8000d39
(gdb) print &_estack
0x20005000
- Why element 0 (start) initialized with address, but element 1 (&_estack) with 0x0? What's the difference between (pointer to) uint32_t and (pointer to) function here?
- Why element 0 initialized by 0x0 but print &_estack prints a value?
- Is there some way to get it working? So get offset/etc. of .stack segment into vectors[0] at compile/linking time?
- Why (even with PIE) start initialized with absolute address (0x8004d39) but not offset by GOT/PLT? (btw, GOT or PLT?)