[PATCH] D91426: [PowerPC] Fix issue where binary uses a .got but is missing a .TOC.

Sean Fertile via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 24 12:30:06 PDT 2021


sfertile added a comment.

In D91426#2569605 <https://reviews.llvm.org/D91426#2569605>, @stefanp wrote:

> In D91426#2568567 <https://reviews.llvm.org/D91426#2568567>, @sfertile wrote:
>
>> Could there be a simpler approach where we always emit a .got section on PPC64:  In `addReservedSymbols` if we fail to resolve `.TOC.` then we create it?
>
> We could do that and it would certainly solve the problem. The issue I have with that is that we will now have a `.got` for everything we link including things that we used to link in the past that did not require it. It seems odd to say that since the design of the linker won't allow us to do this easily we will generate this section whether we need it or not.

I'll need to go over this again to refresh my memory. As a quick recap though:

- On PPC, if we create a .got, then the first entry must be the tocbase.
- If `.TOC.` is not defined by one of the input objects, then we do not increment the number of .got entries here <https://github.com/llvm/llvm-project/blob/3fd7d0d281a9b1dc7a8352cbd29178cbfacc73f1/lld/ELF/SyntheticSections.cpp#L653>
- If we synthetically define `.TOC.` in the linker, then we end up with a .got section in some cases where we would otherwise not need one.

Is it possible to change the .got section to always add `gotHeaderEntriesNum` in its constructor for PPC64, and remove the section late if all it contains is the single entry and `.TOC.` is not defined?

In D91426#2541656 <https://reviews.llvm.org/D91426#2541656>, @stefanp wrote:

> In D91426#2535050 <https://reviews.llvm.org/D91426#2535050>, @MaskRay wrote:
>
>> Sorry, I missed your early comments.
>>
>> Which test can demonstrate the bug? My idea is that instead of creating `setupPPCDelayedInit`, we should let `in.got->hasGotOffRel` to convey that .got is needed.
>> See Relocations.cpp:1397
>
> Thank you for looking at this again!
> I think I understand what you are looking for.
>
> Let me start with the example test case. Pretty much any test that requires a GOT will work as long as we use PC Relative and don't have a TOC.
> Take `globalvar.c`:
>
>    int glob_int=0;
>   int function() {
>     return glob_int;
>   }
>
> If we compile it for Power 10:
>
>   clang -O3 -mcpu=pwr10 -c globalvar.c -fPIC
>   ld.lld --shared globalvar.o -o globalvar.so
>
> We can then dump out some information on the GOT for `globalvar.so`.
>
>   $ llvm-readelf -r globalvar.so
>   Relocation section '.rela.dyn' at offset 0x2a0 contains 1 entries:
>       Offset             Info             Type               Symbol's Value  Symbol's Name + Addend
>   0000000000020380  0000000200000014 R_PPC64_GLOB_DAT       0000000000030388 glob_int + 0
>   $ llvm-readelf -x .got globalvar.so
>   Hex dump of section '.got':
>   0x00020380 80830200 00000000                   ........

Please add this as a lit test as part of this patch.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91426/new/

https://reviews.llvm.org/D91426



More information about the llvm-commits mailing list