New binutils 2.30 rejects `svc 0` (as part of `asm volatile(...)` in C++ source file): -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- arm-none-eabi-g++ -Wall -Wextra -Wshadow -std=gnu++11 -mcpu=cortex-m0 -mthumb -g -ggdb3 -O2 -fno-use-cxa-atexit -ffunction-sections -fdata-sections -fno-rtti -fno-exceptions -Ioutput/include -Iinclude -Isource/architecture/ARM/ARMv6-M-ARMv7-M/include -Isource/architecture/ARM/ARMv6-M-ARMv7-M/external/CMSIS -Isource/chip/STM32/include -Isource/chip/STM32/STM32F0/include -Isource/chip/STM32/peripherals/GPIOv2/include -Isource/chip/STM32/peripherals/SPIv2/include -Isource/chip/STM32/peripherals/USARTv2/include -Isource/chip/STM32/STM32F0/external/CMSIS-STM32F0 -MD -MP -c source/architecture/ARM/ARMv6-M-ARMv7-M/ARMv6-M-ARMv7-M-supervisorCall.cpp -o output/source/architecture/ARM/ARMv6-M-ARMv7-M/ARMv6-M-ARMv7-M-supervisorCall.o /tmp/cchwMvG1.s: Assembler messages: /tmp/cchwMvG1.s:41: Error: SVC is not permitted on this architecture make: *** [Makefile:261: output/source/architecture/ARM/ARMv6-M-ARMv7-M/ARMv6-M-ARMv7-M-supervisorCall.o] Error 1 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- This code was accepted in previous binutils (for years). SVC is listed with no notes about any special conditions in: - Thumb ® 16-bit Instruction Set Quick Reference Card - ARMv6-M Architecture Reference Manual Additionally "ARMv6-M Architecture Reference Manual" says ("A4.9 Exception-generating instructions"): -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- In an ARMv6-M implementation that does not include the Unprivileged/Privileged Extension, execution is always privileged. However in such an implementation, application code might use supervisor calls to maintain a software hierarchy with a system kernel. -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- Adding `-march=armv6s-m` to the compilation flags makes the error go away, but I don't think that requiring it is a good solution. Related problems: https://sourceware.org/bugzilla/show_bug.cgi?id=12296 https://bugs.launchpad.net/gcc-arm-embedded/+bug/1449610
I think the cause of the problem is this change - https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=173205ca3356cab0590c2debaac97107fb9a7fcd
Hi Freddie, I am unable to reproduce this problem. :-( Are you able to capture an assembler input file and command line that I could try out locally ? Cheers Nick
Hmmm... It seems that the problem is not entirely in GAS, but in GCC 8 (RC) as well... With GCC 7.3.0 and most recent binutils everything works fine. With GCC 8.0.1 20180427: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- $ cat svc.cpp __attribute__ ((naked)) int supervisorCall(int (& function)(int, int, int, int), const int argument1, const int argument2, const int argument3, const int argument4) { asm volatile ( " mov r12, r0 \n" " ldr r0, [sp] \n" " svc 0 \n" " \n" " bx lr \n" ); __builtin_unreachable(); // suppress warnings (void)function; (void)argument1; (void)argument2; (void)argument3; (void)argument4; } $ arm-none-eabi-g++ -c svc.cpp -mcpu=cortex-m0 -save-temps svc.s: Assembler messages: svc.s:31: Error: SVC is not permitted on this architecture $ diff -u svc-7.s svc.s --- svc-7.s 2018-05-01 20:14:09.031910734 +0200 +++ svc.s 2018-05-01 20:16:36.751143427 +0200 @@ -12,6 +12,7 @@ .text .align 1 .global _Z14supervisorCallRFiiiiiEiiii + .arch armv6-m .syntax unified .code 16 .thumb_func @@ -37,4 +38,4 @@ .cantunwind .fnend .size _Z14supervisorCallRFiiiiiEiiii, .-_Z14supervisorCallRFiiiiiEiiii - .ident "GCC: (bleeding-edge-toolchain) 7.3.0" + .ident "GCC: (bleeding-edge-toolchain) 8.0.1 20180427 (prerelease)" $ cat svc.s .cpu cortex-m0 .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 1 .eabi_attribute 30, 6 .eabi_attribute 34, 0 .eabi_attribute 18, 4 .file "svc.cpp" .text .align 1 .global _Z14supervisorCallRFiiiiiEiiii .arch armv6-m .syntax unified .code 16 .thumb_func .fpu softvfp .type _Z14supervisorCallRFiiiiiEiiii, %function _Z14supervisorCallRFiiiiiEiiii: .fnstart .LFB0: @ Naked Function: prologue and epilogue provided by programmer. @ args = 4, pretend = 0, frame = 0 @ frame_needed = 1, uses_anonymous_args = 0 .syntax divided @ 12 "svc.cpp" 1 mov r12, r0 ldr r0, [sp] svc 0 bx lr @ 0 "" 2 .thumb .syntax unified .cantunwind .fnend .size _Z14supervisorCallRFiiiiiEiiii, .-_Z14supervisorCallRFiiiiiEiiii .ident "GCC: (bleeding-edge-toolchain) 8.0.1 20180427 (prerelease)" -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- (svc-7.s is a temp file generated with GCC 7.3.0) So new GCC adds explicit arch info - `.arch armv6-m`. The most simple test case: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- $ echo 'svc 0' > /tmp/just-svc.s $ arm-none-eabi-as -mcpu=cortex-m0 just-svc.s $ arm-none-eabi-as -mcpu=cortex-m0 -march=armv6-m just-svc.s $ arm-none-eabi-as -march=armv6-m just-svc.s just-svc.s: Assembler messages: just-svc.s:1: Error: SVC is not permitted on this architecture -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- So it seems that if you have both `-mcpu=cortex-m0 -march=armv6-m` then GAS has no problem with that. However if both CPU and ARCH are specified with directives in the file, then GAS doesn't like this: -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- $ cat svc-directives.s .cpu cortex-m0 .arch armv6-m .syntax unified .thumb svc 0 $ arm-none-eabi-as svc-directives.s svc-directives.s: Assembler messages: svc-directives.s:5: Error: SVC is not permitted on this architecture -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- >8 -- I still think all these GAS errors are wrong, as "ARMv6-M Architecture Reference Manual" says SVC is permitted even if not implemented in the core. Do you think I should file a bug report for GCC too?
Hi Freddie, > Hmmm... It seems that the problem is not entirely in GAS, but in GCC 8 (RC) > as well... Actually, I think that you have found a separate gas bug^H^H feature... > So it seems that if you have both `-mcpu=cortex-m0 -march=armv6-m` then GAS > has no problem with that. > However if both CPU and ARCH are specified with > directives in the file, then GAS doesn't like this: Right - it turns out that command line options are additive, so if you specify -march=armv6-m -mcpu=cortx-m0 you get the features of both the architecture and cpu enabled, even if they are not the same. (This also applies if the options are specified in the opposite order). But - directives inside the assembler source file override any previous directives or command line options. So if you have: .cpu cortex-m0 .arch armv6-m then you *only* get the features of the V6M architecture and not any other features that might be present in the cortex-m0. The other important point to note here is that the assembler's "armv6-m" architecture does *not* support the SVC instruction. In order to support that you must use the "armv6s-m" architecture. The "s" in that string refers to the OS extension to the base V6M architecture, which in this case means the SVC instruction. Note - the assembler does know that the cortex-m0 supports the SVC instruction, but that is because internally it has a table that says that the cortex-m0 uses the armv6s-m architecture. This explains why your svc-directive.s test fails to assemble. It has the .arch directive after the .cpu directive and it uses the wrong architecture name. With regard to the "ARMv6-M Architecture Reference Manual" entry: In an ARMv6-M implementation that does not include the Unprivileged/ Privileged Extension, execution is always privileged. However in such an implementation, application code might use supervisor calls to maintain a software hierarchy with a system kernel. This does not, to me, mean that the SVC instruction *must* be supported. Rather it says that if the SVC instruction is present in machine code that is running on a v6-M implementation that does not separate privileged from unprivileged execution then this should be permitted. However, I did find this document online, the "Cortex-M0 Devices Generic User Guide", which clearly shows that the SVC instruction is supported: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0432c/CHDCICDF.html So all in all, I think that the assembler is not, technically, wrong. But it is rather confusing in its behaviour. > Do you think I should file a bug report for GCC too? Yes - for a -mcpu=cortex-m0 gcc command line option gcc should be generating a ".arch armv6s-m" directive and not a ".arch armv6-m" directive. (This presumably applies to other cortex-m?? variants as well, although I have not checked). Alternatively it should just generate a .cpu directive and no ".arch" directive, and leave it up to the assembler to divine the architecture involved. Cheers Nick
> Right - it turns out that command line options are additive, so if you specify > -march=armv6-m -mcpu=cortx-m0 you get the features of both the architecture and cpu enabled, even if they are not the same. (This also applies if the options are specified in the opposite order). > > But - directives inside the assembler source file override any previous directives or command line options. So I guess this could be treated as a GAS bug, right? Should I file a separate report or maybe you'd just edit the description of this one? > Yes - for a -mcpu=cortex-m0 gcc command line option gcc should be generating a ".arch armv6s-m" directive and not a ".arch armv6-m" directive. (This presumably applies to other cortex-m?? variants as well, although I have not checked). Alternatively it should just generate a .cpu directive and no ".arch" directive, and leave it up to the assembler to divine the architecture involved. Here's the relevant GCC bug - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85606
Hi Freddie, > > Right - it turns out that command line options are additive, so if you specify > > -march=armv6-m -mcpu=cortx-m0 you get the features of both the architecture and cpu enabled, even if they are not the same. (This also applies if the options are specified in the opposite order). > > > > But - directives inside the assembler source file override any previous directives or command line options. > > So I guess this could be treated as a GAS bug, right? Should I file a > separate report or maybe you'd just edit the description of this one? Please file a separate one. (Although I suspect that all that will happen is that the behaviour will be documented so that it is then considered "correct"). Cheers Nick