]> granicus.if.org Git - llvm/commitdiff
[JITLink] Don't under-align zero-fill sections.
authorLang Hames <lhames@gmail.com>
Tue, 27 Aug 2019 15:22:23 +0000 (15:22 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 27 Aug 2019 15:22:23 +0000 (15:22 +0000)
If content sections have lower alignment than zero-fill sections then bump the
overall segment alignment to avoid under-aligning the zero-fill sections.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370072 91177308-0d34-0410-b5e6-96231b3b80d8

lib/ExecutionEngine/JITLink/JITLinkGeneric.cpp
test/ExecutionEngine/JITLink/X86/MachO_zero_fill_alignment.s [new file with mode: 0644]

index 96e074da122ba476eccfa5bbfd992e3e1368dc54..877107ffe2581470e13d04ffdb18996dcac70713 100644 (file)
@@ -238,60 +238,47 @@ Error JITLinkerBase::allocateSegments(const SegmentLayoutMap &Layout) {
 
     // Calculate segment content size.
     size_t SegContentSize = 0;
+    uint32_t SegContentAlign = 1;
     for (auto &SI : SegLayout.ContentSections) {
       assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
       assert(!SI.Atoms.empty() && "Section layouts must not be empty");
 
       // Bump to section alignment before processing atoms.
       SegContentSize = alignTo(SegContentSize, SI.S->getAlignment());
+      SegContentAlign = std::max(SegContentAlign, SI.S->getAlignment());
 
       for (auto *DA : SI.Atoms) {
         SegContentSize = alignTo(SegContentSize, DA->getAlignment());
         SegContentSize += DA->getSize();
+        SegContentAlign = std::max(SegContentAlign, DA->getAlignment());
       }
     }
 
-    // Get segment content alignment.
-    unsigned SegContentAlign = 1;
-    if (!SegLayout.ContentSections.empty()) {
-      auto &FirstContentSection = SegLayout.ContentSections.front();
-      SegContentAlign =
-          std::max(FirstContentSection.S->getAlignment(),
-                   FirstContentSection.Atoms.front()->getAlignment());
-    }
-
     // Calculate segment zero-fill size.
     uint64_t SegZeroFillSize = 0;
+    uint32_t SegZeroFillAlign = 1;
+
     for (auto &SI : SegLayout.ZeroFillSections) {
       assert(!SI.S->atoms_empty() && "Sections in layout must not be empty");
       assert(!SI.Atoms.empty() && "Section layouts must not be empty");
 
       // Bump to section alignment before processing atoms.
       SegZeroFillSize = alignTo(SegZeroFillSize, SI.S->getAlignment());
+      SegZeroFillAlign = std::max(SegZeroFillAlign, SI.S->getAlignment());
 
       for (auto *DA : SI.Atoms) {
         SegZeroFillSize = alignTo(SegZeroFillSize, DA->getAlignment());
         SegZeroFillSize += DA->getSize();
+        SegZeroFillAlign = std::max(SegZeroFillAlign, SI.S->getAlignment());
       }
     }
 
-    // Calculate segment zero-fill alignment.
-    uint32_t SegZeroFillAlign = 1;
-
-    if (!SegLayout.ZeroFillSections.empty()) {
-      auto &FirstZeroFillSection = SegLayout.ZeroFillSections.front();
-      SegZeroFillAlign =
-          std::max(FirstZeroFillSection.S->getAlignment(),
-                   FirstZeroFillSection.Atoms.front()->getAlignment());
-    }
-
-    if (SegContentSize == 0)
-      SegContentAlign = SegZeroFillAlign;
-
-    if (SegContentAlign % SegZeroFillAlign != 0)
-      return make_error<JITLinkError>("First content atom alignment does not "
-                                      "accommodate first zero-fill atom "
-                                      "alignment");
+    assert(isPowerOf2_32(SegContentAlign) &&
+           "Expected content alignment to be power of 2");
+    assert(isPowerOf2_32(SegZeroFillAlign) &&
+           "Expected zero-fill alignment to be power of 2");
+    // Round content alignment up to segment alignment.
+    SegContentAlign = std::max(SegContentAlign, SegZeroFillAlign);
 
     Segments[Prot] = {SegContentSize, SegContentAlign, SegZeroFillSize,
                       SegZeroFillAlign};
diff --git a/test/ExecutionEngine/JITLink/X86/MachO_zero_fill_alignment.s b/test/ExecutionEngine/JITLink/X86/MachO_zero_fill_alignment.s
new file mode 100644 (file)
index 0000000..3b3a385
--- /dev/null
@@ -0,0 +1,14 @@
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/macho_zero_fill_align.o %s
+# RUN: llvm-jitlink -noexec %t/macho_zero_fill_align.o -entry higher_zero_fill_align
+
+        .section        __DATA,__data
+        .globl low_aligned_data
+        .p2align  0
+low_aligned_data:
+        .byte 42
+
+        .globl higher_zero_fill_align
+.zerofill __DATA,__zero_fill,higher_zero_fill_align,8,3
+
+.subsections_via_symbols