[llvm] [llvm-objcopy] Fix file offsets when PT_INTERP/PT_LOAD offsets are equal (PR #80562)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 8 11:11:21 PST 2024


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/80562

>From 0d49a5859ac4920492a6d280dcd8aef491fbdec3 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 3 Feb 2024 12:15:33 -0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 llvm/lib/ObjCopy/ELF/ELFObject.cpp            |   7 +
 .../ELF/non-load-at-load-start.test           | 138 ++++++++++++++++++
 2 files changed, 145 insertions(+)
 create mode 100644 llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test

diff --git a/llvm/lib/ObjCopy/ELF/ELFObject.cpp b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
index c8b66d6fcb5ebf..edf0b53faf96da 100644
--- a/llvm/lib/ObjCopy/ELF/ELFObject.cpp
+++ b/llvm/lib/ObjCopy/ELF/ELFObject.cpp
@@ -1234,6 +1234,13 @@ static bool compareSegmentsByOffset(const Segment *A, const Segment *B) {
     return true;
   if (A->OriginalOffset > B->OriginalOffset)
     return false;
+  // If one is PT_LOAD and the other isn't (e.g. PT_INTERP, PT_GNU_RELRO,
+  // PT_TLS), order the PT_LOAD first to ensure ParentSegment relationship will
+  // be correct.
+  bool AIsLOAD = A->Type == PT_LOAD;
+  bool BIsLOAD = B->Type == PT_LOAD;
+  if (AIsLOAD != BIsLOAD)
+    return AIsLOAD;
   return A->Index < B->Index;
 }
 
diff --git a/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test b/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
new file mode 100644
index 00000000000000..7551b6473379f0
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
@@ -0,0 +1,138 @@
+## When the offset of a non-PT_LOAD segment (e.g. PT_INTERP) equals the offset
+## of a PT_LOAD segment, set the parent of the PT_INTERP segment to the PT_LOAD
+## segment, ensuring that the offset is correctly aligned.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy %t %t2
+# RUN: llvm-readelf -Sl %t2 | FileCheck %s
+
+# CHECK:       [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
+# CHECK-NEXT:  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
+# CHECK-NEXT:  [ 1] .text             PROGBITS        0000000000201000 001000 000001 00  AX  0   0  4
+# CHECK-NEXT:  [ 2] .interp           PROGBITS        0000000000202000 002000 00001c 00   A  0   0  1
+# CHECK-NEXT:  [ 3] .rodata           PROGBITS        0000000000202020 002020 000001 00   A  0   0  1
+# CHECK-NEXT:  [ 4] .tdata            PROGBITS        0000000000203000 003000 000001 00 WAT  0   0 4096
+# CHECK-NEXT:  [ 5] .relro_padding    NOBITS          0000000000203001 003001 000fff 00  WA  0   0  1
+# CHECK-NEXT:  [ 6] .symtab           SYMTAB          0000000000000000 003008 000030 18      7   1  8
+# CHECK-NEXT:  [ 7] .strtab           STRTAB          0000000000000000 003038 000008 00      0   0  1
+# CHECK-NEXT:  [ 8] .shstrtab         STRTAB          0000000000000000 003040 000047 00      0   0  1
+
+# CHECK:     Program Headers:
+# CHECK-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+# CHECK-NEXT:  PHDR           0x000040 0x0000000000200040 0x0000000000200040 0x0001c0 0x0001c0 R   0x8
+# CHECK-NEXT:  INTERP         0x002000 0x0000000000202000 0x0000000000202000 0x00001c 0x00001c R   0x1
+# CHECK-NEXT:      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+# CHECK-NEXT:  LOAD           0x000000 0x0000000000200000 0x0000000000200000 0x000200 0x000200 R   0x1000
+# CHECK-NEXT:  LOAD           0x001000 0x0000000000201000 0x0000000000201000 0x000001 0x000001 R E 0x1000
+# CHECK-NEXT:  LOAD           0x002000 0x0000000000202000 0x0000000000202000 0x000021 0x000021 R   0x1000
+# CHECK-NEXT:  TLS            0x003000 0x0000000000203000 0x0000000000203000 0x000001 0x001000 R   0x1000
+# CHECK-NEXT:  GNU_RELRO      0x003000 0x0000000000203000 0x0000000000203000 0x000001 0x001000 R   0x1000
+# CHECK-NEXT:  LOAD           0x003000 0x0000000000203000 0x0000000000203000 0x000001 0x001000 RW  0x1000
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+  Entry:           0x201000
+ProgramHeaders:
+  - Type:            PT_PHDR
+    Flags:           [ PF_R ]
+    VAddr:           0x200040
+    Align:           0x8
+    Offset:          0x40
+    FileSize:        0x1c0
+    MemSize:         0x1c0
+  - Type:            PT_INTERP
+    Flags:           [ PF_R ]
+    FirstSec:        .interp
+    LastSec:         .interp
+    ## The address equals the address of its containing PT_LOAD.
+    VAddr:           0x202000
+    Offset:          0x2000
+  - Type:            PT_LOAD
+    Flags:           [ PF_R ]
+    VAddr:           0x200000
+    Align:           0x1000
+    Offset:          0x0
+    FileSize:        0x200
+    MemSize:         0x200
+  - Type:            PT_LOAD
+    Flags:           [ PF_X, PF_R ]
+    FirstSec:        .text
+    LastSec:         .text
+    VAddr:           0x201000
+    Align:           0x1000
+    Offset:          0x1000
+  - Type:            PT_LOAD
+    Flags:           [ PF_R ]
+    FirstSec:        .interp
+    LastSec:         .rodata
+    VAddr:           0x202000
+    Align:           0x1000
+    Offset:          0x2000
+  ## Intentionally place PT_TLS/PT_GNU_RELRO before PT_LOAD to test that we
+  ## correctly set parent segments.
+  - Type:            PT_TLS
+    Flags:           [ PF_R ]
+    FirstSec:        .tdata
+    LastSec:         .relro_padding
+    VAddr:           0x203000
+    Align:           0x1000
+    Offset:          0x3000
+  - Type:            PT_GNU_RELRO
+    Flags:           [ PF_R ]
+    FirstSec:        .tdata
+    LastSec:         .relro_padding
+    VAddr:           0x203000
+    Align:           0x1000
+    Offset:          0x3000
+  - Type:            PT_LOAD
+    Flags:           [ PF_W, PF_R ]
+    FirstSec:        .tdata
+    LastSec:         .relro_padding
+    VAddr:           0x203000
+    Align:           0x1000
+    Offset:          0x3000
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x201000
+    AddressAlign:    0x4
+    Offset:          0x1000
+    Content:         C3
+  - Name:            .interp
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x202000
+    AddressAlign:    0x1
+    Offset:          0x2000
+    Content:         2F6C696236342F6C642D6C696E75782D7838362D36342E736F2E3200
+  - Name:            .rodata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x202020
+    AddressAlign:    0x1
+    Offset:          0x2020
+    Content:         '00'
+  - Name:            .tdata
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC, SHF_TLS ]
+    Address:         0x203000
+    AddressAlign:    0x1000
+    Offset:          0x3000
+    Content:         '00'
+  - Name:            .relro_padding
+    Type:            SHT_NOBITS
+    Flags:           [ SHF_WRITE, SHF_ALLOC ]
+    Address:         0x203001
+    AddressAlign:    0x1
+    Size:            0xFFF
+Symbols:
+  - Name:            _start
+    Section:         .text
+    Binding:         STB_GLOBAL
+    Value:           0x201000
+...

>From c711f5b1c72b78994790c9fe5c6754c787bfbb77 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Sat, 3 Feb 2024 12:18:13 -0800
Subject: [PATCH 2/2] remove unused symtab

Created using spr 1.3.4
---
 .../llvm-objcopy/ELF/non-load-at-load-start.test      | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test b/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
index 7551b6473379f0..43c70be3cdd565 100644
--- a/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
+++ b/llvm/test/tools/llvm-objcopy/ELF/non-load-at-load-start.test
@@ -13,9 +13,8 @@
 # CHECK-NEXT:  [ 3] .rodata           PROGBITS        0000000000202020 002020 000001 00   A  0   0  1
 # CHECK-NEXT:  [ 4] .tdata            PROGBITS        0000000000203000 003000 000001 00 WAT  0   0 4096
 # CHECK-NEXT:  [ 5] .relro_padding    NOBITS          0000000000203001 003001 000fff 00  WA  0   0  1
-# CHECK-NEXT:  [ 6] .symtab           SYMTAB          0000000000000000 003008 000030 18      7   1  8
-# CHECK-NEXT:  [ 7] .strtab           STRTAB          0000000000000000 003038 000008 00      0   0  1
-# CHECK-NEXT:  [ 8] .shstrtab         STRTAB          0000000000000000 003040 000047 00      0   0  1
+# CHECK-NEXT:  [ 6] .strtab           STRTAB          0000000000000000 003001 000001 00      0   0  1
+# CHECK-NEXT:  [ 7] .shstrtab         STRTAB          0000000000000000 003002 00003f 00      0   0  1
 
 # CHECK:     Program Headers:
 # CHECK-NEXT:  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
@@ -130,9 +129,3 @@ Sections:
     Address:         0x203001
     AddressAlign:    0x1
     Size:            0xFFF
-Symbols:
-  - Name:            _start
-    Section:         .text
-    Binding:         STB_GLOBAL
-    Value:           0x201000
-...



More information about the llvm-commits mailing list