[Bug 970] #pragma visibility hidden in MdePkg/Include/X64/ProcessorBind.h is misconceived #pragma


bugzilla-daemon at bugzilla.tianocore.org...
 

https://bugzilla.tianocore.org/show_bug.cgi?id=970

--- Comment #6 from Ard Biesheuvel <ard.biesheuvel(a)linaro.org> ---
(In reply to zenith432 from comment #4)
3a8: ff 35 00 00 00 00 pushq 0x0(%rip) # 3ae
<DhcpSendMessage+0x3ae>
3aa: R_X86_64_GOTPCREL DhcpDummyExtFree-0x4
This GOTPCREL can't be transformed because it's a pushq instruction. Only a
limited set of x86_64 opcodes with GOTPCREL relocations can be transformed.
They are summarized in appendix B.2 of

https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf

Nevertheless, you are right about the 2nd part...

3a1: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax # 3a8
<DhcpSendMessage+0x3a8>
3a4: R_X86_64_PC32 DhcpDummyExtFree-0x4
and after some tweaking of the options I found it's because of the -fpie as
opposed to -fpic.
Same GCC 8.1.1 on Fedora as my first post.
Same a.c sample as my first post.

gcc -fpic -Os -c -o a.o a.c

0000000000000000 <f>:
0: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 7 <f+0x7>
3: R_X86_64_REX_GOTPCRELX a-0x4
7: 8b 38 mov (%rax),%edi
9: e9 00 00 00 00 jmpq e <f+0xe>
a: R_X86_64_PLT32 g-0x4

gcc -fpie -Os -c -o a.o a.c

0000000000000000 <f>:
0: 8b 3d 00 00 00 00 mov 0x0(%rip),%edi # 6 <f+0x6>
2: R_X86_64_PC32 a-0x4
6: e9 00 00 00 00 jmpq b <f+0xb>
7: R_X86_64_PLT32 g-0x4

This is what GCC 8.1.1 documentation has to say about -fpie

-fpie -fPIE
These options are similar to ‘-fpic’ and ‘-fPIC’, but generate position
independent code can be only linked into executables. Usually these options
are used when ‘-pie’ GCC option is used during linking. ‘-fpie’ and ‘-fPIE’
both define the macros __pie__ and __PIE__. The macros have the value 1 for
‘-fpie’ and 2 for ‘-fPIE’.

Go figure....

- On one hand, just because code "can only be linked into executables",
doesn't mean it's not going to try to access external symbols defined in
dynamic libraries built from code that was not "only linkable into
executables".

- On the other hand, if using -fpie makes GCC assume none of the global
symbols need to be accessible to dynamic linking - then why does it ever
generate GOTPCREL-type relocations when -fvisibility=default? The -fpie
should be enough to eliminate all GOTPCREL, and in the small program a.c it
is enough! But in large EDK2 code GCC still occasionally emits GOTPCREL,
and nevertheless disappears it if -fvisibility=hidden.
I agree. The reasoning here seems a bit off, and
So you're right, the visilibity should be left hidden for GCC/ELF. However,
this doesn't affect MACHO, and I'm not sure clang+ELF suffers from these
quirks either (don't have it set up).

I have another, probably better idea.
How about I add code to GenFw to handle the various flavors of GOTPCREL
defined by ELF (latest ABI spec has three). I think they can be correctly
transformed to COFF, because the GOT is not discarded (it is put in .text
segment by ld script). I'll check if there are other types of ELF
relocation that can be converted to COFF but are not handled by GenFw today.
Then I'll submit this. If this is done, then GenFw will no longer be as
vulnerable to being broken by ELF relocations.
As you may be aware, the Tianocore crowd are obsessed with binary size, and so
even if GenFw deals with the relocations correctly, you should still expect
some pushback to removing this #pragma if it results in a code size increase
for non-LTO builds.

That said, I think it would be very useful to teach GenFw how to deal with
these relocations. Note that Steven and I have been down this road before,
please refer to [0] for details

[0] https://lists.01.org/pipermail/edk2-devel/2016-July/000113.html

Reading back, I even mention the GOTPCREL linker optimization you bring up
here. Apologies for my poor memory in this regard. In any case, the difficulty
with this was that the GOT entries are only covered by dynamic relocations,
while the GenFw processing is based entirely on the static relocations emitted
into the executable due to the use of GNU ld's --emit-relocs command line
option. This means you cannot simply emit EFI_IMAGE_REL_BASED_DIR64 PE/COFF
relocations for all R_X86_64_GLOB_DAT you encounter in the dynamic .rela
section, because some of them will already be covered by a static relocation.

--
You are receiving this mail because:
You are on the CC list for the bug.