diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 60b8e76f8230..22adb05dd6f8 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -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 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 getContents() const; - // A file this chunk was created from. ObjectFile *File; diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 5f5adaad8eaf..2cc0398a7763 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -602,9 +602,20 @@ template void Writer::writeHeader() { } } if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) { - if (Defined *B = dyn_cast(Sym->Body)) { + if (auto *B = dyn_cast(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 SecContents = SC->getContents(); + uint32_t LoadConfigSize = + *reinterpret_cast(&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; } } diff --git a/lld/test/COFF/loadcfg.ll b/lld/test/COFF/loadcfg.ll index 3166881032b4..c49ae2f6ebd5 100644 --- a/lld/test/COFF/loadcfg.ll +++ b/lld/test/COFF/loadcfg.ll @@ -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 diff --git a/lld/test/COFF/loadcfg.test b/lld/test/COFF/loadcfg.test index a84f864b4b53..3f789d69f43a 100644 --- a/lld/test/COFF/loadcfg.test +++ b/lld/test/COFF/loadcfg.test @@ -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 diff --git a/lld/test/COFF/loadcfg32.test b/lld/test/COFF/loadcfg32.test index f7780e1d0373..530669ed0d52 100644 --- a/lld/test/COFF/loadcfg32.test +++ b/lld/test/COFF/loadcfg32.test @@ -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