On Fri, 23 Jul 2021 at 11:55, Marvin Häuser <mhaeu...@posteo.de> wrote: > > On 22.07.21 17:14, Ard Biesheuvel wrote: > > On Thu, 22 Jul 2021 at 16:54, Bret Barkelew<bret.barke...@microsoft.com> > > wrote: > >> Expanding audience to the full dev list… > >> > >> See below… > >> > >> > >> > >> - Bret > >> > >> > >> > >> From: Thomas Abraham > >> Sent: Wednesday, July 7, 2021 11:07 PM > >> To: Bret Barkelew; Ard Biesheuvel (TianoCore); Lindholm, Leif; Laszlo > >> Ersek; Marvin Häuser; Sami Mujawar > >> Cc: nd > >> Subject: [EXTERNAL] RE: ArmVirt and Self-Updating Code > >> > >> > >> > >> + Sami > >> > >> > >> > >> From: Bret Barkelew<bret.barke...@microsoft.com> > >> Sent: Thursday, July 8, 2021 11:05 AM > >> To: Thomas Abraham<thomas.abra...@arm.com>; Ard Biesheuvel > >> (TianoCore)<ardb+tianoc...@kernel.org>; Lindholm, Leif<l...@nuviainc.com>; > >> Laszlo Ersek<ler...@redhat.com>; Marvin Häuser<mhaeu...@posteo.de> > >> Subject: ArmVirt and Self-Updating Code > >> > >> > >> > >> All, > >> > >> > >> > >> Marvin asked me a question on the UEFI Talkbox Discord that’s a little > >> beyond my ken… > >> > >> > >> > >> “There is self-relocating code in ArmVirtPkg: > >> > >> https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85b2cff1aaf/ArmVirtPkg/PrePi/PrePi.c#L133-L165 > >> > >> According to comments in the ASM, it seems like this is for Linux-based > >> RAM boot (I saw further stuff for KVM, so it makes sense I guess?). It > >> seems unfortunate it cannot be mapped into a known address range so that > >> self-relocation is not necessary, but that's out of my scope to understand. > >> > > "Mapping" implies that the MMU is on, but this code boots with the MMU > > off. Unlike x86, ARM does not define any physical address ranges that > > are guaranteed to be backed by DRAM, so a portable image either needs > > to be fully position independent, or carry the metadata it needs to > > relocate itself as it is invoked. > > And I understood it right that the idea is to use "-fpie" to > 1) have all control flow instructions be position-independent (i.e. > jumps, calls, etc; ARM docs don't spill it out, but vaguely imply this > always is possible?), and
The primary reason to use -fpie and PIE linking is to ensure that the resulting ELF executable contains a RELA section that describes every location in the binary where a memory address is stored that needs to be updated according to the actual placement in memory. The side effect of -fpie is that position independent global references are emitted (i.e., ADRP/ADD instructions which are relative to the program counter). However, the AArch64 compiler uses those by default anyway, so for this it is not strictly needed. > 2) emit a GOT, which ends up being converted to PE/COFF Relocations (-> > self-relocation), for global data that cannot be referenced relatively? > Is there any way to know/force that no symbol in GOT is accessed up > until the end of the self-relocation process? > It is not really a GOT. Actually, a GOT is undesirable, as it forces global variables to be referenced via an absolute address, even when a relative reference could be used. For instance, a statically initialized pointer always carries an absolute address, and so it always needs an entry in the RELA table E.g., int foo = 10; // external linkage static int *bar = &foo; In this case, there is no way to use relative addressing because the address of foo is taken at build time. However, if bar would be something like static int *bar() { return &foo; } the address is only taken at runtime, and the compiler can use a relative reference instead, and no RELA entry is needed. With a GOT, we force the compiler to allocate a variable that holds the absolute address, which we would prefer to avoid. > >> “Now, StandaloneMmPkg has similar (self-)relocation code > >> too:https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85b2cff1aaf/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/StandaloneMmCoreEntryPoint.c#L379-L386 > >> > >> Because I cannot find such elsewhere, I assume it must be for the same ARM > >> virtualised environment as above. > > No. > > > >> The binary it applies the Relocations to is documented to be the > >> Standalone MM core, but in fact SecCore is located: > >> > >> https://github.com/tianocore/edk2/blob/17143c4837393d42c484b42d1789b85b2cff1aaf/StandaloneMmPkg/Library/StandaloneMmCoreEntryPoint/AArch64/SetPermissions.c#L131-L158 > > As per your comments below, I think SecCore should not be located here. > Is the Standalone MM core of *type* SecCore in the FFS (without *being* > SecCore)? This confused me the most. > If the FFS SecCore section type is used here, it does not mean that the image is a SEC image in the strict PI sense. Perhaps we were just too lazy to add a new type to the FFS spec? > >> “This yields the following questions to me: > >> > >> 1) What even invokes Standalone MM on ARM? It is documented it is spawned > >> during SEC, but I could not find any actual invocation. > >> > > It is not spawned by the normal world code that runs UEFI. It is a > > secure world component that runs in a completely different execution > > context (TrustZone). The code does run with the MMU enabled from the > > start, but running from an a priori fixed offset was considered to be > > a security hazard, so we added self relocation support. > > > > The alternative would have been to add metadata to the StMmCore > > component that can be interpreted by the secure world component that > > loads it, but this would go beyond any existing specs, and make > > portability more problematic. > > > >> 2) Why does Standalone MM (self-)relocation locate SecCore? Should it not > >> already have been relocated with the code from ArmPlatformPkg? Is > >> Standalone MM embedded into ARM SecCore? > >> > > No and no. Standalone MM has nothing to do with the code that runs as > > part of UEFI itself. ArmPlatformPkg is completely separate from > > StandaloneMmPkg. > > > >> 3) Why is SecCore the only module relocated? Are all others guaranteed to > >> be "properly" loaded? > >> > > SecCore contains a PE/COFF loader, so all subsequent modules are > > loaded normally. This is similar to the ArmVirtQemuKernel > > self-relocating SEC module, which only relocates itself in this > > manner, and relies on standard PE/COFF metadata for loading other > > modules. > > Interesting... this definitely is vastly different from the x86 side of > things. I think most things became very clear. Thanks a lot! > > >> 4) Is there maybe some high-level documented about the ARM boot flow? It > >> seems to be significantly different from the x86 routes quite vastly.” > >> > > trustedfirmware.org may have some useful documentation. > > I'll check it some time, hopefully this weekend. Thanks! > My pleasure. -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#78128): https://edk2.groups.io/g/devel/message/78128 Mute This Topic: https://groups.io/mt/84380729/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-