forked from OSchip/llvm-project
[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. llvm-svn: 263543
This commit is contained in:
parent
1706719972
commit
22dff0aafc
|
@ -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;
|
||||
|
||||
|
|
|
@ -602,9 +602,20 @@ template <typename PEHeaderTy> void Writer::writeHeader() {
|
|||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
@_load_config_used = constant i32 1
|
||||
@_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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue