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

Eli Friedman via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 2 17:55:50 PDT 2021


We have to use blx for indirect calls; there's no other version of "bl" that takes a register operand.  (Well, technically, you can emulate a call using "mov lr, pc; mov pc, ip", but that's slower.)

-Eli

> -----Original Message-----
> From: cfe-dev <cfe-dev-bounces at lists.llvm.org> On Behalf Of valerij zaporogeci
> via cfe-dev
> Sent: Friday, July 2, 2021 4:11 PM
> To: David Spickett <david.spickett at linaro.org>
> Cc: cfe-dev at lists.llvm.org Developers <cfe-dev at lists.llvm.org>
> Subject: [EXT] Re: [cfe-dev] Q: ARM, why -marm is ignored
> 
> Thank you, David (and Eli). That really looks interesting, because if
> clang doesn't support mixing modes, it shouldn't use blx. right?
> However, looking at the image disassembly, reveals, that calling to
> the UEFI interfaces are being done through blx ip. :)
> 
> Maybe it's a common rule, to use blx instead of bl if the call is to
> something, whose exact mode of execution the compiler cannot know
> about?
> 
> In both cases, (clang and msvc), even though there are no options to
> tell the _compiler_ it's interworking, because they both target thumb
> only, the produced images are interwoking correct. :) I looked into
> disassembly of .obj files, both for msvc and clang, to see if there
> might be bl->blx exchange by the linker. there is no such. in the
> object files of both compilers, calling to UEFI interfaces are done
> through blx. interesting, that MachineType of msvc .obj files are set
> to 1C4 (it's link.exe, who changes it to 1C2). finally, a quick check
> for a msvc produced "hello world" windows console program, linked
> against msvcrt.dll shows, that the calls to imported functions are
> done through blx.
> 
> 2021-07-02 12:37 GMT+03:00, David Spickett <david.spickett at linaro.org>:
> >> 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.
> >
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


More information about the cfe-dev mailing list