[cfe-dev] Q: ARM, why -marm is ignored

David Spickett via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 2 02:37:40 PDT 2021


> As of the calling convention, it's basically AAPCS:

I thought a linux but coff triple would work for this but alas:

$ ../build-llvm-aarch64/bin/clang --target=armv7a-unkonwn-linux-coff
-c /tmp/test.c -o /tmp/test.o
clang-13: warning: unknown platform, assuming -mfloat-abi=soft
clang-13: warning: unknown platform, assuming -mfloat-abi=soft
clang-13: warning: unknown platform, assuming -mfloat-abi=soft
fatal error: error in backend: Cannot initialize MC for non-Windows
COFF object files.

> • Calls to UEFI defined interfaces must be done assuming that the target code requires
> the ARM instruction set state. Images are free to use other instruction set states except
> when invoking UEFI interfaces.

> I use MSVC, which generates Thumb, but when being told about /subsystem:EFI_APPLICATION at least, sets 1C2 MachineType

My only worry there is that the Windows ABI assumes Thumb only
(https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions?view=msvc-160).
However if they specifically support EFI then there's probably some
special case for that, where you need the interworking.

Just from the llvm source there's a few places where interworking is
mentioned. For example we don't emit "__THUMB_INTERWORK__" for Windows
triples. That said the comment above is mysterious:
// FIXME: It's more complicated than this and we don't really support
// interworking.

A very quick test https://godbolt.org/z/18oWPWzsK uses "bl" not "blx"
that you'd want for interworking. If hex editing the machine type
works then great but if you find it failing when you're calling these
interfaces that could be the reason. (perhaps if you link against
functions in another object marked as arm, the linker will convert
this to a blx regardless of the windows triple?)

On Thu, 1 Jul 2021 at 23:53, valerij zaporogeci <vlrzprgts at gmail.com> wrote:
>
> > > maybe there is another target, better suitable for a UEFI OSL
> >
> > Can you describe (or link to docs) what this means? What does a UEFI
> > compatible executable involve, what format would it be, does it have
> > to use Windows calling conventions, that sort of thing. (I'm not
> > familiar with this area myself)
>
> The UEFI specification says (section 2.1.1 in 2.4.Errata_B, yes, it's
> old, but I bet, it's the same in the newest one - compatibility), it
> wants MachineType field for ARM32:
> > #define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01C2
>
> and explains:
>
> > This image type is chosen to enable UEFI images to contain Thumb and Thumb2
> > instructions while defining the EFI interfaces themselves to be in ARM mode.
>
> As of the calling convention, it's basically AAPCS:
> > 2.3.5.3 Detailed Calling Convention
> > The base calling convention for the ARM binding is defined here:
> >   Procedure Call Standard for the ARM Architecture V2.06 (or later)
> > http://infocenter.arm.com/
> > This binding further constrains the calling convention in these ways:
> > • Calls to UEFI defined interfaces must be done assuming that the target code requires
> > the ARM instruction set state. Images are free to use other instruction set states except
> > when invoking UEFI interfaces.
> > • Floating point, SIMD, vector operations and other instruction set extensions must not
> > be used.
> > • Only little endian operation is supported.
> > • The stack will maintain 8 byte alignment as described in the AAPCS for public
> > interfaces.
>
> So, the loader can be compiled to the Thumb instructions, but it has
> to be "interworking" aware, and, as an indication of that, it should
> use 1C2 machine type. And you know, what's funny, I just hexedited the
> clang compiled image, changing MachineType from 1C4 to 1C2 and it
> worked. :) without this, FW rejected to start it. So, if this is going
> to be this optimistic, then this is the only change to be needed to
> make it suitable for UEFI. Of course, pity, there is no way to tell
> clang generate ARM only code.
>
> >> as said in the title, gcc's -marm option (that is not reported as not recognized) gets
> >> absolutely ignored.
> >
> > The title I assume refers to clang. Do you mean gcc here, or clang?
> > Would be good to compare the results if gcc is doing something
> > different. (that doesn't make either correct just more data points)
>
> yes, clang, I just hoped, that passing to it this gcc option, would
> make it generate ARM code fpr Windows targets. naivety. :) gcc
> probably does generate ARM code in this case, but gcc can't do PE, so
> I didn't use it. I use MSVC, which generates Thumb, but when being
> told about /subsystem:EFI_APPLICATION at least, sets 1C2 MachineType.
>
> Thank you for your help.


More information about the cfe-dev mailing list