On Sat, 31 Jul 2021 at 21:08, Marvin Häuser <mhaeu...@posteo.de> wrote: > > On 23.07.21 16:34, Ard Biesheuvel wrote: > > On Fri, 23 Jul 2021 at 16:27, Marvin Häuser <mhaeu...@posteo.de> wrote: > >> > >> > >> On 23.07.21 16:09, Ard Biesheuvel wrote: > >>> On Fri, 23 Jul 2021 at 12:47, Marvin Häuser <mhaeu...@posteo.de> wrote: > >>>> On 23.07.21 12:13, Ard Biesheuvel wrote: > >>>>> On Fri, 23 Jul 2021 at 11:55, Marvin Häuser <mhaeu...@posteo.de> wrote: > > ... > >>>>>> 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? > >> Do you maybe have one final comment regarding that second question, > >> please? :) > > The RELA section is not converted into PE/COFF relocations. This would > > not achieve a lot, given that no prior PE/COFF loader exists to > > process them. There is a snippet of asm code in the startup code that > > processes the R_AARCH64_RELATIVE relocation entries before calling > > into C code. > > I searched for said ASM code till my fingers fell asleep and at last > found this: > https://github.com/tianocore/edk2/commit/b16fd231f6d8124fa05a0f086840934b8709faf9#diff-3d563cc4775c7720900f4895bf619eed06291044aaa277fcc57eddc7618351a1L12-R148 > > If I understand the commit message correctly, it is basically "pray the > C code does not use globals at all", which is fair enough, so maybe I > should document this in my proposed new library? I trust that this is > enough of a constraint for both ARM and AArch64, because I do not know > them at all. >
The C code can use globals, but not global pointer variables. But you are right, this is not very robust at all. > What worries me is that StandaloneMmCore has no such ASM entry point at > all and instead it's just executing C directly. Also, it is not passed > the "-fno-jump-tables" flag that is commented to be important in the > commit linked above. > This is because the StandaloneMmCore is built with -fpie, which already implies -fno-jump-tables, although I suppose this may not offer complete coverage for BASE libraries that are pulled into the link. > Best regards, > Marvin > > > This also gives us the guarantee that no GOT indirections are > > dereferenced, given that our asm code simply does not do that. > > > >> Let's drop "GOT" and make it "any instruction that requires prior > >> relocation to function correctly". > >> > > The thing to keep in mind here is that R_AARCH64_RELATIVE relocations > > never target instructions, but only memory locations that carry > > absolute addresses. This could be locations in .rodata or .data > > (global vars carrying pointer values), or GOT entries. > > > >>>>> 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. > >>>> Hmm, the GCC docs say a GOT is used for "all constant addresses" (I took > >>>> it as "absolute"?), it is kind of vague. I understood it this way: > >>>> 1) no-pie emits relocations that can target the .text and .data sections > >>>> for instructions that embed and variables that hold an absolute address > >>>> (I thought this was RELA?) > >>>> 2) pie emits a GOT such that there are no relocations as described in > >>>> 1), because all absolute addresses are indirected by GOT (just GOT > >>>> references are relocated) > >>>> > >>> Correct. And this works really well for shared libraries, where all > >>> text and data sections can be shared between processes, as they will > >>> not be modified by the loader. All locations targeted by relocations > >>> will be nicely lumped together in the GOT. > >>> > >>> However, for bare metal style programs, there is no sharing, and there > >>> is no advantage to lumping anything together. It is much better to use > >>> relative references where possible, and simply apply relocations > >>> wherever needed across the text and data sections, > >>> > >>>> If I understood the process right, but the term (GOT) is wrong, sorry, > >>>> that is what I gathered from the docs. :) > >>>> I have a x86 + PE background, so ARM + ELF is a bit of a learning > >>>> curve... > >>>> > >>> The GOT is a special data structure used for implicit variable > >>> accesses, i.e., global vars used in the code. Statically initialized > >>> pointer variables are the other category, which are not code, and for > >>> which the same considerations do not apply, given that the right value > >>> simply needs to be stored in the variable before the program starts. > >>> > >>>>> 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. > >>>> And this is not forced by whatever table -fpie uses, as per my > >>>> understanding above? > >>>> > >>> The selection of 'code model' as it is called is controlled by GCC's > >>> -mcmodel= argument, which defaults to 'small' on AArch64, regardless > >>> of whether you use PIC/PIE or not. > >> Aha, makes sense, thanks! > >> > >> Best regards, > >> Marvin > >> > >>>>>>>> “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? > >>>> That is what I meant to imply with the middle question (well, not > >>>> necessarily "lazy", for ARM there simply seems to not be any reason to > >>>> distinguish if the environments are fully separate), just wanted to make > >>>> sure I understand what the code does before modifying it. > >>>> > >>>> Thank you again! > >>>> > >>>> Best regards, > >>>> Marvin > >>>> > >>>>>>>> “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 (#78468): https://edk2.groups.io/g/devel/message/78468 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] -=-=-=-=-=-=-=-=-=-=-=-