[llvm] 84eff8c - [llvm-objcopy][MachO] Fix segment's vmsize

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 26 20:42:33 PDT 2020


Author: Alexander Shaposhnikov
Date: 2020-04-26T20:41:49-07:00
New Revision: 84eff8cef61df89c54e73f99baa3ba3cf03b5e55

URL: https://github.com/llvm/llvm-project/commit/84eff8cef61df89c54e73f99baa3ba3cf03b5e55
DIFF: https://github.com/llvm/llvm-project/commit/84eff8cef61df89c54e73f99baa3ba3cf03b5e55.diff

LOG: [llvm-objcopy][MachO] Fix segment's vmsize

This diff fixes the calculation of the field vmsize
in LC_SEGMENT/LC_SEGMENT_64 load commands.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D78799

Added: 
    llvm/test/tools/llvm-objcopy/MachO/segments-vmsize.test

Modified: 
    llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-objcopy/MachO/segments-vmsize.test b/llvm/test/tools/llvm-objcopy/MachO/segments-vmsize.test
new file mode 100644
index 000000000000..40fb4064bdff
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/segments-vmsize.test
@@ -0,0 +1,259 @@
+# RUN: yaml2obj %s -o %t 
+
+## The binary used in this test can be built (on OSX) as follows:
+## main.c:
+##   __attribute__((used)) static int a[1021];
+##   __attribute__((used)) static char b = 1;
+##   int main() {
+##     return 0;
+##   }
+## build command:
+##   clang -fno-exceptions -fno-unwind-tables main.c -o main.exe
+## Note, that the variable "b" (whose size is 1) is placed into __DATA,__data section,
+## the array "a" (whose size is 4 * 1021 = 4084) is placed into __DATA,__bss and
+## __DATA,__bss is 16-byte aligned. In this case the total vmsize narrowly crosses
+## the border of one page (4096) and the final value should be equal to 8192.
+
+# RUN: llvm-objcopy %t %t.copy
+# RUN: cmp %t %t.copy
+
+## This additionally verifies that the binary created by llvm-objcopy/yaml2obj is valid.
+# RUN: llvm-readobj --sections %t.copy
+
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x80000003
+  filetype:        0x00000002
+  ncmds:           15
+  sizeofcmds:      976
+  flags:           0x00200085
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          4294967296
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          4096
+    fileoff:         0
+    filesize:        4096
+    maxprot:         5
+    initprot:        5
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000100000FA0
+        size:            15
+        offset:          0x00000FA0
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         554889E531C0C745FC000000005DC3
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x0000000100000FB0
+        size:            72
+        offset:          0x00000FB0
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         010000001C000000000000001C000000000000001C00000002000000A00F00003400000034000000B00F00000000000034000000030000000C000100100001000000000000000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __DATA
+    vmaddr:          4294971392
+    vmsize:          8192
+    fileoff:         4096
+    filesize:        4096
+    maxprot:         3
+    initprot:        3
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __data
+        segname:         __DATA
+        addr:            0x0000000100001000
+        size:            1
+        offset:          0x00001000
+        align:           0
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000000
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+        content:         '01'
+      - sectname:        __bss
+        segname:         __DATA
+        addr:            0x0000000100001010
+        size:            4084
+        offset:          0x00000000
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x00000001
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4294979584
+    vmsize:          4096
+    fileoff:         8192
+    filesize:        128
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_DYLD_INFO_ONLY
+    cmdsize:         48
+    rebase_off:      0
+    rebase_size:     0
+    bind_off:        0
+    bind_size:       0
+    weak_bind_off:   0
+    weak_bind_size:  0
+    lazy_bind_off:   0
+    lazy_bind_size:  0
+    export_off:      8192
+    export_size:     48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          8248
+    nsyms:           2
+    stroff:          8280
+    strsize:         40
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
+    nundefsym:       1
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+  - cmd:             LC_LOAD_DYLINKER
+    cmdsize:         32
+    name:            12
+    PayloadString:   '/usr/lib/dyld'
+    ZeroPadBytes:    7
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            11362E8D-D70B-33B3-96F8-A70ADF2583C4
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           658944
+    sdk:             658944
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         34734080
+  - cmd:             LC_SOURCE_VERSION
+    cmdsize:         16
+    version:         0
+  - cmd:             LC_MAIN
+    cmdsize:         24
+    entryoff:        4000
+    stacksize:       0
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 82115073
+      compatibility_version: 65536
+    PayloadString:   '/usr/lib/libSystem.B.dylib'
+    ZeroPadBytes:    6
+  - cmd:             LC_FUNCTION_STARTS
+    cmdsize:         16
+    dataoff:         8240
+    datasize:        8
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         8248
+    datasize:        0
+LinkEditData:
+  ExportTrie:
+    TerminalSize:    0
+    NodeOffset:      0
+    Name:            ''
+    Flags:           0x0000000000000000
+    Address:         0x0000000000000000
+    Other:           0x0000000000000000
+    ImportName:      ''
+    Children:
+      - TerminalSize:    0
+        NodeOffset:      5
+        Name:            _
+        Flags:           0x0000000000000000
+        Address:         0x0000000000000000
+        Other:           0x0000000000000000
+        ImportName:      ''
+        Children:
+          - TerminalSize:    2
+            NodeOffset:      33
+            Name:            _mh_execute_header
+            Flags:           0x0000000000000000
+            Address:         0x0000000000000000
+            Other:           0x0000000000000000
+            ImportName:      ''
+          - TerminalSize:    3
+            NodeOffset:      37
+            Name:            main
+            Flags:           0x0000000000000000
+            Address:         0x0000000000000FA0
+            Other:           0x0000000000000000
+            ImportName:      ''
+  NameList:
+    - n_strx:          18
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          1
+      n_type:          0x01
+      n_sect:          0
+      n_desc:          256
+      n_value:         0
+  StringTable:
+    - ''
+    - dyld_stub_binder
+    - __mh_execute_header
+    - ''
+    - ''
+...

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
index e6c5dde42027..0ffe22a1783b 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp
@@ -144,6 +144,9 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
     uint64_t SegFileSize = 0;
     uint64_t VMSize = 0;
     for (std::unique_ptr<Section> &Sec : LC.Sections) {
+      assert(SegmentVmAddr <= Sec->Addr &&
+             "Section's address cannot be smaller than Segment's one");
+      uint32_t SectOffset = Sec->Addr - SegmentVmAddr;
       if (IsObjectFile) {
         if (Sec->isVirtualSection()) {
           Sec->Offset = 0;
@@ -154,19 +157,16 @@ uint64_t MachOLayoutBuilder::layoutSegments() {
           Sec->Size = Sec->Content.size();
           SegFileSize += PaddingSize + Sec->Size;
         }
-        VMSize = std::max(VMSize, Sec->Addr + Sec->Size);
       } else {
         if (Sec->isVirtualSection()) {
           Sec->Offset = 0;
-          VMSize += Sec->Size;
         } else {
-          uint32_t SectOffset = Sec->Addr - SegmentVmAddr;
           Sec->Offset = SegOffset + SectOffset;
           Sec->Size = Sec->Content.size();
           SegFileSize = std::max(SegFileSize, SectOffset + Sec->Size);
-          VMSize = std::max(VMSize, SegFileSize);
         }
       }
+      VMSize = std::max(VMSize, SectOffset + Sec->Size);
     }
 
     if (IsObjectFile) {


        


More information about the llvm-commits mailing list