[llvm-bugs] [Bug 42963] New: Fix nested segment algorithm for segments with different alignments

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Aug 12 02:27:30 PDT 2019


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

            Bug ID: 42963
           Summary: Fix nested segment algorithm for segments with
                    different alignments
           Product: tools
           Version: trunk
          Hardware: PC
                OS: Windows NT
            Status: NEW
          Severity: normal
          Priority: P
         Component: llvm-objcopy/strip
          Assignee: unassignedbugs at nondot.org
          Reporter: jh7370.2008 at my.bristol.ac.uk
                CC: alexander.v.shaposhnikov at gmail.com,
                    jake.h.ehrlich at gmail.com,
                    jh7370.2008 at my.bristol.ac.uk,
                    llvm-bugs at lists.llvm.org, rupprecht at google.com

The llvm-objcopy (and llvm-strip) segment layout algorithm follows the rough
approach of:
1) If segment1 offset starts before segment2's, and it's end ends after the
start of segment2, segment1 is a parent of segment2.
2) If two segments start at the same offset, the larger one is considered the
parent.
3) If two segments have the same size and offset, the first one in the program
header table is considered the parent.

I think we need to add another condition before 3), namely that if two segments
have the same size and offset, the one with the larger alignment should be
considered the parent.

I have a lit test illustrating the issue:

---

## This test shows that llvm-objcopy and llvm-strip work correctly when two
## segments have the same offset and size, but the first one in the table has a
## lower alignment. In this case, the parent should be the one with the higher
## alignment.

# RUN: yaml2obj %s -o %t
# RUN: llvm-objcopy %t %t2
# RUN: llvm-readobj --program-headers %t2 | FileCheck %s
# RUN: llvm-strip --no-strip-all %t -o %t3
# RUN: cmp %t2 %t3

# CHECK:      ProgramHeaders [
# CHECK-NEXT:   ProgramHeader {
# CHECK-NEXT:     Type: PT_TLS (0x7)
# CHECK-NEXT:     Offset: 0x200
# CHECK:        ProgramHeader {
# CHECK-NEXT:     Type: PT_LOAD (0x1)
# CHECK-NEXT:     Offset: 0x200

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_EXEC
  Machine: EM_X86_64
Sections:
  - Name:         padding
    Type:         SHT_PROGBITS
    AddressAlign: 0x800
ProgramHeaders:
  - Type:     PT_TLS
    Offset:   0x400
    FileSize: 0x10
    MemSize:  0x10
    VAddr:    0x200
    Align:    0x1
  - Type:     PT_LOAD
    Offset:   0x400
    FileSize: 0x10
    MemSize:  0x10
    VAddr:    0x200
    Align:    0x200

---

Note that in this test, there are two segments with the same size and offset,
but the first segment has a lower alignment. As things stand, this test will
fail because the segments are moved to immediately after the end of the program
header table, i.e. offset 0xB0, which violates the alignment requirements of
the PT_LOAD segment.

For reference, there is nothing in the gABI mandating that segments appear in a
specific order, except that PT_INTERP and PT_PHDR must appear before loadable
segments and loadable segments must appear in ascending address order.

Arguably, there is a wider issue here, namely that child segment alignments are
ignored. I'm not sure what the right behaviour is in cases where a clear child
segment has higher alignment requirements than the parent, so this is probably
a separate issue.

Aside: I couldn't get GNU objcopy to do something sensible with similar input
to the above. This might be a GNU objcopy bug though.

-- 
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/20190812/f1f17539/attachment.html>


More information about the llvm-bugs mailing list