On arm-none-eabi-gcc (cortex m0 / stm32f03), I see address values from Attribute'Address
that seem to differ between those inserted at compile time and those which should be real. As an example, I look at the address of Hardfault_Handler
.
This is my code:
procedure Hardfault_Handler is
SP : Address := Get_Stack_Pointer; -- save sp after handler entry
PC : Address := Get_Program_Counter; -- save current pc
PC_Offset : Storage_Offset := PC - Hardfault_Handler'Address;
Num_Of_Pushed_Regs : Natural := 0;
SP_Calc : Integer_Address := To_Integer (SP);
package Thumb_Ins_Pnt is new System.Address_To_Access_Conversions
(Push_Instruction);
use Thumb_Ins_Pnt;
Temp_Ins : Object_Pointer;
begin
--loop over program code at start of hardfaulthandler
for I in 0 .. PC_Offset when (I mod 2 = 0) loop
Temp_Ins := To_Pointer (Hardfault_Handler'Address + I);
-- is this a push instruction?
if Temp_Ins.Mask = PUSH_Ins_Mask then
-- yes, count number of regs we pushed to stack
for Bit of Temp_Ins.Regs when Bit = True loop
Num_Of_Pushed_Regs := Num_Of_Pushed_Regs + 1;
end loop;
-- alter back SP to Point before push (+ because stack grows down)
SP_Calc := SP_Calc + 4 * Integer_Address (Num_Of_Pushed_Regs);
declare
Old_Regs : constant Stacked_Registers with
Import, Address => To_Address (SP_Calc + Stacked_Reg_Offset);
Old_PC_Content : constant Thumb_Instruction with
Import, Address => Old_Regs.PC;
begin
if Old_PC_Content = Break_Point_Instruction then
-- Hardfault happend because no Debugger is connected,
-- just return
return;
end if;
end;
end if;
end loop;
Put_Line ("Hard Fault");
-- fault handling to be done
end Hardfault_Handler;
Output of objdump:
08000754 <m0__startup__hardfault_handler>:
procedure Hardfault_Handler is
8000754: b5f8 push {r3, r4, r5, r6, r7, lr}
function Get_Stack_Pointer return Address is
Result : Address;
begin
Asm
8000756: 46ec mov ip, sp
end Get_Stack_Pointer;
function Get_Program_Counter return Address is
Result : Address;
begin
Asm
8000758: 467d mov r5, pc
PC_Offset : Storage_Offset := PC - Hardfault_Handler'Address;
800075a: 4e2a ldr r6, [pc, #168] ; (8000804 <m0__startup__hardfault_h
andler+0xb0>)
end "-";
Here the value for Hardfault_Handler"Address stored @8000804
8000802: bdf8 pop {r3, r4, r5, r6, r7, pc}
8000804: 08000755 stmdaeq r0, {r0, r2, r4, r6, r8, r9, sl}
8000808: 08002a88 stmdaeq r0, {r3, r7, r9, fp, sp}
800080c: 7fffffff svcvc 0x00ffffff
8000810: 0000beab andeq fp, r0, fp, lsr #29
8000814: 08002a28 stmdaeq r0, {r3, r5, r9, fp, sp}
8000818: 08002ad8 stmdaeq r0, {r3, r4, r6, r7, r9, fp, sp}
from inside gdb it looks like this:

also this is my vector table, the addresses are different too. But the reset handler, gets called and runs fine :
Vector_Table : constant Address_Array :=
(Sram_Stack_Start, Reset_Handler'Address, NMI_Handler'Address,
Hardfault_Handler'Address, MemManage_Handler'Address,
Bus_Fault_Handler'Address, Usage_Fault_Handler'Address, Reserved,
Reserved, Reserved, Reserved, SVCall_Handler'Address,
Debug_Handler'Address, Reserved, PendSV_Handler'Address,
Systick_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address, Default_Handler'Address,
Default_Handler'Address);
--Default_Handler'Address);
pragma Linker_Section (Vector_Table, "_vector_table");
08000000 <m0__startup__vector_table>:
8000000: 20001000 andcs r1, r0, r0
8000004: 080005b1 stmdaeq r0, {r0, r4, r5, r7, r8, sl}
8000008: 08000699 stmdaeq r0, {r0, r3, r4, r7, r9, sl}
800000c: 08000755 stmdaeq r0, {r0, r2, r4, r6, r8, r9, sl}
8000010: 080006b1 stmdaeq r0, {r0, r4, r5, r7, r9, sl}
8000014: 080006c9 stmdaeq r0, {r0, r3, r6, r7, r9, sl}
8000018: 080006e1 stmdaeq r0, {r0, r5, r6, r7, r9, sl}
...
080005b0 <Reset_Handler>:
-------------------
-- Reset_Handler --
-------------------
procedure Reset_Handler is
80005b0: b570 push {r4, r5, r6, lr}
Data_L : Storage_Element with
Volatile, Import, External_Name => "__data_size";
Data_Length : constant Storage_Offset := Addr2SO (Data_L'Address);
Data_Load_Array : Storage_Array (1 .. Data_Length) with
80005b2: 4c16 ldr r4, [pc, #88] ; (800060c <Reset_Handler+0x5c>)
Bss_L : Storage_Element with
Volatile, Import, Convention => Asm, External_Name => "__bss_size";
Can someone explain this behavior?