This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Respect NonAlloc when copying flags from the previous sections
ClosedPublic

Authored by MaskRay on Mar 29 2019, 3:44 AM.

Details

Summary

If the output section contains only symbol assignments, we copy flags
from the previous sections. Don't set SHF_ALLOC if NonAlloc is true.

We also have to change the type from SHT_NOBITS to SHT_PROGBITS.
In BFD, bfd_elf_get_default_section_type maps non-alloctable sections to SHT_PROGBITS.

Fixes PR38626

Diff Detail

Repository
rL LLVM

Event Timeline

MaskRay created this revision.Mar 29 2019, 3:44 AM
ruiu added inline comments.Apr 1 2019, 2:00 AM
ELF/LinkerScript.cpp
883 ↗(On Diff #192795)

Sec->Flags can have SHF_ALLOC bit on while Sec->NonAlloc is true? If so, it sounds like a contradiction... Maybe we should fix that?

MaskRay marked 2 inline comments as done.Apr 1 2019, 4:38 AM
MaskRay added inline comments.
ELF/LinkerScript.cpp
883 ↗(On Diff #192795)

In this function (adjustSectionBeforeSorting), Sec->Flags is consistent with Sec->NonAlloc. This is because processSectionCommands runs before and does if (Sec->NonAlloc) Sec->Flags &= ~(uint64_t)SHF_ALLOC;`.

This patch makes the inferred flags for empty output sections correct.

ruiu added a comment.Apr 1 2019, 9:22 PM

I don't think I understand the logic. So the rule you said is that, if a section is empty, its section attribute is copied from the previous (non-empty) section. Therefore, if the previous section is SHF_ALLOC, the empty section would have SHF_ALLOC, and vice versa. But you are doing more than copying section attributes -- nullifying only SHF_ALLOC using other bits. Why?

MaskRay marked an inline comment as done.EditedApr 1 2019, 10:07 PM

So the rule you said is that, if a section is empty, its section attribute is copied from the previous (non-empty) section.

Yes. (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR) may be copied.

Therefore, if the previous section is SHF_ALLOC, the empty section would have SHF_ALLOC, and vice versa.

The empty OutputSection may have its NonAlloc bit set. In that case, The SHF_ALLOC bit shouldn't be copied.

But you are doing more than copying section attributes -- nullifying only SHF_ALLOC using other bits. Why?

If Sec->NonAlloc, Sec->Flags can't have the SHF_ALLOC bit set. The bit (if set originally) has been cleared by:

void LinkerScript::processSectionCommands() {
...
      if (Sec->NonAlloc)
        Sec->Flags &= ~(uint64_t)SHF_ALLOC;
ruiu accepted this revision.Apr 18 2019, 1:56 AM

LGTM

This revision is now accepted and ready to land.Apr 18 2019, 1:56 AM
This revision was automatically updated to reflect the committed changes.