[llvm-bugs] [Bug 41000] New: PT_NOTE segment not packed correctly

via llvm-bugs llvm-bugs at lists.llvm.org
Thu Mar 7 15:33:08 PST 2019


https://bugs.llvm.org/show_bug.cgi?id=41000

            Bug ID: 41000
           Summary: PT_NOTE segment not packed correctly
           Product: lld
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P
         Component: ELF
          Assignee: unassignedbugs at nondot.org
          Reporter: jakehehrlich at google.com
                CC: llvm-bugs at lists.llvm.org, peter.smith at linaro.org

I'm currently filing it against LLD because its where I think we can fix it but
my hunch is actually that this is an issue with the odd state of how 32-bit
notes are used on 64-bit objects and how NT_GNU_PROPERTY_TYPE_0 requires 8-byte
alignment.

When building clang-tblgen using Clang and LLD we managed to produce a binary
with the following note sections.

Section {
    Index: 2
    Name: .note.ABI-tag (9)
    Type: SHT_NOTE (0x7)
    Flags [ (0x2)
      SHF_ALLOC (0x2)
    ]
    Address: 0x20028C
    Offset: 0x28C
    Size: 32
    Link: 0
    Info: 0
    AddressAlignment: 4
    EntrySize: 0
  }
  Section {
    Index: 3
    Name: .note.gnu.property (23)
    Type: SHT_NOTE (0x7)
    Flags [ (0x2)
      SHF_ALLOC (0x2)
    ]
    Address: 0x2002B0
    Offset: 0x2B0
    Size: 64
    Link: 0
    Info: 0
    AddressAlignment: 8
    EntrySize: 0
  }
  Section {
    Index: 4
    Name: .note.gnu.build-id (42)
    Type: SHT_NOTE (0x7)
    Flags [ (0x2)
      SHF_ALLOC (0x2)
    ]
    Address: 0x2002F0
    Offset: 0x2F0
    Size: 24
    Link: 0
    Info: 0
    AddressAlignment: 4
    EntrySize: 0
  }

The end of the first note occurs 16 bytes before the end of the second note.
This is functionally fine if you're parsing notes from sections but if you
intend to use PT_NOTE this causes an issue because the gap makes iteration
impossible. The PT_NOTE segment is the following

  ProgramHeader {
    Type: PT_NOTE (0x4)
    Offset: 0x28C
    VirtualAddress: 0x20028C
    PhysicalAddress: 0x20028C
    FileSize: 124
    MemSize: 124
    Flags [ (0x4)
      PF_R (0x4)
    ]
    Alignment: 8
  }

The size of each section is appropriate, the size of the PT_NOTE segment covers
all sections exactly, but there's just 16 bytes floating in the middle. The
bytes in that range are the following

         0    2    4    6    8    a    c    e
000002a0: 0200 0000 0600 0000 2000 0000 0000 0000  ........ .......
000002b0: 0400 0000 1000 0000 0500 0000 474e 5500  ............GNU.
000002c0: 0200 00c0 0400 0000 0300 0000 0000 0000  ................

Note that at 0x2B0 a different note starts. 0x2AC to 0x2B0 is just zeros.

This issue appears to have occurred because of an 8-byte alignment bump in the
second section. The output section has 8-byte alignment so this seems like the
correct thing to do but it causes this issue. The 8-byte alignment seems to be
required by NT_GNU_PROPERTY_TYPE_0 however because it stores 64-bit fields on
64-bit objects.

A possible solution is to sort output sections by alignment in descending order
before writing them into the binary. This will close the gap we're currently
seeing here and ensure that PT_NOTE is packed correctly.

Petr Hosek can provide a reproducer for this linking step in case that is
desired but I don't think that's necessary.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190307/7caff624/attachment.html>


More information about the llvm-bugs mailing list