libgloss: arm: Add hardfault handler for M-profile

Message ID 20260612155306.173235-1-christophe.lyon@arm.com
State New
Headers
Series libgloss: arm: Add hardfault handler for M-profile |

Commit Message

Christophe Lyon June 12, 2026, 3:53 p.m. UTC
  After reaching a hardfault, the simulator enters an infinite loop
unless we map the handler to 'abort'.

The patch adds this minimal setup for M-profile in
libgloss/arm/cpu-init/rdimon-aem.S and introduces the new
libgloss/arm/elf-mprofile-mps2.specs to add the mapping to the right
memory address.

2026-05-29  Andre Vieira <andre.simoesdiasvieira@arm.com>
	Christophe Lyon  <christophe.lyon@arm.com>

	libgloss/
	* Makefile.in: Add entry for arm/mprofile-mps2.specs.
	* arm/Makefile.inc: Add entry for mprofile-mps2.specs.
	* arm/cpu-init/rdimon-aem.S: Update comment. Add hardfault
	handler.
	* arm/elf-mprofile-mps2.specs: New file.
---
 libgloss/Makefile.in                 |  1 +
 libgloss/arm/Makefile.inc            |  3 ++-
 libgloss/arm/cpu-init/rdimon-aem.S   | 11 +++++++++--
 libgloss/arm/elf-mprofile-mps2.specs | 26 ++++++++++++++++++++++++++
 4 files changed, 38 insertions(+), 3 deletions(-)
 create mode 100644 libgloss/arm/elf-mprofile-mps2.specs
  

Comments

Richard Earnshaw June 22, 2026, 10:48 a.m. UTC | #1
On 12/06/2026 16:53, Christophe Lyon wrote:
> After reaching a hardfault, the simulator enters an infinite loop
> unless we map the handler to 'abort'.
> 
> The patch adds this minimal setup for M-profile in
> libgloss/arm/cpu-init/rdimon-aem.S and introduces the new
> libgloss/arm/elf-mprofile-mps2.specs to add the mapping to the right
> memory address.
> 
> 2026-05-29  Andre Vieira <andre.simoesdiasvieira@arm.com>
> 	Christophe Lyon  <christophe.lyon@arm.com>
> 
> 	libgloss/
> 	* Makefile.in: Add entry for arm/mprofile-mps2.specs.
> 	* arm/Makefile.inc: Add entry for mprofile-mps2.specs.
> 	* arm/cpu-init/rdimon-aem.S: Update comment. Add hardfault
> 	handler.
> 	* arm/elf-mprofile-mps2.specs: New file.
> ---
>   libgloss/Makefile.in                 |  1 +
>   libgloss/arm/Makefile.inc            |  3 ++-
>   libgloss/arm/cpu-init/rdimon-aem.S   | 11 +++++++++--
>   libgloss/arm/elf-mprofile-mps2.specs | 26 ++++++++++++++++++++++++++
>   4 files changed, 38 insertions(+), 3 deletions(-)
>   create mode 100644 libgloss/arm/elf-mprofile-mps2.specs
> 
> diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in
> index 5146a7880..c03ea4e6b 100644
> --- a/libgloss/Makefile.in
> +++ b/libgloss/Makefile.in
> @@ -2255,6 +2255,7 @@ TEXINFO_TEX = ../texinfo/texinfo.tex
>   @CONFIG_ARM_TRUE@	arm/aprofile-validation-v2m.specs \
>   @CONFIG_ARM_TRUE@	arm/aprofile-ve-v2m.specs \
>   @CONFIG_ARM_TRUE@	arm/aprofile-ve.specs arm/pid.specs \
> +@CONFIG_ARM_TRUE@       arm/mprofile-mps2.specs \
>   @CONFIG_ARM_TRUE@	arm/iq80310.specs
>   @CONFIG_ARM_TRUE@arm_libgloss_linux_a_SOURCES = \
>   @CONFIG_ARM_TRUE@	arm/linux-syscalls0.c \
> diff --git a/libgloss/arm/Makefile.inc b/libgloss/arm/Makefile.inc
> index 41fce3c99..5c740edcb 100644
> --- a/libgloss/arm/Makefile.inc
> +++ b/libgloss/arm/Makefile.inc
> @@ -47,7 +47,8 @@ multilibtool_LIBRARIES += %D%/librdpmon.a
>   	%D%/aprofile-validation.specs \
>   	%D%/aprofile-validation-v2m.specs \
>   	%D%/aprofile-ve-v2m.specs \
> -	%D%/aprofile-ve.specs
> +	%D%/aprofile-ve.specs \
> +	%D%/mprofile-mps2.specs
>   multilibtool_DATA += \
>   	%D%/rdimon-crt0.o \
>   	%D%/rdimon-crt0-v2m.o
> diff --git a/libgloss/arm/cpu-init/rdimon-aem.S b/libgloss/arm/cpu-init/rdimon-aem.S
> index 2aacbeba9..c960924d4 100644
> --- a/libgloss/arm/cpu-init/rdimon-aem.S
> +++ b/libgloss/arm/cpu-init/rdimon-aem.S
It looks to me as though there's no shared code in this file compared to 
the a-profile variant, which makes me think that perhaps they should 
just be separate files, rather than munged together when there's no 
commonality beyond 'this is startup code'.

Personally, I think it would be better to rename the existing file as 
something like rdimon-aem-a.S and then add a new one (say, 
rdimon-aem-m.S) for the m-profile code.

> @@ -25,7 +25,9 @@
>   
>   /* This file gives a basic initialisation of a Cortex-A series core.  It is
>      the bare minimum required to get Cortex-A core running with a semihosting
> -   interface.
> +   interface.  For M-profile we only define a hardfault handler, required to
> +   prevent the simulator from entering into an infinite loop.  The comments
> +   below apply to A-profile only.

If I've missed something and this code does belong in this file, then 
this whole comment needs properly restructuring.  There should be a 
single top-level comment that just says something like "Provide the 
basic CPU initialization for Armv7 and later CPUs.  We currently support 
A-profile and M-profile.  Then the profile-specific details should be 
moved inside the relevant ifdef sections.  It would be good to get rid 
of the reference to 'Cortex-A' here as well (replace it with A-profile) 
as there's nothing here that is specific to Arm's Cortex-* products: 
this is defined by the architecture.

Finally, if you're keeping this in one place, the copyright dates at the 
top of the file need updating.

>   
>      It sets up a basic 1:1 phsyical address to virtual address mapping;
>      turns the MMU on; enables branch prediction; activates any integrated
> @@ -539,4 +541,9 @@ is_a15_a7:
>   page_tables:
>        PT7(0x1c0e)
>   
> -#endif //#if defined(__ARM_ARCH_7A__) || __ARM_ARCH_PROFILE == 'A'
> +#elif  (__ARM_ARCH_PROFILE == 'M')
> +    /* On M-profile, call abort in case of hardfault: this causes the simulator to
> +       abort execution instead of going into an infinite loop.  */
> +    .section .hardfault_handler_addr, "a"
> +    .word abort
> +#endif //#if defined(__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A')
> diff --git a/libgloss/arm/elf-mprofile-mps2.specs b/libgloss/arm/elf-mprofile-mps2.specs
> new file mode 100644
> index 000000000..edaf71917
> --- /dev/null
> +++ b/libgloss/arm/elf-mprofile-mps2.specs
> @@ -0,0 +1,26 @@
> +# rdimon.specs
> +#
> +# Spec file for AArch32 M profile baremetal newlib with version 2 of
> +# the AngelAPI semi-hosting using the SVC trap instruction.
> +#
> +# This version supports extensibility through an extension mechanism.
> +
> +%rename link_gcc_c_sequence                rdimon_link_gcc_c_sequence
> +
> +%rename link old_link
> +
> +*link:
> +--section-start=.hardfault_handler_addr=0xc %(old_link)
> +
> +*rdimon_libc:
> +%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
> +
> +*rdimon_libgloss:
> +%{!specs=nano.specs:-lrdimon} %{specs=nano.specs:-lrdimon_nano}
> +
> +*link_gcc_c_sequence:
> +%(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) %(rdimon_libgloss) --end-group
> +
> +*startfile:
> +crti%O%s crtbegin%O%s cpu-init/rdimon-aem.o%s %{!pg:rdimon-crt0%O%s} %{pg:rdimon-crt0%O%s}
> +
  
Christophe Lyon June 22, 2026, 1:25 p.m. UTC | #2
On 6/22/26 12:48, Richard Earnshaw wrote:
> On 12/06/2026 16:53, Christophe Lyon wrote:
>> After reaching a hardfault, the simulator enters an infinite loop
>> unless we map the handler to 'abort'.
>>
>> The patch adds this minimal setup for M-profile in
>> libgloss/arm/cpu-init/rdimon-aem.S and introduces the new
>> libgloss/arm/elf-mprofile-mps2.specs to add the mapping to the right
>> memory address.
>>
>> 2026-05-29  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>     Christophe Lyon  <christophe.lyon@arm.com>
>>
>>     libgloss/
>>     * Makefile.in: Add entry for arm/mprofile-mps2.specs.
>>     * arm/Makefile.inc: Add entry for mprofile-mps2.specs.
>>     * arm/cpu-init/rdimon-aem.S: Update comment. Add hardfault
>>     handler.
>>     * arm/elf-mprofile-mps2.specs: New file.
>> ---
>>   libgloss/Makefile.in                 |  1 +
>>   libgloss/arm/Makefile.inc            |  3 ++-
>>   libgloss/arm/cpu-init/rdimon-aem.S   | 11 +++++++++--
>>   libgloss/arm/elf-mprofile-mps2.specs | 26 ++++++++++++++++++++++++++
>>   4 files changed, 38 insertions(+), 3 deletions(-)
>>   create mode 100644 libgloss/arm/elf-mprofile-mps2.specs
>>
>> diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in
>> index 5146a7880..c03ea4e6b 100644
>> --- a/libgloss/Makefile.in
>> +++ b/libgloss/Makefile.in
>> @@ -2255,6 +2255,7 @@ TEXINFO_TEX = ../texinfo/texinfo.tex
>>   @CONFIG_ARM_TRUE@    arm/aprofile-validation-v2m.specs \
>>   @CONFIG_ARM_TRUE@    arm/aprofile-ve-v2m.specs \
>>   @CONFIG_ARM_TRUE@    arm/aprofile-ve.specs arm/pid.specs \
>> +@CONFIG_ARM_TRUE@       arm/mprofile-mps2.specs \
>>   @CONFIG_ARM_TRUE@    arm/iq80310.specs
>>   @CONFIG_ARM_TRUE@arm_libgloss_linux_a_SOURCES = \
>>   @CONFIG_ARM_TRUE@    arm/linux-syscalls0.c \
>> diff --git a/libgloss/arm/Makefile.inc b/libgloss/arm/Makefile.inc
>> index 41fce3c99..5c740edcb 100644
>> --- a/libgloss/arm/Makefile.inc
>> +++ b/libgloss/arm/Makefile.inc
>> @@ -47,7 +47,8 @@ multilibtool_LIBRARIES += %D%/librdpmon.a
>>       %D%/aprofile-validation.specs \
>>       %D%/aprofile-validation-v2m.specs \
>>       %D%/aprofile-ve-v2m.specs \
>> -    %D%/aprofile-ve.specs
>> +    %D%/aprofile-ve.specs \
>> +    %D%/mprofile-mps2.specs
>>   multilibtool_DATA += \
>>       %D%/rdimon-crt0.o \
>>       %D%/rdimon-crt0-v2m.o
>> diff --git a/libgloss/arm/cpu-init/rdimon-aem.S b/libgloss/arm/cpu- 
>> init/rdimon-aem.S
>> index 2aacbeba9..c960924d4 100644
>> --- a/libgloss/arm/cpu-init/rdimon-aem.S
>> +++ b/libgloss/arm/cpu-init/rdimon-aem.S
> It looks to me as though there's no shared code in this file compared to 
> the a-profile variant, which makes me think that perhaps they should 
> just be separate files, rather than munged together when there's no 
> commonality beyond 'this is startup code'.
 > > Personally, I think it would be better to rename the existing file as
> something like rdimon-aem-a.S and then add a new one (say, rdimon-aem- 
> m.S) for the m-profile code.
> 
Indeed, before this patch the code is specific to A-profile, and this 
patch adds a section dedicated to M-profile (no nothing common with 
A-profile).
I think having 2 files makes sense but seems tricky to handle at 
Makefile level (wrt multilibs).
So maybe:
- rename rdi-mon-aem.S into rdimon-aem-a.S, and re-create rdi-mon-aem.S 
which only includes rdimon-aem-a.S
- add rdimon-aem-m.S and make rdi-mon-aem.S include it unconditionally

This way we have 2 separate source files, but no change to the build 
system and multilib support


>> @@ -25,7 +25,9 @@
>>   /* This file gives a basic initialisation of a Cortex-A series 
>> core.  It is
>>      the bare minimum required to get Cortex-A core running with a 
>> semihosting
>> -   interface.
>> +   interface.  For M-profile we only define a hardfault handler, 
>> required to
>> +   prevent the simulator from entering into an infinite loop.  The 
>> comments
>> +   below apply to A-profile only.
> 
> If I've missed something and this code does belong in this file, then 
> this whole comment needs properly restructuring.  There should be a 
> single top-level comment that just says something like "Provide the 
> basic CPU initialization for Armv7 and later CPUs.  We currently support 
> A-profile and M-profile.  Then the profile-specific details should be 
> moved inside the relevant ifdef sections.  It would be good to get rid 
> of the reference to 'Cortex-A' here as well (replace it with A-profile) 
> as there's nothing here that is specific to Arm's Cortex-* products: 
> this is defined by the architecture.

If I move rdimon-aem.S into rdimon-aem-a.S, I can probably make some 
small adjustments to this comment (and not add mentions of M-profile). 
This comment has been unmodified since ... 2013!
> 
> Finally, if you're keeping this in one place, the copyright dates at the 
> top of the file need updating.
> 
>>      It sets up a basic 1:1 phsyical address to virtual address mapping;
>>      turns the MMU on; enables branch prediction; activates any 
>> integrated
>> @@ -539,4 +541,9 @@ is_a15_a7:
>>   page_tables:
>>        PT7(0x1c0e)
>> -#endif //#if defined(__ARM_ARCH_7A__) || __ARM_ARCH_PROFILE == 'A'
>> +#elif  (__ARM_ARCH_PROFILE == 'M')
>> +    /* On M-profile, call abort in case of hardfault: this causes the 
>> simulator to
>> +       abort execution instead of going into an infinite loop.  */
>> +    .section .hardfault_handler_addr, "a"
>> +    .word abort
>> +#endif //#if defined(__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A')
>> diff --git a/libgloss/arm/elf-mprofile-mps2.specs b/libgloss/arm/elf- 
>> mprofile-mps2.specs
>> new file mode 100644
>> index 000000000..edaf71917
>> --- /dev/null
>> +++ b/libgloss/arm/elf-mprofile-mps2.specs
>> @@ -0,0 +1,26 @@
>> +# rdimon.specs
>> +#
>> +# Spec file for AArch32 M profile baremetal newlib with version 2 of
>> +# the AngelAPI semi-hosting using the SVC trap instruction.
>> +#
>> +# This version supports extensibility through an extension mechanism.
>> +
>> +%rename link_gcc_c_sequence                rdimon_link_gcc_c_sequence
>> +
>> +%rename link old_link
>> +
>> +*link:
>> +--section-start=.hardfault_handler_addr=0xc %(old_link)
>> +
>> +*rdimon_libc:
>> +%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
>> +
>> +*rdimon_libgloss:
>> +%{!specs=nano.specs:-lrdimon} %{specs=nano.specs:-lrdimon_nano}
>> +
>> +*link_gcc_c_sequence:
>> +%(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) 
>> %(rdimon_libgloss) --end-group
>> +
>> +*startfile:
>> +crti%O%s crtbegin%O%s cpu-init/rdimon-aem.o%s %{!pg:rdimon-crt0%O%s} 
>> %{pg:rdimon-crt0%O%s}
>> +
>
  
Christophe Lyon June 24, 2026, 8:04 p.m. UTC | #3
I have sent an updated version as part of a new series (now 3 patches):
https://sourceware.org/pipermail/newlib/2026/022515.html

On 6/22/26 15:25, Christophe Lyon wrote:
> 
> 
> On 6/22/26 12:48, Richard Earnshaw wrote:
>> On 12/06/2026 16:53, Christophe Lyon wrote:
>>> After reaching a hardfault, the simulator enters an infinite loop
>>> unless we map the handler to 'abort'.
>>>
>>> The patch adds this minimal setup for M-profile in
>>> libgloss/arm/cpu-init/rdimon-aem.S and introduces the new
>>> libgloss/arm/elf-mprofile-mps2.specs to add the mapping to the right
>>> memory address.
>>>
>>> 2026-05-29  Andre Vieira <andre.simoesdiasvieira@arm.com>
>>>     Christophe Lyon  <christophe.lyon@arm.com>
>>>
>>>     libgloss/
>>>     * Makefile.in: Add entry for arm/mprofile-mps2.specs.
>>>     * arm/Makefile.inc: Add entry for mprofile-mps2.specs.
>>>     * arm/cpu-init/rdimon-aem.S: Update comment. Add hardfault
>>>     handler.
>>>     * arm/elf-mprofile-mps2.specs: New file.
>>> ---
>>>   libgloss/Makefile.in                 |  1 +
>>>   libgloss/arm/Makefile.inc            |  3 ++-
>>>   libgloss/arm/cpu-init/rdimon-aem.S   | 11 +++++++++--
>>>   libgloss/arm/elf-mprofile-mps2.specs | 26 ++++++++++++++++++++++++++
>>>   4 files changed, 38 insertions(+), 3 deletions(-)
>>>   create mode 100644 libgloss/arm/elf-mprofile-mps2.specs
>>>
>>> diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in
>>> index 5146a7880..c03ea4e6b 100644
>>> --- a/libgloss/Makefile.in
>>> +++ b/libgloss/Makefile.in
>>> @@ -2255,6 +2255,7 @@ TEXINFO_TEX = ../texinfo/texinfo.tex
>>>   @CONFIG_ARM_TRUE@    arm/aprofile-validation-v2m.specs \
>>>   @CONFIG_ARM_TRUE@    arm/aprofile-ve-v2m.specs \
>>>   @CONFIG_ARM_TRUE@    arm/aprofile-ve.specs arm/pid.specs \
>>> +@CONFIG_ARM_TRUE@       arm/mprofile-mps2.specs \
>>>   @CONFIG_ARM_TRUE@    arm/iq80310.specs
>>>   @CONFIG_ARM_TRUE@arm_libgloss_linux_a_SOURCES = \
>>>   @CONFIG_ARM_TRUE@    arm/linux-syscalls0.c \
>>> diff --git a/libgloss/arm/Makefile.inc b/libgloss/arm/Makefile.inc
>>> index 41fce3c99..5c740edcb 100644
>>> --- a/libgloss/arm/Makefile.inc
>>> +++ b/libgloss/arm/Makefile.inc
>>> @@ -47,7 +47,8 @@ multilibtool_LIBRARIES += %D%/librdpmon.a
>>>       %D%/aprofile-validation.specs \
>>>       %D%/aprofile-validation-v2m.specs \
>>>       %D%/aprofile-ve-v2m.specs \
>>> -    %D%/aprofile-ve.specs
>>> +    %D%/aprofile-ve.specs \
>>> +    %D%/mprofile-mps2.specs
>>>   multilibtool_DATA += \
>>>       %D%/rdimon-crt0.o \
>>>       %D%/rdimon-crt0-v2m.o
>>> diff --git a/libgloss/arm/cpu-init/rdimon-aem.S b/libgloss/arm/cpu- 
>>> init/rdimon-aem.S
>>> index 2aacbeba9..c960924d4 100644
>>> --- a/libgloss/arm/cpu-init/rdimon-aem.S
>>> +++ b/libgloss/arm/cpu-init/rdimon-aem.S
>> It looks to me as though there's no shared code in this file compared 
>> to the a-profile variant, which makes me think that perhaps they 
>> should just be separate files, rather than munged together when 
>> there's no commonality beyond 'this is startup code'.
>  > > Personally, I think it would be better to rename the existing file as
>> something like rdimon-aem-a.S and then add a new one (say, rdimon-aem- 
>> m.S) for the m-profile code.
>>
> Indeed, before this patch the code is specific to A-profile, and this 
> patch adds a section dedicated to M-profile (no nothing common with A- 
> profile).
> I think having 2 files makes sense but seems tricky to handle at 
> Makefile level (wrt multilibs).
> So maybe:
> - rename rdi-mon-aem.S into rdimon-aem-a.S, and re-create rdi-mon-aem.S 
> which only includes rdimon-aem-a.S
> - add rdimon-aem-m.S and make rdi-mon-aem.S include it unconditionally
> 
> This way we have 2 separate source files, but no change to the build 
> system and multilib support
> 
> 
>>> @@ -25,7 +25,9 @@
>>>   /* This file gives a basic initialisation of a Cortex-A series 
>>> core.  It is
>>>      the bare minimum required to get Cortex-A core running with a 
>>> semihosting
>>> -   interface.
>>> +   interface.  For M-profile we only define a hardfault handler, 
>>> required to
>>> +   prevent the simulator from entering into an infinite loop.  The 
>>> comments
>>> +   below apply to A-profile only.
>>
>> If I've missed something and this code does belong in this file, then 
>> this whole comment needs properly restructuring.  There should be a 
>> single top-level comment that just says something like "Provide the 
>> basic CPU initialization for Armv7 and later CPUs.  We currently 
>> support A-profile and M-profile.  Then the profile-specific details 
>> should be moved inside the relevant ifdef sections.  It would be good 
>> to get rid of the reference to 'Cortex-A' here as well (replace it 
>> with A-profile) as there's nothing here that is specific to Arm's 
>> Cortex-* products: this is defined by the architecture.
> 
> If I move rdimon-aem.S into rdimon-aem-a.S, I can probably make some 
> small adjustments to this comment (and not add mentions of M-profile). 
> This comment has been unmodified since ... 2013!
>>
>> Finally, if you're keeping this in one place, the copyright dates at 
>> the top of the file need updating.
>>
>>>      It sets up a basic 1:1 phsyical address to virtual address mapping;
>>>      turns the MMU on; enables branch prediction; activates any 
>>> integrated
>>> @@ -539,4 +541,9 @@ is_a15_a7:
>>>   page_tables:
>>>        PT7(0x1c0e)
>>> -#endif //#if defined(__ARM_ARCH_7A__) || __ARM_ARCH_PROFILE == 'A'
>>> +#elif  (__ARM_ARCH_PROFILE == 'M')
>>> +    /* On M-profile, call abort in case of hardfault: this causes 
>>> the simulator to
>>> +       abort execution instead of going into an infinite loop.  */
>>> +    .section .hardfault_handler_addr, "a"
>>> +    .word abort
>>> +#endif //#if defined(__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A')
>>> diff --git a/libgloss/arm/elf-mprofile-mps2.specs b/libgloss/arm/elf- 
>>> mprofile-mps2.specs
>>> new file mode 100644
>>> index 000000000..edaf71917
>>> --- /dev/null
>>> +++ b/libgloss/arm/elf-mprofile-mps2.specs
>>> @@ -0,0 +1,26 @@
>>> +# rdimon.specs
>>> +#
>>> +# Spec file for AArch32 M profile baremetal newlib with version 2 of
>>> +# the AngelAPI semi-hosting using the SVC trap instruction.
>>> +#
>>> +# This version supports extensibility through an extension mechanism.
>>> +
>>> +%rename link_gcc_c_sequence                rdimon_link_gcc_c_sequence
>>> +
>>> +%rename link old_link
>>> +
>>> +*link:
>>> +--section-start=.hardfault_handler_addr=0xc %(old_link)
>>> +
>>> +*rdimon_libc:
>>> +%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
>>> +
>>> +*rdimon_libgloss:
>>> +%{!specs=nano.specs:-lrdimon} %{specs=nano.specs:-lrdimon_nano}
>>> +
>>> +*link_gcc_c_sequence:
>>> +%(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) 
>>> %(rdimon_libgloss) --end-group
>>> +
>>> +*startfile:
>>> +crti%O%s crtbegin%O%s cpu-init/rdimon-aem.o%s %{!pg:rdimon-crt0%O%s} 
>>> %{pg:rdimon-crt0%O%s}
>>> +
>>
>
  
Richard Earnshaw June 25, 2026, 3:32 p.m. UTC | #4
This series is OK.

Thanks

R.

On 12/06/2026 16:53, Christophe Lyon wrote:
> After reaching a hardfault, the simulator enters an infinite loop
> unless we map the handler to 'abort'.
> 
> The patch adds this minimal setup for M-profile in
> libgloss/arm/cpu-init/rdimon-aem.S and introduces the new
> libgloss/arm/elf-mprofile-mps2.specs to add the mapping to the right
> memory address.
> 
> 2026-05-29  Andre Vieira <andre.simoesdiasvieira@arm.com>
> 	Christophe Lyon  <christophe.lyon@arm.com>
> 
> 	libgloss/
> 	* Makefile.in: Add entry for arm/mprofile-mps2.specs.
> 	* arm/Makefile.inc: Add entry for mprofile-mps2.specs.
> 	* arm/cpu-init/rdimon-aem.S: Update comment. Add hardfault
> 	handler.
> 	* arm/elf-mprofile-mps2.specs: New file.
> ---
>  libgloss/Makefile.in                 |  1 +
>  libgloss/arm/Makefile.inc            |  3 ++-
>  libgloss/arm/cpu-init/rdimon-aem.S   | 11 +++++++++--
>  libgloss/arm/elf-mprofile-mps2.specs | 26 ++++++++++++++++++++++++++
>  4 files changed, 38 insertions(+), 3 deletions(-)
>  create mode 100644 libgloss/arm/elf-mprofile-mps2.specs
> 
> diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in
> index 5146a7880..c03ea4e6b 100644
> --- a/libgloss/Makefile.in
> +++ b/libgloss/Makefile.in
> @@ -2255,6 +2255,7 @@ TEXINFO_TEX = ../texinfo/texinfo.tex
>  @CONFIG_ARM_TRUE@	arm/aprofile-validation-v2m.specs \
>  @CONFIG_ARM_TRUE@	arm/aprofile-ve-v2m.specs \
>  @CONFIG_ARM_TRUE@	arm/aprofile-ve.specs arm/pid.specs \
> +@CONFIG_ARM_TRUE@       arm/mprofile-mps2.specs \
>  @CONFIG_ARM_TRUE@	arm/iq80310.specs
>  @CONFIG_ARM_TRUE@arm_libgloss_linux_a_SOURCES = \
>  @CONFIG_ARM_TRUE@	arm/linux-syscalls0.c \
> diff --git a/libgloss/arm/Makefile.inc b/libgloss/arm/Makefile.inc
> index 41fce3c99..5c740edcb 100644
> --- a/libgloss/arm/Makefile.inc
> +++ b/libgloss/arm/Makefile.inc
> @@ -47,7 +47,8 @@ multilibtool_LIBRARIES += %D%/librdpmon.a
>  	%D%/aprofile-validation.specs \
>  	%D%/aprofile-validation-v2m.specs \
>  	%D%/aprofile-ve-v2m.specs \
> -	%D%/aprofile-ve.specs
> +	%D%/aprofile-ve.specs \
> +	%D%/mprofile-mps2.specs
>  multilibtool_DATA += \
>  	%D%/rdimon-crt0.o \
>  	%D%/rdimon-crt0-v2m.o
> diff --git a/libgloss/arm/cpu-init/rdimon-aem.S b/libgloss/arm/cpu-init/rdimon-aem.S
> index 2aacbeba9..c960924d4 100644
> --- a/libgloss/arm/cpu-init/rdimon-aem.S
> +++ b/libgloss/arm/cpu-init/rdimon-aem.S
> @@ -25,7 +25,9 @@
>  
>  /* This file gives a basic initialisation of a Cortex-A series core.  It is
>     the bare minimum required to get Cortex-A core running with a semihosting
> -   interface.
> +   interface.  For M-profile we only define a hardfault handler, required to
> +   prevent the simulator from entering into an infinite loop.  The comments
> +   below apply to A-profile only.
>  
>     It sets up a basic 1:1 phsyical address to virtual address mapping;
>     turns the MMU on; enables branch prediction; activates any integrated
> @@ -539,4 +541,9 @@ is_a15_a7:
>  page_tables:
>       PT7(0x1c0e)
>  
> -#endif //#if defined(__ARM_ARCH_7A__) || __ARM_ARCH_PROFILE == 'A'
> +#elif  (__ARM_ARCH_PROFILE == 'M')
> +    /* On M-profile, call abort in case of hardfault: this causes the simulator to
> +       abort execution instead of going into an infinite loop.  */
> +    .section .hardfault_handler_addr, "a"
> +    .word abort
> +#endif //#if defined(__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A')
> diff --git a/libgloss/arm/elf-mprofile-mps2.specs b/libgloss/arm/elf-mprofile-mps2.specs
> new file mode 100644
> index 000000000..edaf71917
> --- /dev/null
> +++ b/libgloss/arm/elf-mprofile-mps2.specs
> @@ -0,0 +1,26 @@
> +# rdimon.specs
> +#
> +# Spec file for AArch32 M profile baremetal newlib with version 2 of
> +# the AngelAPI semi-hosting using the SVC trap instruction.
> +#
> +# This version supports extensibility through an extension mechanism.
> +
> +%rename link_gcc_c_sequence                rdimon_link_gcc_c_sequence
> +
> +%rename link old_link
> +
> +*link:
> +--section-start=.hardfault_handler_addr=0xc %(old_link)
> +
> +*rdimon_libc:
> +%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
> +
> +*rdimon_libgloss:
> +%{!specs=nano.specs:-lrdimon} %{specs=nano.specs:-lrdimon_nano}
> +
> +*link_gcc_c_sequence:
> +%(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) %(rdimon_libgloss) --end-group
> +
> +*startfile:
> +crti%O%s crtbegin%O%s cpu-init/rdimon-aem.o%s %{!pg:rdimon-crt0%O%s} %{pg:rdimon-crt0%O%s}
> +
  

Patch

diff --git a/libgloss/Makefile.in b/libgloss/Makefile.in
index 5146a7880..c03ea4e6b 100644
--- a/libgloss/Makefile.in
+++ b/libgloss/Makefile.in
@@ -2255,6 +2255,7 @@  TEXINFO_TEX = ../texinfo/texinfo.tex
 @CONFIG_ARM_TRUE@	arm/aprofile-validation-v2m.specs \
 @CONFIG_ARM_TRUE@	arm/aprofile-ve-v2m.specs \
 @CONFIG_ARM_TRUE@	arm/aprofile-ve.specs arm/pid.specs \
+@CONFIG_ARM_TRUE@       arm/mprofile-mps2.specs \
 @CONFIG_ARM_TRUE@	arm/iq80310.specs
 @CONFIG_ARM_TRUE@arm_libgloss_linux_a_SOURCES = \
 @CONFIG_ARM_TRUE@	arm/linux-syscalls0.c \
diff --git a/libgloss/arm/Makefile.inc b/libgloss/arm/Makefile.inc
index 41fce3c99..5c740edcb 100644
--- a/libgloss/arm/Makefile.inc
+++ b/libgloss/arm/Makefile.inc
@@ -47,7 +47,8 @@  multilibtool_LIBRARIES += %D%/librdpmon.a
 	%D%/aprofile-validation.specs \
 	%D%/aprofile-validation-v2m.specs \
 	%D%/aprofile-ve-v2m.specs \
-	%D%/aprofile-ve.specs
+	%D%/aprofile-ve.specs \
+	%D%/mprofile-mps2.specs
 multilibtool_DATA += \
 	%D%/rdimon-crt0.o \
 	%D%/rdimon-crt0-v2m.o
diff --git a/libgloss/arm/cpu-init/rdimon-aem.S b/libgloss/arm/cpu-init/rdimon-aem.S
index 2aacbeba9..c960924d4 100644
--- a/libgloss/arm/cpu-init/rdimon-aem.S
+++ b/libgloss/arm/cpu-init/rdimon-aem.S
@@ -25,7 +25,9 @@ 
 
 /* This file gives a basic initialisation of a Cortex-A series core.  It is
    the bare minimum required to get Cortex-A core running with a semihosting
-   interface.
+   interface.  For M-profile we only define a hardfault handler, required to
+   prevent the simulator from entering into an infinite loop.  The comments
+   below apply to A-profile only.
 
    It sets up a basic 1:1 phsyical address to virtual address mapping;
    turns the MMU on; enables branch prediction; activates any integrated
@@ -539,4 +541,9 @@  is_a15_a7:
 page_tables:
      PT7(0x1c0e)
 
-#endif //#if defined(__ARM_ARCH_7A__) || __ARM_ARCH_PROFILE == 'A'
+#elif  (__ARM_ARCH_PROFILE == 'M')
+    /* On M-profile, call abort in case of hardfault: this causes the simulator to
+       abort execution instead of going into an infinite loop.  */
+    .section .hardfault_handler_addr, "a"
+    .word abort
+#endif //#if defined(__ARM_ARCH_7A__) || (__ARM_ARCH_PROFILE == 'A')
diff --git a/libgloss/arm/elf-mprofile-mps2.specs b/libgloss/arm/elf-mprofile-mps2.specs
new file mode 100644
index 000000000..edaf71917
--- /dev/null
+++ b/libgloss/arm/elf-mprofile-mps2.specs
@@ -0,0 +1,26 @@ 
+# rdimon.specs
+#
+# Spec file for AArch32 M profile baremetal newlib with version 2 of
+# the AngelAPI semi-hosting using the SVC trap instruction.
+#
+# This version supports extensibility through an extension mechanism.
+
+%rename link_gcc_c_sequence                rdimon_link_gcc_c_sequence
+
+%rename link old_link
+
+*link:
+--section-start=.hardfault_handler_addr=0xc %(old_link)
+
+*rdimon_libc:
+%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
+
+*rdimon_libgloss:
+%{!specs=nano.specs:-lrdimon} %{specs=nano.specs:-lrdimon_nano}
+
+*link_gcc_c_sequence:
+%(rdimon_link_gcc_c_sequence) --start-group %G %(rdimon_libc) %(rdimon_libgloss) --end-group
+
+*startfile:
+crti%O%s crtbegin%O%s cpu-init/rdimon-aem.o%s %{!pg:rdimon-crt0%O%s} %{pg:rdimon-crt0%O%s}
+