On 11 July 2016 at 16:01, Shi, Steven <steven....@intel.com> wrote:

> Hi Ard,
> >
> > What I am still missing here is an explanation of the
> > benefit/necessity of using PIE. What does it give us that we don't
> > already have? How is it different from simply linking a shared ELF
> > object and running GenFw on that?
> >
> [Steven]:
> Using PIE is necessary, at least for x86_64, because it can guarantee the
> 64bits small code model (-mcmodel=small) code can really safe to run at
> anywhere in 64bits address range. If no PIE, the small code binary will
> have trouble when run above 4GB address. Uefi firmware (especially in
> server platform) have the cases to run code above 4GB address, so I have to
> enable PIE with small code model.
> Let me give you a real example, at the beginning of GCC5 and CLANG38
> enabling, I didn't enable the PIE in fact, then I meet a weird issue on
> OVMF X64 firmware (Qemu), which is the OVMF 64bits Sec can jmp to wrong
> address. I attach my debugging email, and in that email, you can see it is
> because the OVMF 64bits Sec (small code) run at 0xfffffffffffcxxxx which is
> very high address above 4GB. If you like, you can also see how I discuss
> this issue in llvm community in the thread: How to debug if LTO generate
> wrong code?(http://lists.llvm.org/pipermail/llvm-dev/2016-May/100298.html)
>
> For the PIE/PIC and code model relation, below article can help you
> understand it:
> http://eli.thegreenplace.net/2012/01/03/understanding-the-x64-code-models
>
>
​If the cost of the large model is due to its use of 64-bit quantities, how
is this any better with PIC/PIE binaries? The primary difference is that
you now have a Global Offset Table (GOT) entry for all symbol references,
which also contains 64-bit values. Do you have any numbers comparing the
large model to PIC/PIE? You should also be aware that GCC's default
visibility setting results in all symbol references to go via the GOT,
which may not be what you want. (This is required for ELF symbol
preemption, which does not make sense in a PIE executable, but GCC does not
know about that when it creates the .o from the .c). Also, do you have any
comparisons for the size of the .reloc section?
​


> OK, then someone might continue to ask why we need small code model and
> not to use large code model to guarantee the 64bits address safe? I see
> both GCC49_AARCH64 and CLANG35_AARCH64 already enable the small code, so I
> believe you know the answer: the large code model is VERY expensive for
> 64bits addressing in code size view, and every 64bits code and data address
> cost full 8 bytes in large code model. So we prefer to use small code model
> for firmware binary.
>
>
​I see. AArch64 is a bit different, but the general idea is the same.
AArch64 has a tiny model (1 MB max relative offset), small model (4 GB max
relative offset) and large model (absolute addressing). Worth to note is
that all EDK2 modules that we use on AArch64 can be built with the tiny
model, except for the UEFI shell built in DEBUG mode.
​


> It is worthy to mention that PIE/PIC can increase code size in fact,
> because more code need to make the addressing position independent. But
> PIE/PIC can guarantee the small code model is safe in 64bits anywhere, and
> the small code can decrease the 64bits code size sharply. So the PIE+Small
> code overall can generate smaller code size than large code. A tricky
> scenario is that if you can make sure your 64bits code only run under 4GB
> address, you can disable PIE but only enable small code model, then you
> will get even smaller 64bits binary.
>
> > OK, so how about we put the following line in GccBase.lds
> >
> >   .rela : { *(.rel .rela)
> >
> > and check for SHT_PROGBITS sections explicitly in both IsTextShdr and
> > IsDataShdr (or at least filter out SHT_RELA sections)?
> >
> [Steven]: it sounds good to me. Current GccBase.lds already has the .rela
> define as below. Will use the section Type in IsTextShdr and IsDataShdr to
> check SHT_RELA.
>
>   .rela ALIGN(CONSTANT(COMMONPAGESIZE)) : {
>     *(.rela .rela.*)
>   }
>
>
​OK. For compatibility with ELF32, you should probably add *(.rel .rel.*)
here as well.
​


> >
> > BTW I wonder if you still need --emit-relocs in the PIE case, since
> > all relocations you need will be in the SHF_ALLOC .rela section, and
> > the per-section .rela sections (which GenFw normally uses) are
> > redundant.
> >
> [Steven]: Yes. I use -q (--emit-relocs) in current GCC5 and CLANG38 link
> flags. My understanding is the --emit-relocs is to let the whole binary
> fully linked, and it is mandatory for Uefi binary.
>
>
​I think y
ou should be cautious here.
​ U
sing -q and -pie at the same time could result in duplicate PE/COFF
relocations. The PIE .rela section ​(
​the one ​
with the SHF_ALLOC flag set) will contain the same information as the
various .rela.xxx entries that are emitted due to the -q argument, and I
don't think GenFw understands the difference
​, so it may end up emitting each PE/COFF relocation ​twice.


> >
> > I don't think we need to add anything, and checking for SHT_RELA (as I
> > suggested above) should be sufficient. However, could you please keep
> > the ELF32 and ELF64 in sync?
> >
> [Steven]: OK. Will sync the ELF32 with ELF64.
>
>
​Thanks,
Ard.
​
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to