[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 #8 from Shi Steven <steven.shi(a)intel.com> ---
====== a.c
#define SIZE_OF_THUNK 9

extern void thunkArea(void);
extern long const offsetOfThunkTable;

unsigned long compute_thunk_address(long thunkIndexInTable)
{
return (unsigned long) thunkArea + offsetOfThunkTable * SIZE_OF_THUNK + thunkIndexInTable * SIZE_OF_THUNK;
}
======
gcc -Os -fpie -fvisibility=hidden -c -o a.o a.c
objdump -dr a.o

Asked H.J. Liu, and his comments about above example are in below:
"
From GCC manual:

'extern' declarations are not affected by '-fvisibility', so a lot
of code can be recompiled with '-fvisibility=hidden' with no
modifications. However, this means that calls to 'extern'
functions with no explicit visibility use the PLT, so it is more
effective to use '__attribute ((visibility))' and/or '#pragma GCC
visibility' to tell the compiler which 'extern' declarations should
be treated as hidden.

You need to add __attribute__ ((visibility("hidden"))) to
extern void thunkArea(void);
"

So, it is not complete to only use the "-fvisibility=hidden" to hide all
symbols' visibility, but adding '__attribute__ ((visibility("hidden")))' or
'#pragma GCC visibility push (hidden)' are better solution. e.g. Add the
'#pragma GCC visibility push (hidden)' in above example as below can disable
the GOTPCREL relocation emit:
==============cat GOTPCREL.c:

#define SIZE_OF_THUNK 9
#pragma GCC visibility push (hidden)
extern void thunkArea(void);
extern long const offsetOfThunkTable;

unsigned long compute_thunk_address(long thunkIndexInTable)
{
return (unsigned long) thunkArea + offsetOfThunkTable * SIZE_OF_THUNK +
thunkIndexInTable * SIZE_OF_THUNK;
}
======================
gcc -Os -fpie -c -o GOTPCREL.o GOTPCREL.c
objdump -dr GOTPCREL.o

GOTPCREL.o: file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <compute_thunk_address>:
0: 48 6b 05 00 00 00 00 imul $0x9,0x0(%rip),%rax # 8
<compute_thunk_address+0x8>
7: 09
3: R_X86_64_PC32 offsetOfThunkTable-0x5
8: 48 8d 15 00 00 00 00 lea 0x0(%rip),%rdx # f
<compute_thunk_address+0xf>
b: R_X86_64_PC32 thunkArea-0x4
f: 48 8d 3c ff lea (%rdi,%rdi,8),%rdi
13: 48 01 d0 add %rdx,%rax
16: 48 01 f8 add %rdi,%rax
19: c3 retq


I also find a useful GCC wiki about the visibility:
https://gcc.gnu.org/wiki/Visibility
"#pragma GCC visibility is stronger than -fvisibility; it affects extern
declarations as well. -fvisibility only affects definitions, so that existing
code can be recompiled with minimal changes. This is more true for C than C++;
C++ interfaces tend use classes, which are affected by -fvisibility."

So, keeping the '#pragma GCC visibility push (hidden)' in ProcessorBind.h is
correct and necessary for ELF symbols.

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