[PowerPC] Garbage collecting .toc entries in a non-adhoc way (section group)

Fangrui Song i@maskray.me
Mon Mar 2 06:56:00 GMT 2020


Originally described at https://reviews.llvm.org/D75416#1900281

.text.foo (SHF_GROUP) references .toc
.toc references .rodata.foo (SHF_GROUP)

If .text.foo and .rodata.foo are not prevailing (discarded by the section group rule) =>
.toc referencing .rodata.foo (STB_LOCAL) is disallowed by the ELF spec (http://www.sco.com/developers/gabi/latest/ch4.sheader.html):

   A symbol table entry with STB_LOCAL binding that is defined relative to one of a group's sections, and that is contained in a symbol table section that is not part of the group, must be discarded if the group members are discarded. References to this symbol table entry from outside the group are not allowed.

One fix is to let .toc reference foo (STB_GLOBAL/STB_WEAK) instead of .rodata.foo . STB_GLOBAL/STB_WEAK are allowed by the ELF spec.
There is still one problem: the .toc entry is not garbage collected.  Well, ld can do it, but that will be an ad-hoc rule.

Now I am thinking about whether we can produce .toc in section groups to obtain garbage collection ability for free.


.text (not in a section group) references `foo` defined in .data.rel.ro.foo (in a section group) via .toc .
```
.text
addis 3,2,.LC0@toc@ha

.section .data.rel.ro.foo,"aGw",foo,comdat
.globl foo
foo:

.section .toc,"aGw",@progbits,foo,comdat
.LC0:
.tc foo[TC],foo
```

When `.data.rel.ro.foo` and the `.toc` are discarded due to the section group rule, the relocation from `.text` to the `.toc` becomes dangling. 

One thought is to change the .toc reference to a STB_GLOBAL:
```
.text
addis 3,2,foo.toc@toc@ha

.section .toc,"aGw",@progbits,foo,comdat
.globl foo.toc
foo.toc:
.tc foo[TC],foo
```

Everything works fine except one thing: foo.toc is left in .symtab (unless --strip-all) and probably .dynsym. If we set the visibility of foo.toc to STB_HIDDEN or STB_INTERNAL, foo.toc will be omitted from .dynsym, but we cannot omit it from .symtab.
(Unless we extend ELF and say STB_INTERNAL symbols are omitted from .symtab, but this is may be bad/ad-hoc.)

I have a feeling that the `.tc` directive was misdesigned for ELF. If we let `foo@toc@ha` create a TOC entry implicitly (like a GOT-generating relocation on other architectures), we would not need multiple .toc sections in the first place.
Additionally, toc-indirect to toc-relative relaxation would become easier to implement.
Note, explicit `.section .toc,"aw",@progbits` can still be allowed if we want to emit some non-symbol entries.
They are explicit. The TOC relocation referenced symbols are implicit.

It is sad that .toc is prettier than ppc32 .got2, but that is the pot calling the kettle black.



More information about the Binutils mailing list