[COFF] Refactor section alignment calculation
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 17 Mar 2016 16:55:18 +0000 (16:55 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 17 Mar 2016 16:55:18 +0000 (16:55 +0000)
Section alignment isn't completely trivial, let it live in one place so
that we may reuse it in LLVM.

llvm-svn: 263722

llvm/include/llvm/Object/COFF.h
llvm/lib/Object/COFFObjectFile.cpp

index 87b7ae2..4aad87c 100644 (file)
@@ -414,6 +414,18 @@ struct coff_section {
     return (Characteristics & COFF::IMAGE_SCN_LNK_NRELOC_OVFL) &&
            NumberOfRelocations == UINT16_MAX;
   }
+  uint32_t getAlignment() const {
+    // The IMAGE_SCN_TYPE_NO_PAD bit is a legacy way of getting to
+    // IMAGE_SCN_ALIGN_1BYTES.
+    if (Characteristics & COFF::IMAGE_SCN_TYPE_NO_PAD)
+      return 1;
+
+    // Bit [20:24] contains section alignment. Both 0 and 1 mean alignment 1.
+    uint32_t Shift = (Characteristics >> 20) & 0xF;
+    if (Shift > 0)
+      return 1U << (Shift - 1);
+    return 1;
+  }
 };
 
 struct coff_relocation {
@@ -494,8 +506,11 @@ struct coff_tls_directory {
   support::ulittle32_t SizeOfZeroFill;
   support::ulittle32_t Characteristics;
   uint32_t getAlignment() const {
-    uint32_t AlignBit = (Characteristics & 0x00F00000) >> 20;
-    return AlignBit ? 1 << (AlignBit - 1) : 0;
+    // Bit [20:24] contains section alignment.
+    uint32_t Shift = (Characteristics & 0x00F00000) >> 20;
+    if (Shift > 0)
+      return 1U << (Shift - 1);
+    return 0;
   }
 };
 
index 4cd6aff..2514547 100644 (file)
@@ -290,7 +290,7 @@ std::error_code COFFObjectFile::getSectionContents(DataRefImpl Ref,
 
 uint64_t COFFObjectFile::getSectionAlignment(DataRefImpl Ref) const {
   const coff_section *Sec = toSec(Ref);
-  return uint64_t(1) << (((Sec->Characteristics & 0x00F00000) >> 20) - 1);
+  return Sec->getAlignment();
 }
 
 bool COFFObjectFile::isSectionText(DataRefImpl Ref) const {