return EC;
writeHeader();
writeSections();
+ sortExceptionTable();
return Buffer->commit();
}
DataDirectory[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA();
DataDirectory[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize();
}
+ if (OutputSection *Sec = findSection(".pdata")) {
+ DataDirectory[EXCEPTION_TABLE].RelativeVirtualAddress = Sec->getRVA();
+ DataDirectory[EXCEPTION_TABLE].Size = Sec->getVirtualSize();
+ }
// Section table
// Name field in the section table is 8 byte long. Longer names need
}
}
+// Sort .pdata section contents according to PE/COFF spec 5.5.
+void Writer::sortExceptionTable() {
+ if (auto *Sec = findSection(".pdata")) {
+ // We assume .pdata contains function table entries only.
+ struct Entry { ulittle32_t Begin, End, Unwind; };
+ uint8_t *Buf = Buffer->getBufferStart() + Sec->getFileOff();
+ std::sort(reinterpret_cast<Entry *>(Buf),
+ reinterpret_cast<Entry *>(Buf + Sec->getVirtualSize()),
+ [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; });
+ }
+}
+
OutputSection *Writer::findSection(StringRef Name) {
for (OutputSection *Sec : OutputSections)
if (Sec->getName() == Name)
--- /dev/null
+# RUN: yaml2obj < %s > %t.obj
+#
+# RUN: lld -flavor link2 /out:%t.exe %t.obj
+# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
+# RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s
+#
+# HEADER: ExceptionTableRVA: 0x1000
+#
+# UNWIND: Function Table:
+# UNWIND: Start Address: 0x2000
+# UNWIND: End Address: 0x201b
+# UNWIND: Unwind Info Address: 0x3000
+# UNWIND: Version: 1
+# UNWIND: Flags: 1 UNW_ExceptionHandler
+# UNWIND: Size of prolog: 18
+# UNWIND: Number of Codes: 8
+# UNWIND: Frame register: RBX
+# UNWIND: Frame offset: 0
+# UNWIND: Unwind Codes:
+# UNWIND: 0x12: UOP_SetFPReg
+# UNWIND: 0x0f: UOP_PushNonVol RBX
+# UNWIND: 0x0e: UOP_SaveXMM128 XMM8 [0x0000]
+# UNWIND: 0x09: UOP_SaveNonVol RSI [0x0010]
+# UNWIND: 0x04: UOP_AllocSmall 24
+# UNWIND: 0x00: UOP_PushMachFrame w/o error code
+# UNWIND: Function Table:
+# UNWIND: Start Address: 0x2012
+# UNWIND: End Address: 0x2012
+# UNWIND: Unwind Info Address: 0x301c
+# UNWIND: Version: 1
+# UNWIND: Flags: 4 UNW_ChainInfo
+# UNWIND: Size of prolog: 0
+# UNWIND: Number of Codes: 0
+# UNWIND: No frame pointer used
+# UNWIND: Function Table:
+# UNWIND: Start Address: 0x201b
+# UNWIND: End Address: 0x201c
+# UNWIND: Unwind Info Address: 0x302c
+# UNWIND: Version: 1
+# UNWIND: Flags: 0
+# UNWIND: Size of prolog: 0
+# UNWIND: Number of Codes: 0
+# UNWIND: No frame pointer used
+# UNWIND: Function Table:
+# UNWIND: Start Address: 0x201c
+# UNWIND: End Address: 0x2039
+# UNWIND: Unwind Info Address: 0x3034
+# UNWIND: Version: 1
+# UNWIND: Flags: 0
+# UNWIND: Size of prolog: 14
+# UNWIND: Number of Codes: 6
+# UNWIND: No frame pointer used
+# UNWIND: Unwind Codes:
+# UNWIND: 0x0e: UOP_AllocLarge 8454128
+# UNWIND: 0x07: UOP_AllocLarge 8190
+# UNWIND: 0x00: UOP_PushMachFrame w/o error code
+
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: [ ]
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 4883EC184889742410440F110424534889E3488D235B4883C418C3C34881ECF0FF00004881ECF0FF80004881C4F0FF80004881C4F0FF0000C3
+ - Name: .xdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 0912080312030F300E880000096402000422001A000000000000000021000000000000001B000000000000000100000000000000010E06000E11F0FF80000701FE1F001A
+ Relocations:
+ - VirtualAddress: 20
+ SymbolName: __C_specific_handler
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 32
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 36
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 40
+ SymbolName: .xdata
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - Name: .pdata
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+ Alignment: 4
+ SectionData: 000000001B0000000000000012000000120000001C00000000000000010000002C000000000000001D00000034000000
+ Relocations:
+ - VirtualAddress: 0
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 4
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 8
+ SymbolName: .xdata
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 12
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 16
+ SymbolName: func
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 20
+ SymbolName: .xdata
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 24
+ SymbolName: smallFunc
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 28
+ SymbolName: smallFunc
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 32
+ SymbolName: .xdata
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 36
+ SymbolName: allocFunc
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 40
+ SymbolName: allocFunc
+ Type: IMAGE_REL_AMD64_ADDR32NB
+ - VirtualAddress: 44
+ SymbolName: .xdata
+ Type: IMAGE_REL_AMD64_ADDR32NB
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 57
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 1
+ - Name: .xdata
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 68
+ NumberOfRelocations: 4
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 2
+ - Name: .pdata
+ Value: 0
+ SectionNumber: 3
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 48
+ NumberOfRelocations: 12
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 3
+ - Name: func
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __C_specific_handler
+ Value: 0
+ SectionNumber: 0
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: smallFunc
+ Value: 27
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: allocFunc
+ Value: 28
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: mainCRTStartup
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: __C_specific_handler
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...