This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Improve section GC for comdat groups
AbandonedPublic

Authored by evgeny777 on Sep 15 2016, 10:43 AM.

Details

Reviewers
ruiu
rafael
Summary

This patch fixes two things

  1. If any section within comdat group is marked Live an entire group is marked live.
  2. On some occasions GC may crash if symbol references section which is a member of comdat group. This happens in case compiler creates section relocation, i.e:
leaq    .text._Z3fooIiEvv(%rip), %rax

Diff Detail

Event Timeline

evgeny777 updated this revision to Diff 71523.Sep 15 2016, 10:43 AM
evgeny777 retitled this revision from to [ELF] Improve section GC for comdat groups.
evgeny777 updated this object.
evgeny777 added reviewers: ruiu, rafael.
evgeny777 set the repository for this revision to rL LLVM.
evgeny777 added a project: lld.
evgeny777 added subscribers: grimar, llvm-commits.
ruiu edited edge metadata.Sep 15 2016, 10:56 AM

Can it actually happen that two sections in the same comdat group have no relocations between them? I'm wondering how you found the issue.

I'm trying to keep debug information in --gc-sections mode. After I tried modifying isReserved() I immediately stepped on a crash, because .debug_lines section had relocation to one of the member of comdat groups. I think test case shows how this can happen, doesn't it?

Or are you trying to tell, that there are always relocs between each member of comdat group and all other members? If so you still need to locate the real section and add it to the queue, no?

ruiu added a comment.Sep 15 2016, 12:24 PM

It feels to me that it is doing too much work to handle comdat groups. How about adding std::vector<InputSectionData *> GroupMembers to InputSectionData and use that as successors? InputFile creates such vector and add it to all group member sections, so that you can reach all group members from any group member.

ruiu added inline comments.Sep 15 2016, 12:26 PM
ELF/MarkLive.cpp
263–269

I don't think this is correct because the last forEachSuccessor could mark a section in a comdat group live, so you want to repeat this process until converge.

Let's elaborate the idea. The main problem is that symbol 'D' inside resolveReloc() may point to InputSectionBase<ELFT>::Discarded. This happens because comdat group is added to only one object file and causes crash in GC, because forEachSuccessor implicitly casts Discarded to InputSection<ELFT> and tries to fetch relocs from it. How this 'GroupMembers' vector would help?

evgeny777 added inline comments.Sep 15 2016, 12:34 PM
ELF/MarkLive.cpp
263–269

The piece of code on lines 214-215 :

if (R.Sec->Live)
   return;

handles this, no?

evgeny777 abandoned this revision.Sep 16 2016, 6:30 AM