From 4a6ead7a9f36319c3c064beae4fdb09a90402b05 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 28 Aug 2014 19:00:40 +0000 Subject: [PATCH] [PECOFF] Another Win64 relocation bug fix When a relocation is applied to a location, the new value needs to be added to the existing value at the location. Existing value is in most cases zero, but if not, the current code does not work. llvm-svn: 216680 --- lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | 29 ++++-- lld/test/pecoff/seh64.test | 104 ++++++++----------- 2 files changed, 60 insertions(+), 73 deletions(-) diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp index 4ed865535ede..8fd4b23de138 100644 --- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp @@ -573,37 +573,44 @@ void AtomChunk::applyRelocations64(uint8_t *buffer, switch (ref->kindValue()) { case llvm::COFF::IMAGE_REL_AMD64_ADDR64: - *relocSite64 = targetAddr + imageBase; + *relocSite64 = *relocSite64 + targetAddr + imageBase; break; case llvm::COFF::IMAGE_REL_AMD64_ADDR32: - *relocSite32 = targetAddr + imageBase; + *relocSite32 = *relocSite32 + targetAddr + imageBase; break; case llvm::COFF::IMAGE_REL_AMD64_ADDR32NB: - *relocSite32 = targetAddr; + *relocSite32 = *relocSite32 + targetAddr; break; case llvm::COFF::IMAGE_REL_AMD64_REL32: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 4; + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 4; break; case llvm::COFF::IMAGE_REL_AMD64_REL32_1: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 3; + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 3; break; case llvm::COFF::IMAGE_REL_AMD64_REL32_2: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 2; + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 2; break; case llvm::COFF::IMAGE_REL_AMD64_REL32_3: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() - 1; + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 1; break; case llvm::COFF::IMAGE_REL_AMD64_REL32_4: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom(); + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom(); break; case llvm::COFF::IMAGE_REL_AMD64_REL32_5: - *relocSite32 = targetAddr - atomRva[atom] - ref->offsetInAtom() + 1; + *relocSite32 = + *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() + 1; break; case llvm::COFF::IMAGE_REL_AMD64_SECTION: - *relocSite16 = getSectionIndex(targetAddr, sectionRva); + *relocSite16 = *relocSite16 + getSectionIndex(targetAddr, sectionRva); break; case llvm::COFF::IMAGE_REL_AMD64_SECREL: - *relocSite32 = targetAddr - getSectionStartAddr(targetAddr, sectionRva); + *relocSite32 = *relocSite32 + targetAddr - + getSectionStartAddr(targetAddr, sectionRva); break; default: llvm::errs() << "Kind: " << (int)ref->kindValue() << "\n"; diff --git a/lld/test/pecoff/seh64.test b/lld/test/pecoff/seh64.test index cceffc003ae6..664ec29e5258 100644 --- a/lld/test/pecoff/seh64.test +++ b/lld/test/pecoff/seh64.test @@ -9,69 +9,49 @@ HEADER: ExceptionTableRVA: 0x1000 UNWIND: Function Table: UNWIND: Start Address: 0x2000 -UNWIND: End Address: 0x2000 -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: 0x2000 -UNWIND: End Address: 0x2000 -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: 0x201b 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: 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: 0x201c -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: 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