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

valerij zaporogeci via cfe-dev cfe-dev at lists.llvm.org
Fri Jul 2 19:52:38 PDT 2021


Thank you!

2021-07-03 5:01 GMT+03:00, Eli Friedman <efriedma at quicinc.com>:
> Easy as in "easy to change the source code of the linker".  See
> https://github.com/llvm/llvm-project/blob/af331e82845523751d39193ae657ca4f20ba1576/lld/COFF/Writer.cpp#L1355
> . Just add a check "if (config->subsystem ==
> COFF::IMAGE_SUBSYSTEM_EFI_APPLICATION && config->machine == ARMNT)" or
> something like that.
>
> -Eli
>
>> -----Original Message-----
>> From: valerij zaporogeci <vlrzprgts at gmail.com>
>> Sent: Friday, July 2, 2021 6:17 PM
>> To: Eli Friedman <efriedma at quicinc.com>
>> Cc: David Spickett <david.spickett at linaro.org>; cfe-dev at lists.llvm.org
>> Subject: [EXT] Re: [cfe-dev] Q: ARM, why -marm is ignored
>>
>> Indeed! :D I am not that familiar with ARM ISA. but it makes sense and
>> is not a coincidence, probably, that there is only blx reg. because
>> having another bl reg, that wouldn't understand mode switch and fail,
>> whereas instructions, directly modifying pc don't fail and do switch,
>> would be alogical and redundant. Thank you for your help, now it's
>> clear. btw, you said, it should be easy to teach lld-link to set
>> MachineType to 1C2. is it really doable at the option setting level or
>> it's "easy" as in "easy to change the source code of the linker"? :)
>>
>> 2021-07-03 3:55 GMT+03:00, Eli Friedman <efriedma at quicinc.com>:
>> > 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