This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Place SHT_NOTE sections with the same alignment into one PT_NOTE
ClosedPublic

Authored by MaskRay on Apr 30 2019, 12:00 AM.

Details

Summary

While the generic ABI requires notes to be 8-byte aligned in ELF64, many
vendor-specific notes (from Linux, NetBSD, Solaris, etc) use 4-byte
alignment.

In a PT_NOTE segment, if 4-byte aligned notes are followed by an 8-byte
aligned note, the possible 4-byte padding may make consumers fail to
parse the 8-byte aligned note. See PR41000 for the recent report about
.note.gnu.property (NT_GNU_PROPERTY_TYPE_0).
(Note, for NT_GNU_PROPERTY_TYPE_0, the consumers should probably migrate
to PT_GNU_PROPERTY, but the alignment issue affects other notes as well.)

To fix the issue, this patches disallows notes with different alignments
from being placed in the same PT_NOTE. If compilers emit 4-byte aligned
notes before 8-byte aligned notes, we'll create at most 2 segments.

We don't have to check whether sh_size is a multiple of sh_addralign.
It is unrealistic and it shouldn't cause parsing issues anyway (the
output is not different from the case with the sh_size aligned up).

An alternative approach is to create a PT_NOTE for each SHT_NOTE, but
we'll have to incur the sizeof(Elf64_Phdr) = 56 overhead every time a
new note section is introduced.

Diff Detail

Repository
rLLD LLVM Linker

Event Timeline

MaskRay created this revision.Apr 30 2019, 12:00 AM
MaskRay updated this revision to Diff 197264.Apr 30 2019, 12:12 AM
MaskRay retitled this revision from [ELF] Place SHT_NOTE sections with the same alignments into one PT_NOTE to [ELF] Place SHT_NOTE sections with the same alignment into one PT_NOTE.
MaskRay edited the summary of this revision. (Show Details)

Change descriptions a bit

If multiple note sections with unaligned sizes but larger than 4-byte alignment are used this solution doesn't work.

MaskRay added a comment.EditedApr 30 2019, 5:25 PM

If multiple note sections with unaligned sizes but larger than 4-byte alignment are used this solution doesn't work.

I've mentioned this in the description.
First, alignments other than 4/8 are unrealistic.
Second, sh_size%sh_addralign!=0 is unrealistic. The rule for linking unrecognized sections is (linker doesn't know the semantics of many .note*):

Unrecognized sections that do not have the SHF_OS_NONCONFORMING attribute, are combined in a two-phase process. As the link editor combines sections using this process, it must honor the alignment constraints of the input sections (asserted by the sh_addralign field), padding between sections with zero bytes, if necessary, and producing a combination with the maximum alignment constraint of its component input sections.

Say you have a .note.a (sh_addralign=8 sh_size=9) followed by another .note.a (sh_addralign=8 sh_size=16). The size of the first note is not a multiple of the alignment. Since the two input sections have the same name, they are concatenated and go to the same output section. When concatenating, the linker will emit a 7-byte padding (as if `sh_addralign=8 sh_size=9+7). To guarantee the notes after linking are parsable, the compilers must take into account of this factor and emit size aligned notes to the object files.

jakehehrlich accepted this revision.May 2 2019, 2:12 PM

Ok so I'm good with this. We would like to land this ASAP.

This revision is now accepted and ready to land.May 2 2019, 2:12 PM
MaskRay updated this revision to Diff 197899.May 2 2019, 5:32 PM

Update description

This revision was automatically updated to reflect the committed changes.