diff options
| author | Rui Ueyama <ruiu@google.com> | 2014-08-29 20:33:27 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2014-08-29 20:33:27 +0000 |
| commit | 495a031ce46002047bb917c8c363187eda98c6b7 (patch) | |
| tree | e973c7ae2a4b140f5fbf3bc05da2e6269acbf119 /lld/lib/ReaderWriter/PECOFF/WriterPECOFF.cpp | |
| parent | 163ef0402a231796c8dc915a92dd5a8e72d70079 (diff) | |
| download | bcm5719-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.cpp | 12 |
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 - |

