[lld] r263543 - [COFF] Don't hard-code the load configuration size

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 15 02:48:27 PDT 2016


Author: majnemer
Date: Tue Mar 15 04:48:27 2016
New Revision: 263543

URL: http://llvm.org/viewvc/llvm-project?rev=263543&view=rev
Log:
[COFF] Don't hard-code the load configuration size

The load configuration directory is a structure whose size varies as the
OS gains additional functionality.  To account for this, the structure's
layout begins with a size field; this allows loaders to know which
fields are available.

However, LLD hard-coded the sizes (112 bytes for 64-bit and 64 for
32-bit).  This means that we might not inform the loader of all the
pertinent fields or we might claim that there are more fields than are
actually present.

To correctly account for this, the size field must be loaded from the
_load_config_used symbol.

N.B.  The COFF spec is either wrong or out of date, the load
configuration directory is not correctly documented in the
specification: it omits the size field.

Modified:
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/loadcfg.ll
    lld/trunk/test/COFF/loadcfg.test
    lld/trunk/test/COFF/loadcfg32.test

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=263543&r1=263542&r2=263543&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Tue Mar 15 04:48:27 2016
@@ -138,6 +138,7 @@ public:
   SectionChunk(ObjectFile *File, const coff_section *Header);
   static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
   size_t getSize() const override { return Header->SizeOfRawData; }
+  ArrayRef<uint8_t> getContents() const;
   void writeTo(uint8_t *Buf) const override;
   bool hasData() const override;
   uint32_t getPermissions() const override;
@@ -186,8 +187,6 @@ public:
   uint32_t Checksum = 0;
 
 private:
-  ArrayRef<uint8_t> getContents() const;
-
   // A file this chunk was created from.
   ObjectFile *File;
 

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=263543&r1=263542&r2=263543&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Tue Mar 15 04:48:27 2016
@@ -602,9 +602,20 @@ template <typename PEHeaderTy> void Writ
     }
   }
   if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) {
-    if (Defined *B = dyn_cast<Defined>(Sym->Body)) {
+    if (auto *B = dyn_cast<DefinedRegular>(Sym->Body)) {
+      SectionChunk *SC = B->getChunk();
+      assert(B->getRVA() >= SC->getRVA());
+      uint64_t OffsetInChunk = B->getRVA() - SC->getRVA();
+      if (!SC->hasData() || OffsetInChunk + 4 > SC->getSize())
+        error("_load_config_used is malformed");
+
+      ArrayRef<uint8_t> SecContents = SC->getContents();
+      uint32_t LoadConfigSize =
+          *reinterpret_cast<const ulittle32_t *>(&SecContents[OffsetInChunk]);
+      if (OffsetInChunk + LoadConfigSize > SC->getSize())
+        error("_load_config_used is too large");
       Dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = B->getRVA();
-      Dir[LOAD_CONFIG_TABLE].Size = Config->is64() ? 112 : 64;
+      Dir[LOAD_CONFIG_TABLE].Size = LoadConfigSize;
     }
   }
 

Modified: lld/trunk/test/COFF/loadcfg.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/loadcfg.ll?rev=263543&r1=263542&r2=263543&view=diff
==============================================================================
--- lld/trunk/test/COFF/loadcfg.ll (original)
+++ lld/trunk/test/COFF/loadcfg.ll Tue Mar 15 04:48:27 2016
@@ -8,7 +8,7 @@
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"
 
- at _load_config_used = constant i32 1
+ at _load_config_used = constant [28 x i32] [i32 112, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
 
 define void @main() {
   ret void

Modified: lld/trunk/test/COFF/loadcfg.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/loadcfg.test?rev=263543&r1=263542&r2=263543&view=diff
==============================================================================
--- lld/trunk/test/COFF/loadcfg.test (original)
+++ lld/trunk/test/COFF/loadcfg.test Tue Mar 15 04:48:27 2016
@@ -2,7 +2,7 @@
 # RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
 # RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
 
-# CHECK: LoadConfigTableRVA: 0x1008
+# CHECK: LoadConfigTableRVA: 0x1000
 # CHECK: LoadConfigTableSize: 0x70
 
 ---
@@ -18,6 +18,10 @@ sections:
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     B82A000000C3
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     '70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
 symbols:
   - Name:            .text
     Value:           0
@@ -50,9 +54,21 @@ symbols:
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            .rdata
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          112
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
   - Name:            _load_config_used
     Value:           0
-    SectionNumber:   2
+    SectionNumber:   3
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL

Modified: lld/trunk/test/COFF/loadcfg32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/loadcfg32.test?rev=263543&r1=263542&r2=263543&view=diff
==============================================================================
--- lld/trunk/test/COFF/loadcfg32.test (original)
+++ lld/trunk/test/COFF/loadcfg32.test Tue Mar 15 04:48:27 2016
@@ -14,6 +14,10 @@ sections:
     Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
     Alignment:       4
     SectionData:     B82A000000C3
+  - Name:            .rdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
 symbols:
   - Name:            .text
     Value:           0
@@ -33,9 +37,21 @@ symbols:
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            .rdata
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          64
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
   - Name:            __load_config_used
     Value:           0
-    SectionNumber:   1
+    SectionNumber:   2
     SimpleType:      IMAGE_SYM_TYPE_NULL
     ComplexType:     IMAGE_SYM_DTYPE_NULL
     StorageClass:    IMAGE_SYM_CLASS_EXTERNAL




More information about the llvm-commits mailing list