summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2014-08-29 20:33:27 +0000
committerRui Ueyama <ruiu@google.com>2014-08-29 20:33:27 +0000
commit495a031ce46002047bb917c8c363187eda98c6b7 (patch)
treee973c7ae2a4b140f5fbf3bc05da2e6269acbf119 /lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
parent163ef0402a231796c8dc915a92dd5a8e72d70079 (diff)
downloadbcm5719-llvm-495a031ce46002047bb917c8c363187eda98c6b7.tar.gz
bcm5719-llvm-495a031ce46002047bb917c8c363187eda98c6b7.zip
[PECOFF] Fix AMD64_REL_[1-5] and AMD64_SECTION relocations
I hope this is the last fix for x64 relocations as I've wasted a few days on this. This caused a mysterious issue that some C++ programs crash on startup. It was because a null pointer is passed as argv to main. __tmainCRTStartup calls main, but before that it calls all initialization routines between .text$xc_a and .text$xc_z. pre_cpp_init is one of such routines, and it is the one who initializes a heap pointer for argv for later use. That routine was not called for some reason. It turned out that __tmainCRTStartup was skipping a block of code because of the relocation bug. A condition in the function depends on a memory load, and that memory load was referring a wrong location. As a result a jump instruction took the wrong branch, skipping pre_cpp_init and so on. This patch fixes the issue. Also added more tests to fix them once and for all. llvm-svn: 216772
Diffstat (limited to 'lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp')
-rw-r--r--lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp12
1 files changed, 6 insertions, 6 deletions
diff --git a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
index 8fd4b23de13..6096e46c8fd 100644
--- a/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
+++ b/lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp
@@ -587,26 +587,26 @@ void AtomChunk::applyRelocations64(uint8_t *buffer,
break;
case llvm::COFF::IMAGE_REL_AMD64_REL32_1:
*relocSite32 =
- *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 3;
+ *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 5;
break;
case llvm::COFF::IMAGE_REL_AMD64_REL32_2:
*relocSite32 =
- *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 2;
+ *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 6;
break;
case llvm::COFF::IMAGE_REL_AMD64_REL32_3:
*relocSite32 =
- *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 1;
+ *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 7;
break;
case llvm::COFF::IMAGE_REL_AMD64_REL32_4:
*relocSite32 =
- *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom();
+ *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 8;
break;
case llvm::COFF::IMAGE_REL_AMD64_REL32_5:
*relocSite32 =
- *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() + 1;
+ *relocSite32 + targetAddr - atomRva[atom] - ref->offsetInAtom() - 9;
break;
case llvm::COFF::IMAGE_REL_AMD64_SECTION:
- *relocSite16 = *relocSite16 + getSectionIndex(targetAddr, sectionRva);
+ *relocSite16 = *relocSite16 + getSectionIndex(targetAddr, sectionRva) - 1;
break;
case llvm::COFF::IMAGE_REL_AMD64_SECREL:
*relocSite32 = *relocSite32 + targetAddr -
OpenPOWER on IntegriCloud